From 0eb07baca369f4091140d965c4b144fedf90fe77 Mon Sep 17 00:00:00 2001 From: Aitor Aznar Date: Thu, 8 Dec 2016 11:06:38 +0100 Subject: [PATCH 01/16] gitignore updated --- .gitignore | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/.gitignore b/.gitignore index 5bcaf95..32ca372 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,52 @@ +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +.idea dist/public/js/loopback-admin.resources.js From 84ea2038098049e7342a4c5b84cca475e687d09c Mon Sep 17 00:00:00 2001 From: Aitor Aznar Date: Thu, 8 Dec 2016 11:08:20 +0100 Subject: [PATCH 02/16] remove auto generated --- dist/admin-spec.js | 83 - dist/create-user.js | 96 - dist/index.js | 106 - dist/public/css/loopback-admin.css | 415 - dist/public/css/loopback-admin.vendor.css | 14685 ------ dist/public/images/avatar.png | Bin 12735 -> 0 bytes dist/public/images/background.png | Bin 66493 -> 0 bytes dist/public/images/social-icons/bloggr.png | Bin 3337 -> 0 bytes .../public/images/social-icons/deviantart.png | Bin 3676 -> 0 bytes dist/public/images/social-icons/digg.png | Bin 1754 -> 0 bytes dist/public/images/social-icons/dribbble.png | Bin 6178 -> 0 bytes dist/public/images/social-icons/email.png | Bin 2990 -> 0 bytes dist/public/images/social-icons/evernote.png | Bin 3948 -> 0 bytes dist/public/images/social-icons/facebook.png | Bin 2049 -> 0 bytes dist/public/images/social-icons/flickr.png | Bin 2856 -> 0 bytes dist/public/images/social-icons/forrst.png | Bin 3286 -> 0 bytes .../images/social-icons/google-plus.png | Bin 5473 -> 0 bytes dist/public/images/social-icons/instagram.png | Bin 4840 -> 0 bytes dist/public/images/social-icons/linkedin.png | Bin 2771 -> 0 bytes dist/public/images/social-icons/pinterest.png | Bin 4495 -> 0 bytes dist/public/images/social-icons/readme.txt | 18 - dist/public/images/social-icons/rss.png | Bin 4159 -> 0 bytes dist/public/images/social-icons/share.png | Bin 3902 -> 0 bytes .../social-icons/simple-flat-social-icons.jpg | Bin 117744 -> 0 bytes dist/public/images/social-icons/skype.png | Bin 4765 -> 0 bytes .../images/social-icons/stumbleupon.png | Bin 3491 -> 0 bytes dist/public/images/social-icons/tumblr.png | Bin 2468 -> 0 bytes dist/public/images/social-icons/twitter.png | Bin 3691 -> 0 bytes dist/public/images/social-icons/vimeo.png | Bin 3900 -> 0 bytes dist/public/images/social-icons/youtube.png | Bin 4492 -> 0 bytes dist/public/index.html | 25 - dist/public/js/angular.js | 29859 ------------ dist/public/js/loopback-admin.js | 2115 - dist/public/js/loopback-admin.templates.js | 861 - dist/public/js/loopback-admin.vendor.js | 38557 ---------------- 35 files changed, 86820 deletions(-) delete mode 100644 dist/admin-spec.js delete mode 100644 dist/create-user.js delete mode 100644 dist/index.js delete mode 100644 dist/public/css/loopback-admin.css delete mode 100644 dist/public/css/loopback-admin.vendor.css delete mode 100644 dist/public/images/avatar.png delete mode 100644 dist/public/images/background.png delete mode 100644 dist/public/images/social-icons/bloggr.png delete mode 100644 dist/public/images/social-icons/deviantart.png delete mode 100644 dist/public/images/social-icons/digg.png delete mode 100644 dist/public/images/social-icons/dribbble.png delete mode 100644 dist/public/images/social-icons/email.png delete mode 100644 dist/public/images/social-icons/evernote.png delete mode 100644 dist/public/images/social-icons/facebook.png delete mode 100644 dist/public/images/social-icons/flickr.png delete mode 100644 dist/public/images/social-icons/forrst.png delete mode 100644 dist/public/images/social-icons/google-plus.png delete mode 100644 dist/public/images/social-icons/instagram.png delete mode 100644 dist/public/images/social-icons/linkedin.png delete mode 100644 dist/public/images/social-icons/pinterest.png delete mode 100644 dist/public/images/social-icons/readme.txt delete mode 100644 dist/public/images/social-icons/rss.png delete mode 100644 dist/public/images/social-icons/share.png delete mode 100644 dist/public/images/social-icons/simple-flat-social-icons.jpg delete mode 100644 dist/public/images/social-icons/skype.png delete mode 100644 dist/public/images/social-icons/stumbleupon.png delete mode 100644 dist/public/images/social-icons/tumblr.png delete mode 100644 dist/public/images/social-icons/twitter.png delete mode 100644 dist/public/images/social-icons/vimeo.png delete mode 100644 dist/public/images/social-icons/youtube.png delete mode 100644 dist/public/index.html delete mode 100644 dist/public/js/angular.js delete mode 100644 dist/public/js/loopback-admin.js delete mode 100644 dist/public/js/loopback-admin.templates.js delete mode 100644 dist/public/js/loopback-admin.vendor.js diff --git a/dist/admin-spec.js b/dist/admin-spec.js deleted file mode 100644 index 11b1240..0000000 --- a/dist/admin-spec.js +++ /dev/null @@ -1,83 +0,0 @@ -'use strict'; -var _models, clone, defaults, extend, formatProperties, fs, getModelInfo, path, ref, services; - -fs = require('fs'); - -ref = require('lodash'), defaults = ref.defaults, extend = ref.extend, clone = ref.clone; - -services = require('loopback-sdk-angular').services; - -path = require('path'); - -formatProperties = function(properties) { - var key, result; - result = {}; - for (key in properties) { - result[key] = clone(properties[key]); - if (Array.isArray(properties[key].type)) { - result[key].type = 'Array'; - result[key].subtype = properties[key].type[0]; - } else { - result[key].type = properties[key].type.name; - } - } - return result; -}; - -_models = {}; - -getModelInfo = function(loopbackApplication, modelName) { - var baseModel, baseProperties, keys, model, properties, result; - if (_models[modelName]) { - return _models[modelName]; - } - model = loopbackApplication.models[modelName]; - baseModel = void 0; - baseProperties = void 0; - if (model.definition.base) { - baseModel = getModelInfo(loopbackApplication, model.definition.base); - baseProperties = formatProperties(baseModel.definition.properties); - } - properties = formatProperties(model.definition.properties); - result = { - name: model.definition.name, - properties: extend(properties, baseProperties) - }; - keys = ['description', 'plural', 'idInjection', 'persistUndefinedAsNull', 'strict', 'hidden', 'validations', 'relations', 'acls', 'methods', 'mixins']; - keys.forEach(function(key) { - var ref1, ref2; - result[key] = (ref1 = model.definition) != null ? (ref2 = ref1.settings) != null ? ref2[key] : void 0 : void 0; - }); - _models[modelName] = result; - return result; -}; - -module.exports = function(loopbackApplication, options, callback) { - var api, handler, host, models, mountPath, port, sdkFile, sdkFilePath, url; - mountPath = options.mountPath; - host = loopbackApplication.get('host'); - port = loopbackApplication.get('port'); - api = loopbackApplication.get('restApiRoot'); - url = options.url || 'http://' + host + ':' + port + api; - sdkFile = services(loopbackApplication, 'loopback-admin.services', url); - sdkFilePath = path.join(__dirname, 'public/js/loopback-admin.resources.js'); - fs.writeFileSync(sdkFilePath, sdkFile, 'utf-8'); - handler = loopbackApplication.handler('rest'); - models = []; - process.nextTick(function() { - var config, configFile, configJSON; - handler.adapter.getClasses().forEach(function(modelClass) { - if (modelClass.ctor) { - return models.push(getModelInfo(loopbackApplication, modelClass.name)); - } - }); - config = { - options: options, - models: models.sort() - }; - configFile = path.join(__dirname, 'public/config.json'); - configJSON = JSON.stringify(config); - fs.writeFileSync(configFile, configJSON, 'utf-8'); - callback(configJSON); - }); -}; diff --git a/dist/create-user.js b/dist/create-user.js deleted file mode 100644 index a5fa0c2..0000000 --- a/dist/create-user.js +++ /dev/null @@ -1,96 +0,0 @@ -var createAdminRole, createDefaultAdmin; - -module.exports = function(loopbackApplication, options) { - var ACL, Role, RoleMapping, User; - ACL = loopbackApplication.models.ACL; - Role = loopbackApplication.models.Role; - RoleMapping = loopbackApplication.models.RoleMapping; - User = loopbackApplication.models[options.userModel]; - if (!User) { - User = loopbackApplication.models.User; - } - User.count(function(error, count) { - if (error) { - console.log('Error setting up default admin.'); - console.dir(error); - return; - } - if (count === 0) { - Role.findOne({ - where: { - name: 'admin' - } - }, function(error, result) { - if (error) { - console.log('Error setting up default admin role.'); - console.dir(error); - return; - } - if (!result) { - createAdminRole(Role, function(error, role) { - if (error) { - console.log('Error creating admin role.'); - console.dir(error); - return; - } - createDefaultAdmin(User, RoleMapping, ACL, role.id); - }); - } else { - createDefaultAdmin(User, RoleMapping, ACL, result.id); - } - }); - } - }); -}; - -createAdminRole = function(Role, callback) { - var role; - role = { - name: 'admin', - description: 'admin' - }; - Role.create(role, callback); -}; - -createDefaultAdmin = function(User, RoleMapping, ACL, roleId) { - User.create({ - email: 'admin@example.com', - username: 'admin', - password: 'password', - created: new Date - }, function(error, user) { - if (error) { - console.log('Error creating \'admin\' user.'); - console.dir(error); - return; - } - RoleMapping.create({ - principalType: 'USER', - principalId: user.getId(), - roleId: roleId - }, function(error, result) { - if (error) { - console.log('Error creating \'admin\' role mapping.'); - console.dir(error); - return; - } - console.log('Created default \'admin\' user with password \'password\'.'); - }); - ACL.create({ - model: User.definition.name, - property: '*', - accessType: '*', - permission: 'ALLOW', - principalType: 'ROLE', - principalId: 'admin' - }); - ACL.create({ - model: 'AccessToken', - property: '*', - accessType: '*', - permission: 'ALLOW', - principalType: 'ROLE', - principalId: 'admin' - }); - }); -}; diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index 446af1c..0000000 --- a/dist/index.js +++ /dev/null @@ -1,106 +0,0 @@ -'use strict'; -var STATIC_ROOT, attachXTotalCount, cors, createUser, defaults, fs, generateAdminSpec, mountAdmin, path, routes, setupCors, url, writeConfig; - -cors = require('cors'); - -path = require('path'); - -url = require('url'); - -fs = require('fs'); - -defaults = require('lodash').defaults; - -createUser = require('./create-user'); - -generateAdminSpec = require('./admin-spec'); - -STATIC_ROOT = path.join(__dirname, 'public'); - -attachXTotalCount = function(loopbackApplication) { - var remotes; - remotes = loopbackApplication.remotes(); - remotes.after('*.find', function(ctx, next) { - var filter; - filter = void 0; - if (ctx.args && ctx.args.filter) { - if (typeof ctx.args.filter === 'object') { - filter = ctx.args.filter.where; - } else { - filter = JSON.parse(ctx.args.filter).where; - } - } - if (!ctx.res._headerSent) { - this.count(filter, function(err, count) { - ctx.res.set('Access-Control-Expose-Headers', 'X-Total-Count'); - ctx.res.set('X-Total-Count', count); - next(); - }); - } else { - next(); - } - }); -}; - -writeConfig = function(config) { - var configJS, configJSON; - configJSON = JSON.stringify(config); - configJS = "angular.module('loopback-admin')\n\n.config([\"LoopBackAdminConfigurationProvider\", function(LoopBackAdminConfigurationProvider) {\n LoopBackAdminConfigurationProvider.setConfig(" + configJSON + ");\n}]);"; - fs.writeFileSync(path.join(__dirname, 'public/js/loopback-admin.config.js'), configJS, 'utf-8'); -}; - -mountAdmin = function(loopbackApplication, adminApp, opts) { - return generateAdminSpec(loopbackApplication, opts, function(adminObject) { - var remotes, resourcePath; - resourcePath = opts.resourcePath; - if (resourcePath[0] !== '/') { - resourcePath = '/' + resourcePath; - } - remotes = loopbackApplication.remotes(); - setupCors(adminApp, remotes); - adminApp.get(resourcePath, function(req, res) { - res.status(200).send(adminObject); - }); - }); -}; - -setupCors = function(adminApp, remotes) { - var corsOptions; - corsOptions = remotes.options && remotes.options.cors || { - origin: true, - credentials: true - }; - adminApp.use(cors(corsOptions)); -}; - -routes = function(loopbackApplication, options) { - var loopback, router; - loopback = loopbackApplication.loopback; - options = defaults({}, options, { - resourcePath: 'config.json', - mountPath: '/admin', - userModel: 'User', - userLoginField: 'username', - apiInfo: loopbackApplication.get('apiInfo') || {} - }); - router = new loopback.Router(); - attachXTotalCount(loopbackApplication); - mountAdmin(loopbackApplication, router, options); - writeConfig(options); - router.use(loopback["static"](STATIC_ROOT)); - return router; -}; - -module.exports = function(loopbackApplication, options) { - options = defaults({}, options, { - mountPath: '/admin' - }); - loopbackApplication.use(options.mountPath, routes(loopbackApplication, options)); - loopbackApplication.set('loopback-component-admin', options); - loopbackApplication.once('started', function() { - var adminPath, baseUrl; - baseUrl = loopbackApplication.get('url').replace(/\/$/, ''); - adminPath = options.mountPath || options.route; - return console.log('Browse your Admin UI at %s%s', baseUrl, adminPath); - }); -}; diff --git a/dist/public/css/loopback-admin.css b/dist/public/css/loopback-admin.css deleted file mode 100644 index a573e1c..0000000 --- a/dist/public/css/loopback-admin.css +++ /dev/null @@ -1,415 +0,0 @@ -.forgot-password { - position: absolute; - right: 15px; - cursor: pointer; - font-weight: 400; -} -cms-social-buttons { - margin: auto 0px; -} -#reset-password-page { - background-color: #f4f4f4; - height: 100%; -} -#reset-password-page .reset-container { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - height: 100%; - width: 100%; -} -#reset-password-page .reset-container .panel { - width: 600px; -} -.md-modal .md-modal-info { - order: 3; -} -.md-modal .md-modal-header { - position: relative; -} -.md-modal.md-modal-wide { - min-width: 450px; -} -.md-modal.limit-width { - max-width: 450px; -} -.md-modal .sub-header { - margin-top: 15px; -} -.md-modal h1 { - margin: 0; - font-size: 19px; - color: #4d4d4d; -} -.md-modal .buttons { - text-align: right; -} -.md-modal .buttons .btn { - padding: 7px 16px; -} -.md-modal .buttons .btn:first-of-type { - margin-right: 5px; -} -.account-settings-modal { - padding: 0; - overflow: visible; -} -@media screen and (max-height: 720px) { - .account-settings-modal .md-modal-header { - display: none !important; - } - .account-settings-modal .md-modal-nav-item { - font-size: 25px !important; - } -} -.account-settings-modal .md-modal-header { - display: flex; - flex-direction: column; - padding-bottom: 20px; - flex: 0 0 auto; -} -.account-settings-modal .md-modal-header > .name { - text-align: center; - font-size: 25px; - font-weight: 100; - margin-top: 80px; -} -.account-settings-modal .md-modal-header > .email { - padding-top: 5px; - text-align: center; -} -.account-settings-modal .md-modal-avatar { - width: 120px; - height: 120px; - border-radius: 50%; - position: absolute; - top: -50px; - left: calc(50% - 60px); - margin: 0 auto; -} -.account-settings-modal .md-modal-avatar > img { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 50%; -} -.account-settings-modal .md-modal-nav { - display: flex; - flex-direction: row; - flex: 0 0 auto; -} -.account-settings-modal .md-modal-nav > .md-modal-nav-item { - font-size: 35px; - padding: 15px; - flex: 1 1 auto; - text-align: center; - cursor: pointer; -} -.account-settings-modal .md-modal-nav > .md-modal-nav-item.active { - background-color: #fff; - color: #22322F; -} -.account-settings-modal .md-modal-tab { - display: none; - flex-direction: column; - padding: 25px; - flex: 0 0 auto; -} -.account-settings-modal .md-modal-tab.open { - display: flex; -} -.account-settings-modal .avatar-tab .img-responsive { - margin: 15px auto; -} -.account-settings-modal .avatar-tab p { - text-align: center; -} -.account-settings-modal .buttons { - margin-top: 30px; -} -.account-settings-modal .buttons md-select { - padding-left: 2px; -} -.account-settings-modal md-input-container { - padding-bottom: 10px; -} -.account-settings-modal md-input-container label { - color: rgba(0, 0, 0, 0.36) !important; -} -.user-modal form { - overflow: hidden; -} -.user-modal .errors { - margin-top: 15px; - color: #D32F2F; -} -.user-modal .errors .error { - margin-top: 5px; -} -.user-modal .buttons { - margin-top: 20px; -} -#landing-page { - background-color: #EFEFEF; - width: 100%; - height: 100%; - background-size: cover; - background-position: center; -} -#landing-page ::after { - background-color: rgba(0, 0, 0, 0.1); -} -#landing-page md-toolbar { - background-color: transparent; -} -#landing-page md-toolbar .login { - border: 1px solid #fff; - border-radius: 3px; - margin-left: 0px; -} -#landing-page md-toolbar a { - padding: 4px 24px; - font-size: 16px; -} -#landing-page section { - padding-bottom: 64px; -} -#landing-page section md-content { - text-align: center; - background-color: transparent; - color: #fff; -} -#landing-page section md-content h1 { - font-size: 45px; -} -#landing-page section md-content a { - padding: 0 30px; - min-height: 50px; - line-height: 50px; - font-size: 15px; - margin-top: 30px; -} -@media (max-width: 768px) { - #login-page .login-container { - width: 90%; - } - .md-modal { - min-width: 90%; - } - .md-modal.md-modal-wide { - min-width: 90%; - max-width: 100%; - } - #left-col { - display: none; - } -} -#left-col { - width: 220px; - text-align: center; - flex: 0 0 auto; - min-width: 0px; - position: relative; - height: 100%; -} -#left-col .current-user { - border-bottom: 1px solid #202327; - box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.08); - padding: 20px; - cursor: pointer; -} -#left-col .current-user .avatar, -#left-col .current-user .user-email { - float: left; -} -#left-col .current-user .avatar { - width: 30%; - overflow: hidden; -} -#left-col .current-user .avatar img { - width: 45px; - height: 45px; - object-fit: cover; - border-radius: 50%; -} -#left-col .current-user .user-email { - text-align: left; - width: 70%; - padding-top: 12px; - font-size: 14px; -} -@media (max-width: 1200px) { - #left-col { - width: 80px; - } - #left-col .current-user { - padding: 0px; - } - #left-col .current-user md-menu button { - min-width: 0px; - } - #left-col .current-user .user-email { - display: none; - } - #left-col .current-user .avatar { - width: 70%; - padding: 7px 12px 0px 12px; - } - #left-col .current-user .avatar > img { - width: 100%; - height: auto; - } -} -md-sidemenu h2 { - margin: 10px 0px; - padding: 0px 10px; - text-align: left; -} -md-sidemenu ul { - list-style: none; - padding: 0; - magin: 0; -} -md-sidemenu ul .md-button { - box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.26); - /* disable to remove underline */ - border-radius: 0px !important; - cursor: pointer; - display: flex; - line-height: 40px; - margin: 0; - max-height: 50px; - text-transform: none; - min-width: 0px; - overflow: hidden; - text-align: left; - width: 100%; -} -md-sidemenu ul .md-button span, -md-sidemenu ul .md-button md-icon { - padding: 0px 5px; -} -md-sidemenu ul .md-button .md-ripple-container { - border-radius: 0px !important; -} -md-sidemenu ul button.md-button::-moz-focus-inner { - padding: 0; -} -.social-icon { - width: 32px; - height: 32px; - margin-right: 5px; - background-size: 100%; - display: inline-block; - cursor: pointer; - transition: opacity 0.2s ease; - box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); -} -.social-icon:hover { - opacity: 0.7; -} -.social-icon.facebook { - background-image: url(../images/social-icons/facebook.png); -} -.social-icon.twitter { - background-image: url(../images/social-icons/twitter.png); -} -.social-icon.googleplus { - background-image: url(../images/social-icons/google-plus.png); -} -.social-icon.pinterest { - background-image: url(../images/social-icons/pinterest.png); -} -.social-icon.tumblr { - background-image: url(../images/social-icons/tumblr.png); -} -.social-icon.stumbleupon { - background-image: url(../images/social-icons/stumbleupon.png); -} -.social-icon.blogger { - background-image: url(../images/social-icons/bloggr.png); -} -.md-button.md-icon-button { - line-height: normal !important; -} -.content-margin { - overflow-x: hidden; -} -md-checkbox .md-label span { - line-height: 35px; -} -md-data-table-toolbar form > input { - width: 100%; - margin: 0; - margin-left: 6px; - font-size: 20px; - border: none; - color: rgba(0, 0, 0, 0.87); -} -md-data-table-toolbar.property { - height: auto; - padding: 0px; - padding-left: 3px; - font-size: 13px; - color: rgba(0, 0, 0, 0.54); -} -* { - outline: none; -} -md-input-container { - display: inline-block; - position: relative; - padding: 2px; - margin: 6px 0; - width: 100%; -} -md-input-container .md-errors-spacer { - min-height: 0px !important; -} -body { - background-color: #EFEFEF !important; - overflow: hidden; -} -#left-col-upper { - display: flex; - flex: 1 1 auto; - height: 100%; -} -::-webkit-scrollbar { - width: 13px; - height: 13px; -} -::-webkit-scrollbar-thumb { - background-color: #A7A7A7; - border: solid transparent; - background-clip: padding-box; - border-width: 1px 1px 1px 1px; -} -md-icon[md-font-icon] { - line-height: 1; - width: auto; - vertical-align: text-bottom; -} -[ui-view] { - height: 100%; -} -[ui-view].ng-enter, -[ui-view].ng-leave { - position: absolute; - left: 0; - right: 0; - transition: opacity 0.3s ease-in-out; -} -[ui-view].ng-enter { - opacity: 0; -} -[ui-view].ng-enter-active { - opacity: 1; -} -[ui-view].ng-leave { - opacity: 1; -} -[ui-view].ng-leave-active { - opacity: 0; -} diff --git a/dist/public/css/loopback-admin.vendor.css b/dist/public/css/loopback-admin.vendor.css deleted file mode 100644 index a27b6ef..0000000 --- a/dist/public/css/loopback-admin.vendor.css +++ /dev/null @@ -1,14685 +0,0 @@ -/*! - * Angular Material Design - * https://github.com/angular/material - * @license MIT - * v1.0.1 - */ -html, body { - height: 100%; - color: rgba(0, 0, 0, 0.87); - background: white; - position: relative; } - -body { - margin: 0; - padding: 0; } - -[tabindex='-1']:focus { - outline: none; } - -.inset { - padding: 10px; } - -button.md-no-style { - font-weight: normal; - background-color: inherit; - text-align: left; - border: none; - padding: 0; - margin: 0; } - -select, -button, -textarea, -input { - vertical-align: baseline; } - -input[type="reset"], -input[type="submit"], -html input[type="button"], -button { - cursor: pointer; - -webkit-appearance: button; } - input[type="reset"][disabled], - input[type="submit"][disabled], - html input[type="button"][disabled], - button[disabled] { - cursor: default; } - -textarea { - vertical-align: top; - overflow: auto; } - -input[type="search"] { - -webkit-appearance: textfield; - box-sizing: content-box; - -webkit-box-sizing: content-box; } - input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { - -webkit-appearance: none; } - -.md-visually-hidden { - border: 0; - clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - text-transform: none; - width: 1px; } - -.md-shadow { - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - border-radius: inherit; - pointer-events: none; } - -.md-shadow-bottom-z-1 { - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); } - -.md-shadow-bottom-z-2 { - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4); } - -.md-shadow-animated.md-shadow { - transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1); } - -/* - * A container inside of a rippling element (eg a button), - * which contains all of the individual ripples - */ -.md-ripple-container { - pointer-events: none; - position: absolute; - overflow: hidden; - left: 0; - top: 0; - width: 100%; - height: 100%; - transition: all 0.55s cubic-bezier(0.25, 0.8, 0.25, 1); } - -.md-ripple { - position: absolute; - -webkit-transform: translate(-50%, -50%) scale(0); - transform: translate(-50%, -50%) scale(0); - -webkit-transform-origin: 50% 50%; - transform-origin: 50% 50%; - opacity: 0; - border-radius: 50%; } - .md-ripple.md-ripple-placed { - transition: margin 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), border 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), width 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), height 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), opacity 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), -webkit-transform 0.9s cubic-bezier(0.25, 0.8, 0.25, 1); - transition: margin 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), border 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), width 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), height 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), opacity 0.9s cubic-bezier(0.25, 0.8, 0.25, 1), transform 0.9s cubic-bezier(0.25, 0.8, 0.25, 1); } - .md-ripple.md-ripple-scaled { - -webkit-transform: translate(-50%, -50%) scale(1); - transform: translate(-50%, -50%) scale(1); } - .md-ripple.md-ripple-active, .md-ripple.md-ripple-full, .md-ripple.md-ripple-visible { - opacity: 0.20; } - -.md-padding { - padding: 8px; } - -.md-margin { - margin: 8px; } - -.md-scroll-mask { - position: absolute; - background-color: transparent; - top: 0; - right: 0; - bottom: 0; - left: 0; } - .md-scroll-mask > .md-scroll-mask-bar { - display: block; - position: absolute; - background-color: #fafafa; - right: 0; - top: 0; - bottom: 0; - z-index: 65; - box-shadow: inset 0px 0px 1px rgba(0, 0, 0, 0.3); } - -@media (min-width: 960px) { - .md-padding { - padding: 16px; } } - -html, body { - -webkit-tap-highlight-color: transparent; - -webkit-touch-callout: none; - min-height: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; } - -/************ - * Headings - ************/ -.md-display-4 { - font-size: 112px; - font-weight: 300; - letter-spacing: -0.010em; - line-height: 112px; } - -.md-display-3 { - font-size: 56px; - font-weight: 400; - letter-spacing: -0.005em; - line-height: 56px; } - -.md-display-2 { - font-size: 45px; - font-weight: 400; - line-height: 64px; } - -.md-display-1 { - font-size: 34px; - font-weight: 400; - line-height: 40px; } - -.md-headline { - font-size: 24px; - font-weight: 400; - line-height: 32px; } - -.md-title { - font-size: 20px; - font-weight: 500; - letter-spacing: 0.005em; } - -.md-subhead { - font-size: 16px; - font-weight: 400; - letter-spacing: 0.010em; - line-height: 24px; } - -/************ - * Body Copy - ************/ -.md-body-1 { - font-size: 14px; - font-weight: 400; - letter-spacing: 0.010em; - line-height: 20px; } - -.md-body-2 { - font-size: 14px; - font-weight: 500; - letter-spacing: 0.010em; - line-height: 24px; } - -.md-caption { - font-size: 12px; - letter-spacing: 0.020em; } - -.md-button { - letter-spacing: 0.010em; } - -/************ - * Defaults - ************/ -button, -select, -html, -textarea, -input { - font-family: Roboto, "Helvetica Neue", sans-serif; } - -select, -button, -textarea, -input { - font-size: 100%; } - -/* -* -* Responsive attributes -* -* References: -* 1) https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties#flex -* 2) https://css-tricks.com/almanac/properties/f/flex/ -* 3) https://css-tricks.com/snippets/css/a-guide-to-flexbox/ -* 4) https://github.com/philipwalton/flexbugs#3-min-height-on-a-flex-container-wont-apply-to-its-flex-items -* 5) http://godban.com.ua/projects/flexgrid -* -* -*/ -@-moz-document url-prefix() { - .layout-fill { - margin: 0; - width: 100%; - min-height: 100%; - height: 100%; } } - -/* - * Apply Mixins to create Layout/Flexbox styles - * - */ -.flex-order { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - -.flex-order--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - -.flex-order--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - -.flex-order--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - -.flex-order--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - -.flex-order--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - -.flex-order--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - -.flex-order--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - -.flex-order--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - -.flex-order--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - -.flex-order--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - -.flex-order--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - -.flex-order--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - -.flex-order--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - -.flex-order--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - -.flex-order--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - -.flex-order--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - -.flex-order--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - -.flex-order--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - -.flex-order--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - -.flex-order--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - -.flex-order-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - -.flex-order-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - -.flex-order-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - -.flex-order-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - -.flex-order-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - -.flex-order-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - -.flex-order-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - -.flex-order-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - -.flex-order-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - -.flex-order-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - -.flex-order-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - -.flex-order-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - -.flex-order-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - -.flex-order-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - -.flex-order-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - -.flex-order-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - -.flex-order-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - -.flex-order-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - -.flex-order-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - -.flex-order-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - -.flex-order-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - -.offset-0, .flex-offset-0 { - margin-left: 0%; } - -.offset-5, .flex-offset-5 { - margin-left: 5%; } - -.offset-10, .flex-offset-10 { - margin-left: 10%; } - -.offset-15, .flex-offset-15 { - margin-left: 15%; } - -.offset-20, .flex-offset-20 { - margin-left: 20%; } - -.offset-25, .flex-offset-25 { - margin-left: 25%; } - -.offset-30, .flex-offset-30 { - margin-left: 30%; } - -.offset-35, .flex-offset-35 { - margin-left: 35%; } - -.offset-40, .flex-offset-40 { - margin-left: 40%; } - -.offset-45, .flex-offset-45 { - margin-left: 45%; } - -.offset-50, .flex-offset-50 { - margin-left: 50%; } - -.offset-55, .flex-offset-55 { - margin-left: 55%; } - -.offset-60, .flex-offset-60 { - margin-left: 60%; } - -.offset-65, .flex-offset-65 { - margin-left: 65%; } - -.offset-70, .flex-offset-70 { - margin-left: 70%; } - -.offset-75, .flex-offset-75 { - margin-left: 75%; } - -.offset-80, .flex-offset-80 { - margin-left: 80%; } - -.offset-85, .flex-offset-85 { - margin-left: 85%; } - -.offset-90, .flex-offset-90 { - margin-left: 90%; } - -.offset-95, .flex-offset-95 { - margin-left: 95%; } - -.offset-33, .flex-offset-33 { - margin-left: calc(100% / 3); } - -.offset-66, .flex-offset-66 { - margin-left: calc(200% / 3); } - -.layout-align { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - -.layout-align-start, -.layout-align-start-start, -.layout-align-start-center, -.layout-align-start-end, -.layout-align-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - -.layout-align-center, -.layout-align-center-start, -.layout-align-center-center, -.layout-align-center-end, -.layout-align-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - -.layout-align-end, -.layout-align-end-start, -.layout-align-end-center, -.layout-align-end-end, -.layout-align-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - -.layout-align-space-around, -.layout-align-space-around-center, -.layout-align-space-around-start, -.layout-align-space-around-end, -.layout-align-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - -.layout-align-space-between, -.layout-align-space-between-center, -.layout-align-space-between-start, -.layout-align-space-between-end, -.layout-align-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - -.layout-align-start-start, -.layout-align-center-start, -.layout-align-end-start, -.layout-align-space-between-start, -.layout-align-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - -.layout-align-start-center, -.layout-align-center-center, -.layout-align-end-center, -.layout-align-space-between-center, -.layout-align-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - -.layout-align-start-center > *, -.layout-align-center-center > *, -.layout-align-end-center > *, -.layout-align-space-between-center > *, -.layout-align-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - -.layout-align-start-end, -.layout-align-center-end, -.layout-align-end-end, -.layout-align-space-between-end, -.layout-align-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - -.layout-align-start-stretch, -.layout-align-center-stretch, -.layout-align-end-stretch, -.layout-align-space-between-stretch, -.layout-align-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - -.flex { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } - -@media screen\0 { - .flex { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -.flex-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - -.flex-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - -.flex-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - -.flex-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - -.flex-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - -.flex-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - -.flex-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-0, -.layout-row > .flex-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-0, -.layout-column > .flex-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - -.flex-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-5, -.layout-row > .flex-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-5, -.layout-column > .flex-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - -.flex-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-10, -.layout-row > .flex-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-10, -.layout-column > .flex-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - -.flex-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-15, -.layout-row > .flex-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-15, -.layout-column > .flex-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - -.flex-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-20, -.layout-row > .flex-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-20, -.layout-column > .flex-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - -.flex-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-25, -.layout-row > .flex-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-25, -.layout-column > .flex-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - -.flex-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-30, -.layout-row > .flex-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-30, -.layout-column > .flex-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - -.flex-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-35, -.layout-row > .flex-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-35, -.layout-column > .flex-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - -.flex-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-40, -.layout-row > .flex-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-40, -.layout-column > .flex-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - -.flex-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-45, -.layout-row > .flex-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-45, -.layout-column > .flex-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - -.flex-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-50, -.layout-row > .flex-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-50, -.layout-column > .flex-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - -.flex-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-55, -.layout-row > .flex-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-55, -.layout-column > .flex-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - -.flex-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-60, -.layout-row > .flex-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-60, -.layout-column > .flex-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - -.flex-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-65, -.layout-row > .flex-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-65, -.layout-column > .flex-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - -.flex-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-70, -.layout-row > .flex-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-70, -.layout-column > .flex-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - -.flex-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-75, -.layout-row > .flex-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-75, -.layout-column > .flex-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - -.flex-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-80, -.layout-row > .flex-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-80, -.layout-column > .flex-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - -.flex-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-85, -.layout-row > .flex-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-85, -.layout-column > .flex-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - -.flex-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-90, -.layout-row > .flex-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-90, -.layout-column > .flex-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - -.flex-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-95, -.layout-row > .flex-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-95, -.layout-column > .flex-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - -.flex-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-100, -.layout-row > .flex-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-100, -.layout-column > .flex-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-33, .layout-row > .flex-33, .layout-row > .flex-33, .layout-row > .flex-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - -.layout-row > .flex-66, .layout-row > .flex-66, .layout-row > .flex-66, .layout-row > .flex-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - -.layout-column > .flex-33, .layout-column > .flex-33, .layout-column > .flex-33, .layout-column > .flex-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - -.layout-column > .flex-66, .layout-column > .flex-66, .layout-column > .flex-66, .layout-column > .flex-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - -.layout, .layout-column, .layout-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - -.layout-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - -.layout-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - -.layout-padding-sm > *, -.layout-padding > .flex-sm { - padding: 4px; } - -.layout-padding, -.layout-padding-gt-sm, -.layout-padding-md, -.layout-padding > *, -.layout-padding-gt-sm > *, -.layout-padding-md > *, -.layout-padding > .flex, -.layout-padding > .flex-gt-sm, -.layout-padding > .flex-md { - padding: 8px; } - -.layout-padding-gt-md > *, -.layout-padding-lg > *, -.layout-padding-gt-lg > *, -.layout-padding > .flex-gt-md, -.layout-padding > .flex-lg, -.layout-padding > .flex-lg, -.layout-padding > .flex-gt-lg { - padding: 16px; } - -.layout-margin-sm > *, -.layout-margin > .flex-sm { - margin: 4px; } - -.layout-margin, -.layout-margin-gt-sm, -.layout-margin-md, -.layout-margin > *, -.layout-margin-gt-sm > *, -.layout-margin-md > *, -.layout-margin > .flex, -.layout-margin > .flex-gt-sm, -.layout-margin > .flex-md { - margin: 8px; } - -.layout-margin-gt-md > *, -.layout-margin-lg > *, -.layout-margin-gt-lg > *, -.layout-margin > .flex-gt-md, -.layout-margin > .flex-lg, -.layout-margin > .flex-gt-lg { - margin: 16px; } - -.layout-wrap { - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; } - -.layout-nowrap { - -webkit-flex-wrap: nowrap; - -ms-flex-wrap: nowrap; - flex-wrap: nowrap; } - -.layout-fill { - margin: 0; - width: 100%; - min-height: 100%; - height: 100%; } - -/** - * `hide-gt-sm show-gt-lg` should hide from 600px to 1200px - * `show-md hide-gt-sm` should show from 0px to 960px and hide at >960px - * `hide-gt-md show-gt-sm` should show everywhere (show overrides hide)` - * - * hide means hide everywhere - * Sizes: - * $layout-breakpoint-xs: 600px !default; - * $layout-breakpoint-sm: 960px !default; - * $layout-breakpoint-md: 1280px !default; - * $layout-breakpoint-lg: 1920px !default; - */ -@media (max-width: 599px) { - .hide-xs:not(.show-xs):not(.show), .hide:not(.show-xs):not(.show) { - display: none; } - .flex-order-xs--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - .flex-order-xs--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - .flex-order-xs--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - .flex-order-xs--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - .flex-order-xs--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - .flex-order-xs--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - .flex-order-xs--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - .flex-order-xs--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - .flex-order-xs--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - .flex-order-xs--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - .flex-order-xs--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - .flex-order-xs--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - .flex-order-xs--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - .flex-order-xs--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - .flex-order-xs--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - .flex-order-xs--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - .flex-order-xs--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - .flex-order-xs--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - .flex-order-xs--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - .flex-order-xs--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - .flex-order-xs-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - .flex-order-xs-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - .flex-order-xs-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - .flex-order-xs-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - .flex-order-xs-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - .flex-order-xs-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - .flex-order-xs-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - .flex-order-xs-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - .flex-order-xs-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - .flex-order-xs-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - .flex-order-xs-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - .flex-order-xs-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - .flex-order-xs-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - .flex-order-xs-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - .flex-order-xs-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - .flex-order-xs-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - .flex-order-xs-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - .flex-order-xs-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - .flex-order-xs-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - .flex-order-xs-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - .flex-order-xs-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - .offset-xs-0, .flex-offset-xs-0 { - margin-left: 0%; } - .offset-xs-5, .flex-offset-xs-5 { - margin-left: 5%; } - .offset-xs-10, .flex-offset-xs-10 { - margin-left: 10%; } - .offset-xs-15, .flex-offset-xs-15 { - margin-left: 15%; } - .offset-xs-20, .flex-offset-xs-20 { - margin-left: 20%; } - .offset-xs-25, .flex-offset-xs-25 { - margin-left: 25%; } - .offset-xs-30, .flex-offset-xs-30 { - margin-left: 30%; } - .offset-xs-35, .flex-offset-xs-35 { - margin-left: 35%; } - .offset-xs-40, .flex-offset-xs-40 { - margin-left: 40%; } - .offset-xs-45, .flex-offset-xs-45 { - margin-left: 45%; } - .offset-xs-50, .flex-offset-xs-50 { - margin-left: 50%; } - .offset-xs-55, .flex-offset-xs-55 { - margin-left: 55%; } - .offset-xs-60, .flex-offset-xs-60 { - margin-left: 60%; } - .offset-xs-65, .flex-offset-xs-65 { - margin-left: 65%; } - .offset-xs-70, .flex-offset-xs-70 { - margin-left: 70%; } - .offset-xs-75, .flex-offset-xs-75 { - margin-left: 75%; } - .offset-xs-80, .flex-offset-xs-80 { - margin-left: 80%; } - .offset-xs-85, .flex-offset-xs-85 { - margin-left: 85%; } - .offset-xs-90, .flex-offset-xs-90 { - margin-left: 90%; } - .offset-xs-95, .flex-offset-xs-95 { - margin-left: 95%; } - .offset-xs-33, .flex-offset-xs-33 { - margin-left: calc(100% / 3); } - .offset-xs-66, .flex-offset-xs-66 { - margin-left: calc(200% / 3); } - .layout-align-xs { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - .layout-align-xs-start, - .layout-align-xs-start-start, - .layout-align-xs-start-center, - .layout-align-xs-start-end, - .layout-align-xs-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - .layout-align-xs-center, - .layout-align-xs-center-start, - .layout-align-xs-center-center, - .layout-align-xs-center-end, - .layout-align-xs-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - .layout-align-xs-end, - .layout-align-xs-end-start, - .layout-align-xs-end-center, - .layout-align-xs-end-end, - .layout-align-xs-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - .layout-align-xs-space-around, - .layout-align-xs-space-around-center, - .layout-align-xs-space-around-start, - .layout-align-xs-space-around-end, - .layout-align-xs-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - .layout-align-xs-space-between, - .layout-align-xs-space-between-center, - .layout-align-xs-space-between-start, - .layout-align-xs-space-between-end, - .layout-align-xs-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - .layout-align-xs-start-start, - .layout-align-xs-center-start, - .layout-align-xs-end-start, - .layout-align-xs-space-between-start, - .layout-align-xs-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - .layout-align-xs-start-center, - .layout-align-xs-center-center, - .layout-align-xs-end-center, - .layout-align-xs-space-between-center, - .layout-align-xs-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - .layout-align-xs-start-center > *, - .layout-align-xs-center-center > *, - .layout-align-xs-end-center > *, - .layout-align-xs-space-between-center > *, - .layout-align-xs-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - .layout-align-xs-start-end, - .layout-align-xs-center-end, - .layout-align-xs-end-end, - .layout-align-xs-space-between-end, - .layout-align-xs-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - .layout-align-xs-start-stretch, - .layout-align-xs-center-stretch, - .layout-align-xs-end-stretch, - .layout-align-xs-space-between-stretch, - .layout-align-xs-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - .flex-xs { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } } - -@media screen\0 and (max-width: 599px) { - .flex-xs { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -@media (max-width: 599px) { - .flex-xs-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - .flex-xs-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-xs-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - .flex-xs-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - .flex-xs-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - .flex-xs-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-xs-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-0, - .layout-xs-row > .flex-xs-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-0, - .layout-xs-column > .flex-xs-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - .flex-xs-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-5, - .layout-xs-row > .flex-xs-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-5, - .layout-xs-column > .flex-xs-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - .flex-xs-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-10, - .layout-xs-row > .flex-xs-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-10, - .layout-xs-column > .flex-xs-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - .flex-xs-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-15, - .layout-xs-row > .flex-xs-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-15, - .layout-xs-column > .flex-xs-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - .flex-xs-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-20, - .layout-xs-row > .flex-xs-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-20, - .layout-xs-column > .flex-xs-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - .flex-xs-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-25, - .layout-xs-row > .flex-xs-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-25, - .layout-xs-column > .flex-xs-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - .flex-xs-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-30, - .layout-xs-row > .flex-xs-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-30, - .layout-xs-column > .flex-xs-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - .flex-xs-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-35, - .layout-xs-row > .flex-xs-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-35, - .layout-xs-column > .flex-xs-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - .flex-xs-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-40, - .layout-xs-row > .flex-xs-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-40, - .layout-xs-column > .flex-xs-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - .flex-xs-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-45, - .layout-xs-row > .flex-xs-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-45, - .layout-xs-column > .flex-xs-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - .flex-xs-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-50, - .layout-xs-row > .flex-xs-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-50, - .layout-xs-column > .flex-xs-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - .flex-xs-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-55, - .layout-xs-row > .flex-xs-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-55, - .layout-xs-column > .flex-xs-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - .flex-xs-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-60, - .layout-xs-row > .flex-xs-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-60, - .layout-xs-column > .flex-xs-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - .flex-xs-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-65, - .layout-xs-row > .flex-xs-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-65, - .layout-xs-column > .flex-xs-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - .flex-xs-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-70, - .layout-xs-row > .flex-xs-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-70, - .layout-xs-column > .flex-xs-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - .flex-xs-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-75, - .layout-xs-row > .flex-xs-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-75, - .layout-xs-column > .flex-xs-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - .flex-xs-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-80, - .layout-xs-row > .flex-xs-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-80, - .layout-xs-column > .flex-xs-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - .flex-xs-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-85, - .layout-xs-row > .flex-xs-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-85, - .layout-xs-column > .flex-xs-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - .flex-xs-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-90, - .layout-xs-row > .flex-xs-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-90, - .layout-xs-column > .flex-xs-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - .flex-xs-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-95, - .layout-xs-row > .flex-xs-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-95, - .layout-xs-column > .flex-xs-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - .flex-xs-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-100, - .layout-xs-row > .flex-xs-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-100, - .layout-xs-column > .flex-xs-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-33, .layout-row > .flex-xs-33, .layout-xs-row > .flex-xs-33, .layout-xs-row > .flex-xs-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xs-66, .layout-row > .flex-xs-66, .layout-xs-row > .flex-xs-66, .layout-xs-row > .flex-xs-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xs-33, .layout-column > .flex-xs-33, .layout-xs-column > .flex-xs-33, .layout-xs-column > .flex-xs-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - .layout-column > .flex-xs-66, .layout-column > .flex-xs-66, .layout-xs-column > .flex-xs-66, .layout-xs-column > .flex-xs-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - .layout-xs, .layout-xs-column, .layout-xs-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - .layout-xs-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - .layout-xs-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } } - -@media (min-width: 600px) { - .flex-order-gt-xs--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - .flex-order-gt-xs--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - .flex-order-gt-xs--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - .flex-order-gt-xs--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - .flex-order-gt-xs--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - .flex-order-gt-xs--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - .flex-order-gt-xs--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - .flex-order-gt-xs--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - .flex-order-gt-xs--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - .flex-order-gt-xs--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - .flex-order-gt-xs--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - .flex-order-gt-xs--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - .flex-order-gt-xs--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - .flex-order-gt-xs--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - .flex-order-gt-xs--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - .flex-order-gt-xs--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - .flex-order-gt-xs--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - .flex-order-gt-xs--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - .flex-order-gt-xs--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - .flex-order-gt-xs--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - .flex-order-gt-xs-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - .flex-order-gt-xs-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - .flex-order-gt-xs-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - .flex-order-gt-xs-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - .flex-order-gt-xs-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - .flex-order-gt-xs-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - .flex-order-gt-xs-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - .flex-order-gt-xs-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - .flex-order-gt-xs-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - .flex-order-gt-xs-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - .flex-order-gt-xs-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - .flex-order-gt-xs-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - .flex-order-gt-xs-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - .flex-order-gt-xs-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - .flex-order-gt-xs-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - .flex-order-gt-xs-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - .flex-order-gt-xs-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - .flex-order-gt-xs-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - .flex-order-gt-xs-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - .flex-order-gt-xs-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - .flex-order-gt-xs-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - .offset-gt-xs-0, .flex-offset-gt-xs-0 { - margin-left: 0%; } - .offset-gt-xs-5, .flex-offset-gt-xs-5 { - margin-left: 5%; } - .offset-gt-xs-10, .flex-offset-gt-xs-10 { - margin-left: 10%; } - .offset-gt-xs-15, .flex-offset-gt-xs-15 { - margin-left: 15%; } - .offset-gt-xs-20, .flex-offset-gt-xs-20 { - margin-left: 20%; } - .offset-gt-xs-25, .flex-offset-gt-xs-25 { - margin-left: 25%; } - .offset-gt-xs-30, .flex-offset-gt-xs-30 { - margin-left: 30%; } - .offset-gt-xs-35, .flex-offset-gt-xs-35 { - margin-left: 35%; } - .offset-gt-xs-40, .flex-offset-gt-xs-40 { - margin-left: 40%; } - .offset-gt-xs-45, .flex-offset-gt-xs-45 { - margin-left: 45%; } - .offset-gt-xs-50, .flex-offset-gt-xs-50 { - margin-left: 50%; } - .offset-gt-xs-55, .flex-offset-gt-xs-55 { - margin-left: 55%; } - .offset-gt-xs-60, .flex-offset-gt-xs-60 { - margin-left: 60%; } - .offset-gt-xs-65, .flex-offset-gt-xs-65 { - margin-left: 65%; } - .offset-gt-xs-70, .flex-offset-gt-xs-70 { - margin-left: 70%; } - .offset-gt-xs-75, .flex-offset-gt-xs-75 { - margin-left: 75%; } - .offset-gt-xs-80, .flex-offset-gt-xs-80 { - margin-left: 80%; } - .offset-gt-xs-85, .flex-offset-gt-xs-85 { - margin-left: 85%; } - .offset-gt-xs-90, .flex-offset-gt-xs-90 { - margin-left: 90%; } - .offset-gt-xs-95, .flex-offset-gt-xs-95 { - margin-left: 95%; } - .offset-gt-xs-33, .flex-offset-gt-xs-33 { - margin-left: calc(100% / 3); } - .offset-gt-xs-66, .flex-offset-gt-xs-66 { - margin-left: calc(200% / 3); } - .layout-align-gt-xs { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - .layout-align-gt-xs-start, - .layout-align-gt-xs-start-start, - .layout-align-gt-xs-start-center, - .layout-align-gt-xs-start-end, - .layout-align-gt-xs-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - .layout-align-gt-xs-center, - .layout-align-gt-xs-center-start, - .layout-align-gt-xs-center-center, - .layout-align-gt-xs-center-end, - .layout-align-gt-xs-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - .layout-align-gt-xs-end, - .layout-align-gt-xs-end-start, - .layout-align-gt-xs-end-center, - .layout-align-gt-xs-end-end, - .layout-align-gt-xs-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - .layout-align-gt-xs-space-around, - .layout-align-gt-xs-space-around-center, - .layout-align-gt-xs-space-around-start, - .layout-align-gt-xs-space-around-end, - .layout-align-gt-xs-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - .layout-align-gt-xs-space-between, - .layout-align-gt-xs-space-between-center, - .layout-align-gt-xs-space-between-start, - .layout-align-gt-xs-space-between-end, - .layout-align-gt-xs-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - .layout-align-gt-xs-start-start, - .layout-align-gt-xs-center-start, - .layout-align-gt-xs-end-start, - .layout-align-gt-xs-space-between-start, - .layout-align-gt-xs-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - .layout-align-gt-xs-start-center, - .layout-align-gt-xs-center-center, - .layout-align-gt-xs-end-center, - .layout-align-gt-xs-space-between-center, - .layout-align-gt-xs-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - .layout-align-gt-xs-start-center > *, - .layout-align-gt-xs-center-center > *, - .layout-align-gt-xs-end-center > *, - .layout-align-gt-xs-space-between-center > *, - .layout-align-gt-xs-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - .layout-align-gt-xs-start-end, - .layout-align-gt-xs-center-end, - .layout-align-gt-xs-end-end, - .layout-align-gt-xs-space-between-end, - .layout-align-gt-xs-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - .layout-align-gt-xs-start-stretch, - .layout-align-gt-xs-center-stretch, - .layout-align-gt-xs-end-stretch, - .layout-align-gt-xs-space-between-stretch, - .layout-align-gt-xs-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - .flex-gt-xs { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } } - -@media screen\0 and (min-width: 600px) { - .flex-gt-xs { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -@media (min-width: 600px) { - .flex-gt-xs-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - .flex-gt-xs-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-gt-xs-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - .flex-gt-xs-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - .flex-gt-xs-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - .flex-gt-xs-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-gt-xs-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-0, - .layout-gt-xs-row > .flex-gt-xs-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-0, - .layout-gt-xs-column > .flex-gt-xs-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - .flex-gt-xs-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-5, - .layout-gt-xs-row > .flex-gt-xs-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-5, - .layout-gt-xs-column > .flex-gt-xs-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - .flex-gt-xs-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-10, - .layout-gt-xs-row > .flex-gt-xs-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-10, - .layout-gt-xs-column > .flex-gt-xs-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - .flex-gt-xs-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-15, - .layout-gt-xs-row > .flex-gt-xs-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-15, - .layout-gt-xs-column > .flex-gt-xs-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - .flex-gt-xs-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-20, - .layout-gt-xs-row > .flex-gt-xs-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-20, - .layout-gt-xs-column > .flex-gt-xs-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - .flex-gt-xs-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-25, - .layout-gt-xs-row > .flex-gt-xs-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-25, - .layout-gt-xs-column > .flex-gt-xs-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - .flex-gt-xs-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-30, - .layout-gt-xs-row > .flex-gt-xs-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-30, - .layout-gt-xs-column > .flex-gt-xs-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - .flex-gt-xs-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-35, - .layout-gt-xs-row > .flex-gt-xs-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-35, - .layout-gt-xs-column > .flex-gt-xs-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - .flex-gt-xs-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-40, - .layout-gt-xs-row > .flex-gt-xs-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-40, - .layout-gt-xs-column > .flex-gt-xs-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - .flex-gt-xs-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-45, - .layout-gt-xs-row > .flex-gt-xs-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-45, - .layout-gt-xs-column > .flex-gt-xs-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - .flex-gt-xs-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-50, - .layout-gt-xs-row > .flex-gt-xs-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-50, - .layout-gt-xs-column > .flex-gt-xs-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - .flex-gt-xs-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-55, - .layout-gt-xs-row > .flex-gt-xs-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-55, - .layout-gt-xs-column > .flex-gt-xs-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - .flex-gt-xs-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-60, - .layout-gt-xs-row > .flex-gt-xs-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-60, - .layout-gt-xs-column > .flex-gt-xs-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - .flex-gt-xs-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-65, - .layout-gt-xs-row > .flex-gt-xs-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-65, - .layout-gt-xs-column > .flex-gt-xs-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - .flex-gt-xs-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-70, - .layout-gt-xs-row > .flex-gt-xs-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-70, - .layout-gt-xs-column > .flex-gt-xs-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - .flex-gt-xs-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-75, - .layout-gt-xs-row > .flex-gt-xs-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-75, - .layout-gt-xs-column > .flex-gt-xs-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - .flex-gt-xs-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-80, - .layout-gt-xs-row > .flex-gt-xs-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-80, - .layout-gt-xs-column > .flex-gt-xs-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - .flex-gt-xs-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-85, - .layout-gt-xs-row > .flex-gt-xs-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-85, - .layout-gt-xs-column > .flex-gt-xs-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - .flex-gt-xs-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-90, - .layout-gt-xs-row > .flex-gt-xs-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-90, - .layout-gt-xs-column > .flex-gt-xs-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - .flex-gt-xs-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-95, - .layout-gt-xs-row > .flex-gt-xs-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-95, - .layout-gt-xs-column > .flex-gt-xs-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - .flex-gt-xs-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-100, - .layout-gt-xs-row > .flex-gt-xs-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-100, - .layout-gt-xs-column > .flex-gt-xs-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-33, .layout-row > .flex-gt-xs-33, .layout-gt-xs-row > .flex-gt-xs-33, .layout-gt-xs-row > .flex-gt-xs-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-xs-66, .layout-row > .flex-gt-xs-66, .layout-gt-xs-row > .flex-gt-xs-66, .layout-gt-xs-row > .flex-gt-xs-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-xs-33, .layout-column > .flex-gt-xs-33, .layout-gt-xs-column > .flex-gt-xs-33, .layout-gt-xs-column > .flex-gt-xs-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - .layout-column > .flex-gt-xs-66, .layout-column > .flex-gt-xs-66, .layout-gt-xs-column > .flex-gt-xs-66, .layout-gt-xs-column > .flex-gt-xs-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - .layout-gt-xs, .layout-gt-xs-column, .layout-gt-xs-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - .layout-gt-xs-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - .layout-gt-xs-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } } - -@media (min-width: 600px) and (max-width: 959px) { - .hide:not(.show-gt-xs):not(.show-sm):not(.show), .hide-gt-xs:not(.show-gt-xs):not(.show-sm):not(.show) { - display: none; } - .hide-sm:not(.show-gt-xs):not(.show-sm):not(.show) { - display: none; } - .flex-order-sm--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - .flex-order-sm--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - .flex-order-sm--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - .flex-order-sm--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - .flex-order-sm--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - .flex-order-sm--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - .flex-order-sm--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - .flex-order-sm--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - .flex-order-sm--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - .flex-order-sm--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - .flex-order-sm--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - .flex-order-sm--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - .flex-order-sm--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - .flex-order-sm--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - .flex-order-sm--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - .flex-order-sm--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - .flex-order-sm--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - .flex-order-sm--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - .flex-order-sm--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - .flex-order-sm--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - .flex-order-sm-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - .flex-order-sm-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - .flex-order-sm-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - .flex-order-sm-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - .flex-order-sm-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - .flex-order-sm-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - .flex-order-sm-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - .flex-order-sm-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - .flex-order-sm-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - .flex-order-sm-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - .flex-order-sm-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - .flex-order-sm-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - .flex-order-sm-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - .flex-order-sm-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - .flex-order-sm-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - .flex-order-sm-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - .flex-order-sm-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - .flex-order-sm-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - .flex-order-sm-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - .flex-order-sm-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - .flex-order-sm-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - .offset-sm-0, .flex-offset-sm-0 { - margin-left: 0%; } - .offset-sm-5, .flex-offset-sm-5 { - margin-left: 5%; } - .offset-sm-10, .flex-offset-sm-10 { - margin-left: 10%; } - .offset-sm-15, .flex-offset-sm-15 { - margin-left: 15%; } - .offset-sm-20, .flex-offset-sm-20 { - margin-left: 20%; } - .offset-sm-25, .flex-offset-sm-25 { - margin-left: 25%; } - .offset-sm-30, .flex-offset-sm-30 { - margin-left: 30%; } - .offset-sm-35, .flex-offset-sm-35 { - margin-left: 35%; } - .offset-sm-40, .flex-offset-sm-40 { - margin-left: 40%; } - .offset-sm-45, .flex-offset-sm-45 { - margin-left: 45%; } - .offset-sm-50, .flex-offset-sm-50 { - margin-left: 50%; } - .offset-sm-55, .flex-offset-sm-55 { - margin-left: 55%; } - .offset-sm-60, .flex-offset-sm-60 { - margin-left: 60%; } - .offset-sm-65, .flex-offset-sm-65 { - margin-left: 65%; } - .offset-sm-70, .flex-offset-sm-70 { - margin-left: 70%; } - .offset-sm-75, .flex-offset-sm-75 { - margin-left: 75%; } - .offset-sm-80, .flex-offset-sm-80 { - margin-left: 80%; } - .offset-sm-85, .flex-offset-sm-85 { - margin-left: 85%; } - .offset-sm-90, .flex-offset-sm-90 { - margin-left: 90%; } - .offset-sm-95, .flex-offset-sm-95 { - margin-left: 95%; } - .offset-sm-33, .flex-offset-sm-33 { - margin-left: calc(100% / 3); } - .offset-sm-66, .flex-offset-sm-66 { - margin-left: calc(200% / 3); } - .layout-align-sm { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - .layout-align-sm-start, - .layout-align-sm-start-start, - .layout-align-sm-start-center, - .layout-align-sm-start-end, - .layout-align-sm-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - .layout-align-sm-center, - .layout-align-sm-center-start, - .layout-align-sm-center-center, - .layout-align-sm-center-end, - .layout-align-sm-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - .layout-align-sm-end, - .layout-align-sm-end-start, - .layout-align-sm-end-center, - .layout-align-sm-end-end, - .layout-align-sm-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - .layout-align-sm-space-around, - .layout-align-sm-space-around-center, - .layout-align-sm-space-around-start, - .layout-align-sm-space-around-end, - .layout-align-sm-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - .layout-align-sm-space-between, - .layout-align-sm-space-between-center, - .layout-align-sm-space-between-start, - .layout-align-sm-space-between-end, - .layout-align-sm-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - .layout-align-sm-start-start, - .layout-align-sm-center-start, - .layout-align-sm-end-start, - .layout-align-sm-space-between-start, - .layout-align-sm-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - .layout-align-sm-start-center, - .layout-align-sm-center-center, - .layout-align-sm-end-center, - .layout-align-sm-space-between-center, - .layout-align-sm-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - .layout-align-sm-start-center > *, - .layout-align-sm-center-center > *, - .layout-align-sm-end-center > *, - .layout-align-sm-space-between-center > *, - .layout-align-sm-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - .layout-align-sm-start-end, - .layout-align-sm-center-end, - .layout-align-sm-end-end, - .layout-align-sm-space-between-end, - .layout-align-sm-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - .layout-align-sm-start-stretch, - .layout-align-sm-center-stretch, - .layout-align-sm-end-stretch, - .layout-align-sm-space-between-stretch, - .layout-align-sm-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - .flex-sm { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } } - -@media screen\0 and (min-width: 600px) and (max-width: 959px) { - .flex-sm { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -@media (min-width: 600px) and (max-width: 959px) { - .flex-sm-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - .flex-sm-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-sm-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - .flex-sm-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - .flex-sm-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - .flex-sm-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-sm-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-0, - .layout-sm-row > .flex-sm-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-0, - .layout-sm-column > .flex-sm-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - .flex-sm-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-5, - .layout-sm-row > .flex-sm-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-5, - .layout-sm-column > .flex-sm-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - .flex-sm-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-10, - .layout-sm-row > .flex-sm-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-10, - .layout-sm-column > .flex-sm-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - .flex-sm-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-15, - .layout-sm-row > .flex-sm-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-15, - .layout-sm-column > .flex-sm-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - .flex-sm-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-20, - .layout-sm-row > .flex-sm-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-20, - .layout-sm-column > .flex-sm-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - .flex-sm-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-25, - .layout-sm-row > .flex-sm-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-25, - .layout-sm-column > .flex-sm-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - .flex-sm-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-30, - .layout-sm-row > .flex-sm-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-30, - .layout-sm-column > .flex-sm-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - .flex-sm-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-35, - .layout-sm-row > .flex-sm-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-35, - .layout-sm-column > .flex-sm-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - .flex-sm-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-40, - .layout-sm-row > .flex-sm-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-40, - .layout-sm-column > .flex-sm-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - .flex-sm-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-45, - .layout-sm-row > .flex-sm-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-45, - .layout-sm-column > .flex-sm-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - .flex-sm-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-50, - .layout-sm-row > .flex-sm-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-50, - .layout-sm-column > .flex-sm-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - .flex-sm-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-55, - .layout-sm-row > .flex-sm-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-55, - .layout-sm-column > .flex-sm-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - .flex-sm-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-60, - .layout-sm-row > .flex-sm-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-60, - .layout-sm-column > .flex-sm-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - .flex-sm-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-65, - .layout-sm-row > .flex-sm-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-65, - .layout-sm-column > .flex-sm-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - .flex-sm-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-70, - .layout-sm-row > .flex-sm-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-70, - .layout-sm-column > .flex-sm-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - .flex-sm-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-75, - .layout-sm-row > .flex-sm-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-75, - .layout-sm-column > .flex-sm-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - .flex-sm-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-80, - .layout-sm-row > .flex-sm-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-80, - .layout-sm-column > .flex-sm-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - .flex-sm-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-85, - .layout-sm-row > .flex-sm-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-85, - .layout-sm-column > .flex-sm-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - .flex-sm-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-90, - .layout-sm-row > .flex-sm-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-90, - .layout-sm-column > .flex-sm-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - .flex-sm-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-95, - .layout-sm-row > .flex-sm-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-95, - .layout-sm-column > .flex-sm-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - .flex-sm-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-100, - .layout-sm-row > .flex-sm-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-100, - .layout-sm-column > .flex-sm-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-33, .layout-row > .flex-sm-33, .layout-sm-row > .flex-sm-33, .layout-sm-row > .flex-sm-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-sm-66, .layout-row > .flex-sm-66, .layout-sm-row > .flex-sm-66, .layout-sm-row > .flex-sm-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-sm-33, .layout-column > .flex-sm-33, .layout-sm-column > .flex-sm-33, .layout-sm-column > .flex-sm-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - .layout-column > .flex-sm-66, .layout-column > .flex-sm-66, .layout-sm-column > .flex-sm-66, .layout-sm-column > .flex-sm-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - .layout-sm, .layout-sm-column, .layout-sm-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - .layout-sm-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - .layout-sm-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } } - -@media (min-width: 960px) { - .flex-order-gt-sm--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - .flex-order-gt-sm--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - .flex-order-gt-sm--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - .flex-order-gt-sm--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - .flex-order-gt-sm--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - .flex-order-gt-sm--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - .flex-order-gt-sm--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - .flex-order-gt-sm--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - .flex-order-gt-sm--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - .flex-order-gt-sm--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - .flex-order-gt-sm--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - .flex-order-gt-sm--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - .flex-order-gt-sm--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - .flex-order-gt-sm--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - .flex-order-gt-sm--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - .flex-order-gt-sm--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - .flex-order-gt-sm--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - .flex-order-gt-sm--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - .flex-order-gt-sm--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - .flex-order-gt-sm--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - .flex-order-gt-sm-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - .flex-order-gt-sm-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - .flex-order-gt-sm-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - .flex-order-gt-sm-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - .flex-order-gt-sm-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - .flex-order-gt-sm-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - .flex-order-gt-sm-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - .flex-order-gt-sm-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - .flex-order-gt-sm-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - .flex-order-gt-sm-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - .flex-order-gt-sm-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - .flex-order-gt-sm-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - .flex-order-gt-sm-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - .flex-order-gt-sm-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - .flex-order-gt-sm-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - .flex-order-gt-sm-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - .flex-order-gt-sm-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - .flex-order-gt-sm-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - .flex-order-gt-sm-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - .flex-order-gt-sm-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - .flex-order-gt-sm-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - .offset-gt-sm-0, .flex-offset-gt-sm-0 { - margin-left: 0%; } - .offset-gt-sm-5, .flex-offset-gt-sm-5 { - margin-left: 5%; } - .offset-gt-sm-10, .flex-offset-gt-sm-10 { - margin-left: 10%; } - .offset-gt-sm-15, .flex-offset-gt-sm-15 { - margin-left: 15%; } - .offset-gt-sm-20, .flex-offset-gt-sm-20 { - margin-left: 20%; } - .offset-gt-sm-25, .flex-offset-gt-sm-25 { - margin-left: 25%; } - .offset-gt-sm-30, .flex-offset-gt-sm-30 { - margin-left: 30%; } - .offset-gt-sm-35, .flex-offset-gt-sm-35 { - margin-left: 35%; } - .offset-gt-sm-40, .flex-offset-gt-sm-40 { - margin-left: 40%; } - .offset-gt-sm-45, .flex-offset-gt-sm-45 { - margin-left: 45%; } - .offset-gt-sm-50, .flex-offset-gt-sm-50 { - margin-left: 50%; } - .offset-gt-sm-55, .flex-offset-gt-sm-55 { - margin-left: 55%; } - .offset-gt-sm-60, .flex-offset-gt-sm-60 { - margin-left: 60%; } - .offset-gt-sm-65, .flex-offset-gt-sm-65 { - margin-left: 65%; } - .offset-gt-sm-70, .flex-offset-gt-sm-70 { - margin-left: 70%; } - .offset-gt-sm-75, .flex-offset-gt-sm-75 { - margin-left: 75%; } - .offset-gt-sm-80, .flex-offset-gt-sm-80 { - margin-left: 80%; } - .offset-gt-sm-85, .flex-offset-gt-sm-85 { - margin-left: 85%; } - .offset-gt-sm-90, .flex-offset-gt-sm-90 { - margin-left: 90%; } - .offset-gt-sm-95, .flex-offset-gt-sm-95 { - margin-left: 95%; } - .offset-gt-sm-33, .flex-offset-gt-sm-33 { - margin-left: calc(100% / 3); } - .offset-gt-sm-66, .flex-offset-gt-sm-66 { - margin-left: calc(200% / 3); } - .layout-align-gt-sm { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - .layout-align-gt-sm-start, - .layout-align-gt-sm-start-start, - .layout-align-gt-sm-start-center, - .layout-align-gt-sm-start-end, - .layout-align-gt-sm-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - .layout-align-gt-sm-center, - .layout-align-gt-sm-center-start, - .layout-align-gt-sm-center-center, - .layout-align-gt-sm-center-end, - .layout-align-gt-sm-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - .layout-align-gt-sm-end, - .layout-align-gt-sm-end-start, - .layout-align-gt-sm-end-center, - .layout-align-gt-sm-end-end, - .layout-align-gt-sm-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - .layout-align-gt-sm-space-around, - .layout-align-gt-sm-space-around-center, - .layout-align-gt-sm-space-around-start, - .layout-align-gt-sm-space-around-end, - .layout-align-gt-sm-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - .layout-align-gt-sm-space-between, - .layout-align-gt-sm-space-between-center, - .layout-align-gt-sm-space-between-start, - .layout-align-gt-sm-space-between-end, - .layout-align-gt-sm-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - .layout-align-gt-sm-start-start, - .layout-align-gt-sm-center-start, - .layout-align-gt-sm-end-start, - .layout-align-gt-sm-space-between-start, - .layout-align-gt-sm-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - .layout-align-gt-sm-start-center, - .layout-align-gt-sm-center-center, - .layout-align-gt-sm-end-center, - .layout-align-gt-sm-space-between-center, - .layout-align-gt-sm-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - .layout-align-gt-sm-start-center > *, - .layout-align-gt-sm-center-center > *, - .layout-align-gt-sm-end-center > *, - .layout-align-gt-sm-space-between-center > *, - .layout-align-gt-sm-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - .layout-align-gt-sm-start-end, - .layout-align-gt-sm-center-end, - .layout-align-gt-sm-end-end, - .layout-align-gt-sm-space-between-end, - .layout-align-gt-sm-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - .layout-align-gt-sm-start-stretch, - .layout-align-gt-sm-center-stretch, - .layout-align-gt-sm-end-stretch, - .layout-align-gt-sm-space-between-stretch, - .layout-align-gt-sm-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - .flex-gt-sm { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } } - -@media screen\0 and (min-width: 960px) { - .flex-gt-sm { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -@media (min-width: 960px) { - .flex-gt-sm-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - .flex-gt-sm-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-gt-sm-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - .flex-gt-sm-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - .flex-gt-sm-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - .flex-gt-sm-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-gt-sm-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-0, - .layout-gt-sm-row > .flex-gt-sm-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-0, - .layout-gt-sm-column > .flex-gt-sm-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - .flex-gt-sm-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-5, - .layout-gt-sm-row > .flex-gt-sm-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-5, - .layout-gt-sm-column > .flex-gt-sm-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - .flex-gt-sm-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-10, - .layout-gt-sm-row > .flex-gt-sm-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-10, - .layout-gt-sm-column > .flex-gt-sm-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - .flex-gt-sm-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-15, - .layout-gt-sm-row > .flex-gt-sm-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-15, - .layout-gt-sm-column > .flex-gt-sm-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - .flex-gt-sm-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-20, - .layout-gt-sm-row > .flex-gt-sm-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-20, - .layout-gt-sm-column > .flex-gt-sm-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - .flex-gt-sm-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-25, - .layout-gt-sm-row > .flex-gt-sm-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-25, - .layout-gt-sm-column > .flex-gt-sm-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - .flex-gt-sm-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-30, - .layout-gt-sm-row > .flex-gt-sm-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-30, - .layout-gt-sm-column > .flex-gt-sm-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - .flex-gt-sm-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-35, - .layout-gt-sm-row > .flex-gt-sm-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-35, - .layout-gt-sm-column > .flex-gt-sm-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - .flex-gt-sm-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-40, - .layout-gt-sm-row > .flex-gt-sm-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-40, - .layout-gt-sm-column > .flex-gt-sm-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - .flex-gt-sm-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-45, - .layout-gt-sm-row > .flex-gt-sm-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-45, - .layout-gt-sm-column > .flex-gt-sm-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - .flex-gt-sm-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-50, - .layout-gt-sm-row > .flex-gt-sm-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-50, - .layout-gt-sm-column > .flex-gt-sm-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - .flex-gt-sm-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-55, - .layout-gt-sm-row > .flex-gt-sm-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-55, - .layout-gt-sm-column > .flex-gt-sm-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - .flex-gt-sm-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-60, - .layout-gt-sm-row > .flex-gt-sm-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-60, - .layout-gt-sm-column > .flex-gt-sm-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - .flex-gt-sm-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-65, - .layout-gt-sm-row > .flex-gt-sm-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-65, - .layout-gt-sm-column > .flex-gt-sm-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - .flex-gt-sm-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-70, - .layout-gt-sm-row > .flex-gt-sm-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-70, - .layout-gt-sm-column > .flex-gt-sm-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - .flex-gt-sm-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-75, - .layout-gt-sm-row > .flex-gt-sm-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-75, - .layout-gt-sm-column > .flex-gt-sm-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - .flex-gt-sm-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-80, - .layout-gt-sm-row > .flex-gt-sm-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-80, - .layout-gt-sm-column > .flex-gt-sm-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - .flex-gt-sm-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-85, - .layout-gt-sm-row > .flex-gt-sm-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-85, - .layout-gt-sm-column > .flex-gt-sm-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - .flex-gt-sm-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-90, - .layout-gt-sm-row > .flex-gt-sm-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-90, - .layout-gt-sm-column > .flex-gt-sm-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - .flex-gt-sm-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-95, - .layout-gt-sm-row > .flex-gt-sm-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-95, - .layout-gt-sm-column > .flex-gt-sm-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - .flex-gt-sm-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-100, - .layout-gt-sm-row > .flex-gt-sm-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-100, - .layout-gt-sm-column > .flex-gt-sm-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-33, .layout-row > .flex-gt-sm-33, .layout-gt-sm-row > .flex-gt-sm-33, .layout-gt-sm-row > .flex-gt-sm-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-sm-66, .layout-row > .flex-gt-sm-66, .layout-gt-sm-row > .flex-gt-sm-66, .layout-gt-sm-row > .flex-gt-sm-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-sm-33, .layout-column > .flex-gt-sm-33, .layout-gt-sm-column > .flex-gt-sm-33, .layout-gt-sm-column > .flex-gt-sm-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - .layout-column > .flex-gt-sm-66, .layout-column > .flex-gt-sm-66, .layout-gt-sm-column > .flex-gt-sm-66, .layout-gt-sm-column > .flex-gt-sm-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - .layout-gt-sm, .layout-gt-sm-column, .layout-gt-sm-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - .layout-gt-sm-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - .layout-gt-sm-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } } - -@media (min-width: 960px) and (max-width: 1279px) { - .hide:not(.show-gt-xs):not(.show-gt-sm):not(.show-md):not(.show), .hide-gt-xs:not(.show-gt-xs):not(.show-gt-sm):not(.show-md):not(.show), .hide-gt-sm:not(.show-gt-xs):not(.show-gt-sm):not(.show-md):not(.show) { - display: none; } - .hide-md:not(.show-md):not(.show-gt-sm):not(.show-gt-xs):not(.show) { - display: none; } - .flex-order-md--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - .flex-order-md--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - .flex-order-md--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - .flex-order-md--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - .flex-order-md--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - .flex-order-md--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - .flex-order-md--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - .flex-order-md--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - .flex-order-md--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - .flex-order-md--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - .flex-order-md--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - .flex-order-md--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - .flex-order-md--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - .flex-order-md--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - .flex-order-md--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - .flex-order-md--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - .flex-order-md--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - .flex-order-md--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - .flex-order-md--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - .flex-order-md--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - .flex-order-md-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - .flex-order-md-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - .flex-order-md-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - .flex-order-md-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - .flex-order-md-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - .flex-order-md-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - .flex-order-md-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - .flex-order-md-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - .flex-order-md-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - .flex-order-md-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - .flex-order-md-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - .flex-order-md-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - .flex-order-md-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - .flex-order-md-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - .flex-order-md-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - .flex-order-md-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - .flex-order-md-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - .flex-order-md-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - .flex-order-md-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - .flex-order-md-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - .flex-order-md-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - .offset-md-0, .flex-offset-md-0 { - margin-left: 0%; } - .offset-md-5, .flex-offset-md-5 { - margin-left: 5%; } - .offset-md-10, .flex-offset-md-10 { - margin-left: 10%; } - .offset-md-15, .flex-offset-md-15 { - margin-left: 15%; } - .offset-md-20, .flex-offset-md-20 { - margin-left: 20%; } - .offset-md-25, .flex-offset-md-25 { - margin-left: 25%; } - .offset-md-30, .flex-offset-md-30 { - margin-left: 30%; } - .offset-md-35, .flex-offset-md-35 { - margin-left: 35%; } - .offset-md-40, .flex-offset-md-40 { - margin-left: 40%; } - .offset-md-45, .flex-offset-md-45 { - margin-left: 45%; } - .offset-md-50, .flex-offset-md-50 { - margin-left: 50%; } - .offset-md-55, .flex-offset-md-55 { - margin-left: 55%; } - .offset-md-60, .flex-offset-md-60 { - margin-left: 60%; } - .offset-md-65, .flex-offset-md-65 { - margin-left: 65%; } - .offset-md-70, .flex-offset-md-70 { - margin-left: 70%; } - .offset-md-75, .flex-offset-md-75 { - margin-left: 75%; } - .offset-md-80, .flex-offset-md-80 { - margin-left: 80%; } - .offset-md-85, .flex-offset-md-85 { - margin-left: 85%; } - .offset-md-90, .flex-offset-md-90 { - margin-left: 90%; } - .offset-md-95, .flex-offset-md-95 { - margin-left: 95%; } - .offset-md-33, .flex-offset-md-33 { - margin-left: calc(100% / 3); } - .offset-md-66, .flex-offset-md-66 { - margin-left: calc(200% / 3); } - .layout-align-md { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - .layout-align-md-start, - .layout-align-md-start-start, - .layout-align-md-start-center, - .layout-align-md-start-end, - .layout-align-md-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - .layout-align-md-center, - .layout-align-md-center-start, - .layout-align-md-center-center, - .layout-align-md-center-end, - .layout-align-md-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - .layout-align-md-end, - .layout-align-md-end-start, - .layout-align-md-end-center, - .layout-align-md-end-end, - .layout-align-md-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - .layout-align-md-space-around, - .layout-align-md-space-around-center, - .layout-align-md-space-around-start, - .layout-align-md-space-around-end, - .layout-align-md-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - .layout-align-md-space-between, - .layout-align-md-space-between-center, - .layout-align-md-space-between-start, - .layout-align-md-space-between-end, - .layout-align-md-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - .layout-align-md-start-start, - .layout-align-md-center-start, - .layout-align-md-end-start, - .layout-align-md-space-between-start, - .layout-align-md-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - .layout-align-md-start-center, - .layout-align-md-center-center, - .layout-align-md-end-center, - .layout-align-md-space-between-center, - .layout-align-md-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - .layout-align-md-start-center > *, - .layout-align-md-center-center > *, - .layout-align-md-end-center > *, - .layout-align-md-space-between-center > *, - .layout-align-md-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - .layout-align-md-start-end, - .layout-align-md-center-end, - .layout-align-md-end-end, - .layout-align-md-space-between-end, - .layout-align-md-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - .layout-align-md-start-stretch, - .layout-align-md-center-stretch, - .layout-align-md-end-stretch, - .layout-align-md-space-between-stretch, - .layout-align-md-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - .flex-md { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } } - -@media screen\0 and (min-width: 960px) and (max-width: 1279px) { - .flex-md { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -@media (min-width: 960px) and (max-width: 1279px) { - .flex-md-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - .flex-md-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-md-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - .flex-md-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - .flex-md-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - .flex-md-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-md-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-0, - .layout-md-row > .flex-md-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-0, - .layout-md-column > .flex-md-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - .flex-md-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-5, - .layout-md-row > .flex-md-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-5, - .layout-md-column > .flex-md-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - .flex-md-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-10, - .layout-md-row > .flex-md-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-10, - .layout-md-column > .flex-md-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - .flex-md-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-15, - .layout-md-row > .flex-md-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-15, - .layout-md-column > .flex-md-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - .flex-md-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-20, - .layout-md-row > .flex-md-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-20, - .layout-md-column > .flex-md-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - .flex-md-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-25, - .layout-md-row > .flex-md-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-25, - .layout-md-column > .flex-md-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - .flex-md-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-30, - .layout-md-row > .flex-md-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-30, - .layout-md-column > .flex-md-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - .flex-md-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-35, - .layout-md-row > .flex-md-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-35, - .layout-md-column > .flex-md-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - .flex-md-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-40, - .layout-md-row > .flex-md-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-40, - .layout-md-column > .flex-md-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - .flex-md-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-45, - .layout-md-row > .flex-md-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-45, - .layout-md-column > .flex-md-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - .flex-md-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-50, - .layout-md-row > .flex-md-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-50, - .layout-md-column > .flex-md-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - .flex-md-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-55, - .layout-md-row > .flex-md-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-55, - .layout-md-column > .flex-md-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - .flex-md-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-60, - .layout-md-row > .flex-md-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-60, - .layout-md-column > .flex-md-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - .flex-md-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-65, - .layout-md-row > .flex-md-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-65, - .layout-md-column > .flex-md-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - .flex-md-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-70, - .layout-md-row > .flex-md-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-70, - .layout-md-column > .flex-md-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - .flex-md-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-75, - .layout-md-row > .flex-md-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-75, - .layout-md-column > .flex-md-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - .flex-md-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-80, - .layout-md-row > .flex-md-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-80, - .layout-md-column > .flex-md-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - .flex-md-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-85, - .layout-md-row > .flex-md-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-85, - .layout-md-column > .flex-md-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - .flex-md-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-90, - .layout-md-row > .flex-md-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-90, - .layout-md-column > .flex-md-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - .flex-md-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-95, - .layout-md-row > .flex-md-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-95, - .layout-md-column > .flex-md-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - .flex-md-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-100, - .layout-md-row > .flex-md-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-100, - .layout-md-column > .flex-md-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-33, .layout-row > .flex-md-33, .layout-md-row > .flex-md-33, .layout-md-row > .flex-md-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-md-66, .layout-row > .flex-md-66, .layout-md-row > .flex-md-66, .layout-md-row > .flex-md-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-md-33, .layout-column > .flex-md-33, .layout-md-column > .flex-md-33, .layout-md-column > .flex-md-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - .layout-column > .flex-md-66, .layout-column > .flex-md-66, .layout-md-column > .flex-md-66, .layout-md-column > .flex-md-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - .layout-md, .layout-md-column, .layout-md-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - .layout-md-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - .layout-md-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } } - -@media (min-width: 1280px) { - .flex-order-gt-md--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - .flex-order-gt-md--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - .flex-order-gt-md--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - .flex-order-gt-md--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - .flex-order-gt-md--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - .flex-order-gt-md--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - .flex-order-gt-md--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - .flex-order-gt-md--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - .flex-order-gt-md--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - .flex-order-gt-md--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - .flex-order-gt-md--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - .flex-order-gt-md--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - .flex-order-gt-md--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - .flex-order-gt-md--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - .flex-order-gt-md--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - .flex-order-gt-md--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - .flex-order-gt-md--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - .flex-order-gt-md--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - .flex-order-gt-md--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - .flex-order-gt-md--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - .flex-order-gt-md-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - .flex-order-gt-md-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - .flex-order-gt-md-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - .flex-order-gt-md-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - .flex-order-gt-md-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - .flex-order-gt-md-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - .flex-order-gt-md-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - .flex-order-gt-md-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - .flex-order-gt-md-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - .flex-order-gt-md-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - .flex-order-gt-md-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - .flex-order-gt-md-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - .flex-order-gt-md-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - .flex-order-gt-md-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - .flex-order-gt-md-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - .flex-order-gt-md-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - .flex-order-gt-md-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - .flex-order-gt-md-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - .flex-order-gt-md-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - .flex-order-gt-md-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - .flex-order-gt-md-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - .offset-gt-md-0, .flex-offset-gt-md-0 { - margin-left: 0%; } - .offset-gt-md-5, .flex-offset-gt-md-5 { - margin-left: 5%; } - .offset-gt-md-10, .flex-offset-gt-md-10 { - margin-left: 10%; } - .offset-gt-md-15, .flex-offset-gt-md-15 { - margin-left: 15%; } - .offset-gt-md-20, .flex-offset-gt-md-20 { - margin-left: 20%; } - .offset-gt-md-25, .flex-offset-gt-md-25 { - margin-left: 25%; } - .offset-gt-md-30, .flex-offset-gt-md-30 { - margin-left: 30%; } - .offset-gt-md-35, .flex-offset-gt-md-35 { - margin-left: 35%; } - .offset-gt-md-40, .flex-offset-gt-md-40 { - margin-left: 40%; } - .offset-gt-md-45, .flex-offset-gt-md-45 { - margin-left: 45%; } - .offset-gt-md-50, .flex-offset-gt-md-50 { - margin-left: 50%; } - .offset-gt-md-55, .flex-offset-gt-md-55 { - margin-left: 55%; } - .offset-gt-md-60, .flex-offset-gt-md-60 { - margin-left: 60%; } - .offset-gt-md-65, .flex-offset-gt-md-65 { - margin-left: 65%; } - .offset-gt-md-70, .flex-offset-gt-md-70 { - margin-left: 70%; } - .offset-gt-md-75, .flex-offset-gt-md-75 { - margin-left: 75%; } - .offset-gt-md-80, .flex-offset-gt-md-80 { - margin-left: 80%; } - .offset-gt-md-85, .flex-offset-gt-md-85 { - margin-left: 85%; } - .offset-gt-md-90, .flex-offset-gt-md-90 { - margin-left: 90%; } - .offset-gt-md-95, .flex-offset-gt-md-95 { - margin-left: 95%; } - .offset-gt-md-33, .flex-offset-gt-md-33 { - margin-left: calc(100% / 3); } - .offset-gt-md-66, .flex-offset-gt-md-66 { - margin-left: calc(200% / 3); } - .layout-align-gt-md { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - .layout-align-gt-md-start, - .layout-align-gt-md-start-start, - .layout-align-gt-md-start-center, - .layout-align-gt-md-start-end, - .layout-align-gt-md-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - .layout-align-gt-md-center, - .layout-align-gt-md-center-start, - .layout-align-gt-md-center-center, - .layout-align-gt-md-center-end, - .layout-align-gt-md-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - .layout-align-gt-md-end, - .layout-align-gt-md-end-start, - .layout-align-gt-md-end-center, - .layout-align-gt-md-end-end, - .layout-align-gt-md-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - .layout-align-gt-md-space-around, - .layout-align-gt-md-space-around-center, - .layout-align-gt-md-space-around-start, - .layout-align-gt-md-space-around-end, - .layout-align-gt-md-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - .layout-align-gt-md-space-between, - .layout-align-gt-md-space-between-center, - .layout-align-gt-md-space-between-start, - .layout-align-gt-md-space-between-end, - .layout-align-gt-md-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - .layout-align-gt-md-start-start, - .layout-align-gt-md-center-start, - .layout-align-gt-md-end-start, - .layout-align-gt-md-space-between-start, - .layout-align-gt-md-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - .layout-align-gt-md-start-center, - .layout-align-gt-md-center-center, - .layout-align-gt-md-end-center, - .layout-align-gt-md-space-between-center, - .layout-align-gt-md-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - .layout-align-gt-md-start-center > *, - .layout-align-gt-md-center-center > *, - .layout-align-gt-md-end-center > *, - .layout-align-gt-md-space-between-center > *, - .layout-align-gt-md-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - .layout-align-gt-md-start-end, - .layout-align-gt-md-center-end, - .layout-align-gt-md-end-end, - .layout-align-gt-md-space-between-end, - .layout-align-gt-md-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - .layout-align-gt-md-start-stretch, - .layout-align-gt-md-center-stretch, - .layout-align-gt-md-end-stretch, - .layout-align-gt-md-space-between-stretch, - .layout-align-gt-md-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - .flex-gt-md { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } } - -@media screen\0 and (min-width: 1280px) { - .flex-gt-md { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -@media (min-width: 1280px) { - .flex-gt-md-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - .flex-gt-md-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-gt-md-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - .flex-gt-md-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - .flex-gt-md-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - .flex-gt-md-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-gt-md-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-0, - .layout-gt-md-row > .flex-gt-md-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-0, - .layout-gt-md-column > .flex-gt-md-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - .flex-gt-md-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-5, - .layout-gt-md-row > .flex-gt-md-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-5, - .layout-gt-md-column > .flex-gt-md-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - .flex-gt-md-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-10, - .layout-gt-md-row > .flex-gt-md-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-10, - .layout-gt-md-column > .flex-gt-md-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - .flex-gt-md-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-15, - .layout-gt-md-row > .flex-gt-md-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-15, - .layout-gt-md-column > .flex-gt-md-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - .flex-gt-md-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-20, - .layout-gt-md-row > .flex-gt-md-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-20, - .layout-gt-md-column > .flex-gt-md-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - .flex-gt-md-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-25, - .layout-gt-md-row > .flex-gt-md-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-25, - .layout-gt-md-column > .flex-gt-md-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - .flex-gt-md-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-30, - .layout-gt-md-row > .flex-gt-md-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-30, - .layout-gt-md-column > .flex-gt-md-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - .flex-gt-md-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-35, - .layout-gt-md-row > .flex-gt-md-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-35, - .layout-gt-md-column > .flex-gt-md-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - .flex-gt-md-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-40, - .layout-gt-md-row > .flex-gt-md-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-40, - .layout-gt-md-column > .flex-gt-md-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - .flex-gt-md-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-45, - .layout-gt-md-row > .flex-gt-md-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-45, - .layout-gt-md-column > .flex-gt-md-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - .flex-gt-md-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-50, - .layout-gt-md-row > .flex-gt-md-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-50, - .layout-gt-md-column > .flex-gt-md-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - .flex-gt-md-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-55, - .layout-gt-md-row > .flex-gt-md-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-55, - .layout-gt-md-column > .flex-gt-md-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - .flex-gt-md-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-60, - .layout-gt-md-row > .flex-gt-md-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-60, - .layout-gt-md-column > .flex-gt-md-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - .flex-gt-md-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-65, - .layout-gt-md-row > .flex-gt-md-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-65, - .layout-gt-md-column > .flex-gt-md-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - .flex-gt-md-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-70, - .layout-gt-md-row > .flex-gt-md-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-70, - .layout-gt-md-column > .flex-gt-md-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - .flex-gt-md-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-75, - .layout-gt-md-row > .flex-gt-md-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-75, - .layout-gt-md-column > .flex-gt-md-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - .flex-gt-md-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-80, - .layout-gt-md-row > .flex-gt-md-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-80, - .layout-gt-md-column > .flex-gt-md-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - .flex-gt-md-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-85, - .layout-gt-md-row > .flex-gt-md-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-85, - .layout-gt-md-column > .flex-gt-md-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - .flex-gt-md-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-90, - .layout-gt-md-row > .flex-gt-md-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-90, - .layout-gt-md-column > .flex-gt-md-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - .flex-gt-md-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-95, - .layout-gt-md-row > .flex-gt-md-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-95, - .layout-gt-md-column > .flex-gt-md-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - .flex-gt-md-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-100, - .layout-gt-md-row > .flex-gt-md-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-100, - .layout-gt-md-column > .flex-gt-md-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-33, .layout-row > .flex-gt-md-33, .layout-gt-md-row > .flex-gt-md-33, .layout-gt-md-row > .flex-gt-md-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-md-66, .layout-row > .flex-gt-md-66, .layout-gt-md-row > .flex-gt-md-66, .layout-gt-md-row > .flex-gt-md-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-md-33, .layout-column > .flex-gt-md-33, .layout-gt-md-column > .flex-gt-md-33, .layout-gt-md-column > .flex-gt-md-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - .layout-column > .flex-gt-md-66, .layout-column > .flex-gt-md-66, .layout-gt-md-column > .flex-gt-md-66, .layout-gt-md-column > .flex-gt-md-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - .layout-gt-md, .layout-gt-md-column, .layout-gt-md-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - .layout-gt-md-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - .layout-gt-md-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } } - -@media (min-width: 1280px) and (max-width: 1919px) { - .hide:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-lg):not(.show), .hide-gt-xs:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-lg):not(.show), .hide-gt-sm:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-lg):not(.show), .hide-gt-md:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-lg):not(.show) { - display: none; } - .hide-lg:not(.show-lg):not(.show-gt-md):not(.show-gt-sm):not(.show-gt-xs):not(.show) { - display: none; } - .flex-order-lg--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - .flex-order-lg--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - .flex-order-lg--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - .flex-order-lg--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - .flex-order-lg--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - .flex-order-lg--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - .flex-order-lg--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - .flex-order-lg--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - .flex-order-lg--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - .flex-order-lg--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - .flex-order-lg--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - .flex-order-lg--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - .flex-order-lg--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - .flex-order-lg--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - .flex-order-lg--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - .flex-order-lg--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - .flex-order-lg--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - .flex-order-lg--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - .flex-order-lg--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - .flex-order-lg--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - .flex-order-lg-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - .flex-order-lg-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - .flex-order-lg-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - .flex-order-lg-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - .flex-order-lg-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - .flex-order-lg-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - .flex-order-lg-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - .flex-order-lg-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - .flex-order-lg-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - .flex-order-lg-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - .flex-order-lg-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - .flex-order-lg-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - .flex-order-lg-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - .flex-order-lg-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - .flex-order-lg-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - .flex-order-lg-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - .flex-order-lg-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - .flex-order-lg-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - .flex-order-lg-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - .flex-order-lg-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - .flex-order-lg-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - .offset-lg-0, .flex-offset-lg-0 { - margin-left: 0%; } - .offset-lg-5, .flex-offset-lg-5 { - margin-left: 5%; } - .offset-lg-10, .flex-offset-lg-10 { - margin-left: 10%; } - .offset-lg-15, .flex-offset-lg-15 { - margin-left: 15%; } - .offset-lg-20, .flex-offset-lg-20 { - margin-left: 20%; } - .offset-lg-25, .flex-offset-lg-25 { - margin-left: 25%; } - .offset-lg-30, .flex-offset-lg-30 { - margin-left: 30%; } - .offset-lg-35, .flex-offset-lg-35 { - margin-left: 35%; } - .offset-lg-40, .flex-offset-lg-40 { - margin-left: 40%; } - .offset-lg-45, .flex-offset-lg-45 { - margin-left: 45%; } - .offset-lg-50, .flex-offset-lg-50 { - margin-left: 50%; } - .offset-lg-55, .flex-offset-lg-55 { - margin-left: 55%; } - .offset-lg-60, .flex-offset-lg-60 { - margin-left: 60%; } - .offset-lg-65, .flex-offset-lg-65 { - margin-left: 65%; } - .offset-lg-70, .flex-offset-lg-70 { - margin-left: 70%; } - .offset-lg-75, .flex-offset-lg-75 { - margin-left: 75%; } - .offset-lg-80, .flex-offset-lg-80 { - margin-left: 80%; } - .offset-lg-85, .flex-offset-lg-85 { - margin-left: 85%; } - .offset-lg-90, .flex-offset-lg-90 { - margin-left: 90%; } - .offset-lg-95, .flex-offset-lg-95 { - margin-left: 95%; } - .offset-lg-33, .flex-offset-lg-33 { - margin-left: calc(100% / 3); } - .offset-lg-66, .flex-offset-lg-66 { - margin-left: calc(200% / 3); } - .layout-align-lg { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - .layout-align-lg-start, - .layout-align-lg-start-start, - .layout-align-lg-start-center, - .layout-align-lg-start-end, - .layout-align-lg-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - .layout-align-lg-center, - .layout-align-lg-center-start, - .layout-align-lg-center-center, - .layout-align-lg-center-end, - .layout-align-lg-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - .layout-align-lg-end, - .layout-align-lg-end-start, - .layout-align-lg-end-center, - .layout-align-lg-end-end, - .layout-align-lg-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - .layout-align-lg-space-around, - .layout-align-lg-space-around-center, - .layout-align-lg-space-around-start, - .layout-align-lg-space-around-end, - .layout-align-lg-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - .layout-align-lg-space-between, - .layout-align-lg-space-between-center, - .layout-align-lg-space-between-start, - .layout-align-lg-space-between-end, - .layout-align-lg-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - .layout-align-lg-start-start, - .layout-align-lg-center-start, - .layout-align-lg-end-start, - .layout-align-lg-space-between-start, - .layout-align-lg-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - .layout-align-lg-start-center, - .layout-align-lg-center-center, - .layout-align-lg-end-center, - .layout-align-lg-space-between-center, - .layout-align-lg-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - .layout-align-lg-start-center > *, - .layout-align-lg-center-center > *, - .layout-align-lg-end-center > *, - .layout-align-lg-space-between-center > *, - .layout-align-lg-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - .layout-align-lg-start-end, - .layout-align-lg-center-end, - .layout-align-lg-end-end, - .layout-align-lg-space-between-end, - .layout-align-lg-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - .layout-align-lg-start-stretch, - .layout-align-lg-center-stretch, - .layout-align-lg-end-stretch, - .layout-align-lg-space-between-stretch, - .layout-align-lg-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - .flex-lg { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } } - -@media screen\0 and (min-width: 1280px) and (max-width: 1919px) { - .flex-lg { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -@media (min-width: 1280px) and (max-width: 1919px) { - .flex-lg-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - .flex-lg-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-lg-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - .flex-lg-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - .flex-lg-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - .flex-lg-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-lg-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-0, - .layout-lg-row > .flex-lg-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-0, - .layout-lg-column > .flex-lg-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - .flex-lg-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-5, - .layout-lg-row > .flex-lg-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-5, - .layout-lg-column > .flex-lg-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - .flex-lg-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-10, - .layout-lg-row > .flex-lg-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-10, - .layout-lg-column > .flex-lg-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - .flex-lg-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-15, - .layout-lg-row > .flex-lg-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-15, - .layout-lg-column > .flex-lg-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - .flex-lg-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-20, - .layout-lg-row > .flex-lg-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-20, - .layout-lg-column > .flex-lg-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - .flex-lg-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-25, - .layout-lg-row > .flex-lg-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-25, - .layout-lg-column > .flex-lg-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - .flex-lg-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-30, - .layout-lg-row > .flex-lg-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-30, - .layout-lg-column > .flex-lg-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - .flex-lg-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-35, - .layout-lg-row > .flex-lg-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-35, - .layout-lg-column > .flex-lg-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - .flex-lg-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-40, - .layout-lg-row > .flex-lg-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-40, - .layout-lg-column > .flex-lg-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - .flex-lg-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-45, - .layout-lg-row > .flex-lg-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-45, - .layout-lg-column > .flex-lg-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - .flex-lg-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-50, - .layout-lg-row > .flex-lg-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-50, - .layout-lg-column > .flex-lg-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - .flex-lg-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-55, - .layout-lg-row > .flex-lg-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-55, - .layout-lg-column > .flex-lg-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - .flex-lg-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-60, - .layout-lg-row > .flex-lg-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-60, - .layout-lg-column > .flex-lg-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - .flex-lg-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-65, - .layout-lg-row > .flex-lg-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-65, - .layout-lg-column > .flex-lg-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - .flex-lg-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-70, - .layout-lg-row > .flex-lg-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-70, - .layout-lg-column > .flex-lg-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - .flex-lg-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-75, - .layout-lg-row > .flex-lg-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-75, - .layout-lg-column > .flex-lg-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - .flex-lg-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-80, - .layout-lg-row > .flex-lg-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-80, - .layout-lg-column > .flex-lg-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - .flex-lg-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-85, - .layout-lg-row > .flex-lg-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-85, - .layout-lg-column > .flex-lg-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - .flex-lg-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-90, - .layout-lg-row > .flex-lg-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-90, - .layout-lg-column > .flex-lg-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - .flex-lg-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-95, - .layout-lg-row > .flex-lg-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-95, - .layout-lg-column > .flex-lg-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - .flex-lg-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-100, - .layout-lg-row > .flex-lg-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-100, - .layout-lg-column > .flex-lg-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-33, .layout-row > .flex-lg-33, .layout-lg-row > .flex-lg-33, .layout-lg-row > .flex-lg-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-lg-66, .layout-row > .flex-lg-66, .layout-lg-row > .flex-lg-66, .layout-lg-row > .flex-lg-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-lg-33, .layout-column > .flex-lg-33, .layout-lg-column > .flex-lg-33, .layout-lg-column > .flex-lg-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - .layout-column > .flex-lg-66, .layout-column > .flex-lg-66, .layout-lg-column > .flex-lg-66, .layout-lg-column > .flex-lg-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - .layout-lg, .layout-lg-column, .layout-lg-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - .layout-lg-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - .layout-lg-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } } - -@media (min-width: 1920px) { - .flex-order-gt-lg--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - .flex-order-gt-lg--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - .flex-order-gt-lg--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - .flex-order-gt-lg--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - .flex-order-gt-lg--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - .flex-order-gt-lg--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - .flex-order-gt-lg--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - .flex-order-gt-lg--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - .flex-order-gt-lg--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - .flex-order-gt-lg--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - .flex-order-gt-lg--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - .flex-order-gt-lg--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - .flex-order-gt-lg--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - .flex-order-gt-lg--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - .flex-order-gt-lg--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - .flex-order-gt-lg--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - .flex-order-gt-lg--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - .flex-order-gt-lg--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - .flex-order-gt-lg--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - .flex-order-gt-lg--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - .flex-order-gt-lg-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - .flex-order-gt-lg-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - .flex-order-gt-lg-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - .flex-order-gt-lg-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - .flex-order-gt-lg-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - .flex-order-gt-lg-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - .flex-order-gt-lg-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - .flex-order-gt-lg-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - .flex-order-gt-lg-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - .flex-order-gt-lg-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - .flex-order-gt-lg-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - .flex-order-gt-lg-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - .flex-order-gt-lg-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - .flex-order-gt-lg-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - .flex-order-gt-lg-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - .flex-order-gt-lg-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - .flex-order-gt-lg-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - .flex-order-gt-lg-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - .flex-order-gt-lg-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - .flex-order-gt-lg-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - .flex-order-gt-lg-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - .offset-gt-lg-0, .flex-offset-gt-lg-0 { - margin-left: 0%; } - .offset-gt-lg-5, .flex-offset-gt-lg-5 { - margin-left: 5%; } - .offset-gt-lg-10, .flex-offset-gt-lg-10 { - margin-left: 10%; } - .offset-gt-lg-15, .flex-offset-gt-lg-15 { - margin-left: 15%; } - .offset-gt-lg-20, .flex-offset-gt-lg-20 { - margin-left: 20%; } - .offset-gt-lg-25, .flex-offset-gt-lg-25 { - margin-left: 25%; } - .offset-gt-lg-30, .flex-offset-gt-lg-30 { - margin-left: 30%; } - .offset-gt-lg-35, .flex-offset-gt-lg-35 { - margin-left: 35%; } - .offset-gt-lg-40, .flex-offset-gt-lg-40 { - margin-left: 40%; } - .offset-gt-lg-45, .flex-offset-gt-lg-45 { - margin-left: 45%; } - .offset-gt-lg-50, .flex-offset-gt-lg-50 { - margin-left: 50%; } - .offset-gt-lg-55, .flex-offset-gt-lg-55 { - margin-left: 55%; } - .offset-gt-lg-60, .flex-offset-gt-lg-60 { - margin-left: 60%; } - .offset-gt-lg-65, .flex-offset-gt-lg-65 { - margin-left: 65%; } - .offset-gt-lg-70, .flex-offset-gt-lg-70 { - margin-left: 70%; } - .offset-gt-lg-75, .flex-offset-gt-lg-75 { - margin-left: 75%; } - .offset-gt-lg-80, .flex-offset-gt-lg-80 { - margin-left: 80%; } - .offset-gt-lg-85, .flex-offset-gt-lg-85 { - margin-left: 85%; } - .offset-gt-lg-90, .flex-offset-gt-lg-90 { - margin-left: 90%; } - .offset-gt-lg-95, .flex-offset-gt-lg-95 { - margin-left: 95%; } - .offset-gt-lg-33, .flex-offset-gt-lg-33 { - margin-left: calc(100% / 3); } - .offset-gt-lg-66, .flex-offset-gt-lg-66 { - margin-left: calc(200% / 3); } - .layout-align-gt-lg { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - .layout-align-gt-lg-start, - .layout-align-gt-lg-start-start, - .layout-align-gt-lg-start-center, - .layout-align-gt-lg-start-end, - .layout-align-gt-lg-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - .layout-align-gt-lg-center, - .layout-align-gt-lg-center-start, - .layout-align-gt-lg-center-center, - .layout-align-gt-lg-center-end, - .layout-align-gt-lg-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - .layout-align-gt-lg-end, - .layout-align-gt-lg-end-start, - .layout-align-gt-lg-end-center, - .layout-align-gt-lg-end-end, - .layout-align-gt-lg-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - .layout-align-gt-lg-space-around, - .layout-align-gt-lg-space-around-center, - .layout-align-gt-lg-space-around-start, - .layout-align-gt-lg-space-around-end, - .layout-align-gt-lg-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - .layout-align-gt-lg-space-between, - .layout-align-gt-lg-space-between-center, - .layout-align-gt-lg-space-between-start, - .layout-align-gt-lg-space-between-end, - .layout-align-gt-lg-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - .layout-align-gt-lg-start-start, - .layout-align-gt-lg-center-start, - .layout-align-gt-lg-end-start, - .layout-align-gt-lg-space-between-start, - .layout-align-gt-lg-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - .layout-align-gt-lg-start-center, - .layout-align-gt-lg-center-center, - .layout-align-gt-lg-end-center, - .layout-align-gt-lg-space-between-center, - .layout-align-gt-lg-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - .layout-align-gt-lg-start-center > *, - .layout-align-gt-lg-center-center > *, - .layout-align-gt-lg-end-center > *, - .layout-align-gt-lg-space-between-center > *, - .layout-align-gt-lg-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - .layout-align-gt-lg-start-end, - .layout-align-gt-lg-center-end, - .layout-align-gt-lg-end-end, - .layout-align-gt-lg-space-between-end, - .layout-align-gt-lg-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - .layout-align-gt-lg-start-stretch, - .layout-align-gt-lg-center-stretch, - .layout-align-gt-lg-end-stretch, - .layout-align-gt-lg-space-between-stretch, - .layout-align-gt-lg-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - .flex-gt-lg { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } } - -@media screen\0 and (min-width: 1920px) { - .flex-gt-lg { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -@media (min-width: 1920px) { - .flex-gt-lg-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - .flex-gt-lg-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-gt-lg-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - .flex-gt-lg-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - .flex-gt-lg-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - .flex-gt-lg-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-gt-lg-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-0, - .layout-gt-lg-row > .flex-gt-lg-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-0, - .layout-gt-lg-column > .flex-gt-lg-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - .flex-gt-lg-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-5, - .layout-gt-lg-row > .flex-gt-lg-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-5, - .layout-gt-lg-column > .flex-gt-lg-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - .flex-gt-lg-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-10, - .layout-gt-lg-row > .flex-gt-lg-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-10, - .layout-gt-lg-column > .flex-gt-lg-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - .flex-gt-lg-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-15, - .layout-gt-lg-row > .flex-gt-lg-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-15, - .layout-gt-lg-column > .flex-gt-lg-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - .flex-gt-lg-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-20, - .layout-gt-lg-row > .flex-gt-lg-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-20, - .layout-gt-lg-column > .flex-gt-lg-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - .flex-gt-lg-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-25, - .layout-gt-lg-row > .flex-gt-lg-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-25, - .layout-gt-lg-column > .flex-gt-lg-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - .flex-gt-lg-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-30, - .layout-gt-lg-row > .flex-gt-lg-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-30, - .layout-gt-lg-column > .flex-gt-lg-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - .flex-gt-lg-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-35, - .layout-gt-lg-row > .flex-gt-lg-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-35, - .layout-gt-lg-column > .flex-gt-lg-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - .flex-gt-lg-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-40, - .layout-gt-lg-row > .flex-gt-lg-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-40, - .layout-gt-lg-column > .flex-gt-lg-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - .flex-gt-lg-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-45, - .layout-gt-lg-row > .flex-gt-lg-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-45, - .layout-gt-lg-column > .flex-gt-lg-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - .flex-gt-lg-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-50, - .layout-gt-lg-row > .flex-gt-lg-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-50, - .layout-gt-lg-column > .flex-gt-lg-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - .flex-gt-lg-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-55, - .layout-gt-lg-row > .flex-gt-lg-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-55, - .layout-gt-lg-column > .flex-gt-lg-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - .flex-gt-lg-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-60, - .layout-gt-lg-row > .flex-gt-lg-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-60, - .layout-gt-lg-column > .flex-gt-lg-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - .flex-gt-lg-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-65, - .layout-gt-lg-row > .flex-gt-lg-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-65, - .layout-gt-lg-column > .flex-gt-lg-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - .flex-gt-lg-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-70, - .layout-gt-lg-row > .flex-gt-lg-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-70, - .layout-gt-lg-column > .flex-gt-lg-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - .flex-gt-lg-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-75, - .layout-gt-lg-row > .flex-gt-lg-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-75, - .layout-gt-lg-column > .flex-gt-lg-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - .flex-gt-lg-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-80, - .layout-gt-lg-row > .flex-gt-lg-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-80, - .layout-gt-lg-column > .flex-gt-lg-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - .flex-gt-lg-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-85, - .layout-gt-lg-row > .flex-gt-lg-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-85, - .layout-gt-lg-column > .flex-gt-lg-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - .flex-gt-lg-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-90, - .layout-gt-lg-row > .flex-gt-lg-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-90, - .layout-gt-lg-column > .flex-gt-lg-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - .flex-gt-lg-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-95, - .layout-gt-lg-row > .flex-gt-lg-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-95, - .layout-gt-lg-column > .flex-gt-lg-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - .flex-gt-lg-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-100, - .layout-gt-lg-row > .flex-gt-lg-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-100, - .layout-gt-lg-column > .flex-gt-lg-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-33, .layout-row > .flex-gt-lg-33, .layout-gt-lg-row > .flex-gt-lg-33, .layout-gt-lg-row > .flex-gt-lg-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-gt-lg-66, .layout-row > .flex-gt-lg-66, .layout-gt-lg-row > .flex-gt-lg-66, .layout-gt-lg-row > .flex-gt-lg-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-gt-lg-33, .layout-column > .flex-gt-lg-33, .layout-gt-lg-column > .flex-gt-lg-33, .layout-gt-lg-column > .flex-gt-lg-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - .layout-column > .flex-gt-lg-66, .layout-column > .flex-gt-lg-66, .layout-gt-lg-column > .flex-gt-lg-66, .layout-gt-lg-column > .flex-gt-lg-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - .layout-gt-lg, .layout-gt-lg-column, .layout-gt-lg-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - .layout-gt-lg-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - .layout-gt-lg-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - .flex-order-xl--20 { - -webkit-order: -20; - -ms-flex-order: -20; - order: -20; } - .flex-order-xl--19 { - -webkit-order: -19; - -ms-flex-order: -19; - order: -19; } - .flex-order-xl--18 { - -webkit-order: -18; - -ms-flex-order: -18; - order: -18; } - .flex-order-xl--17 { - -webkit-order: -17; - -ms-flex-order: -17; - order: -17; } - .flex-order-xl--16 { - -webkit-order: -16; - -ms-flex-order: -16; - order: -16; } - .flex-order-xl--15 { - -webkit-order: -15; - -ms-flex-order: -15; - order: -15; } - .flex-order-xl--14 { - -webkit-order: -14; - -ms-flex-order: -14; - order: -14; } - .flex-order-xl--13 { - -webkit-order: -13; - -ms-flex-order: -13; - order: -13; } - .flex-order-xl--12 { - -webkit-order: -12; - -ms-flex-order: -12; - order: -12; } - .flex-order-xl--11 { - -webkit-order: -11; - -ms-flex-order: -11; - order: -11; } - .flex-order-xl--10 { - -webkit-order: -10; - -ms-flex-order: -10; - order: -10; } - .flex-order-xl--9 { - -webkit-order: -9; - -ms-flex-order: -9; - order: -9; } - .flex-order-xl--8 { - -webkit-order: -8; - -ms-flex-order: -8; - order: -8; } - .flex-order-xl--7 { - -webkit-order: -7; - -ms-flex-order: -7; - order: -7; } - .flex-order-xl--6 { - -webkit-order: -6; - -ms-flex-order: -6; - order: -6; } - .flex-order-xl--5 { - -webkit-order: -5; - -ms-flex-order: -5; - order: -5; } - .flex-order-xl--4 { - -webkit-order: -4; - -ms-flex-order: -4; - order: -4; } - .flex-order-xl--3 { - -webkit-order: -3; - -ms-flex-order: -3; - order: -3; } - .flex-order-xl--2 { - -webkit-order: -2; - -ms-flex-order: -2; - order: -2; } - .flex-order-xl--1 { - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - .flex-order-xl-0 { - -webkit-order: 0; - -ms-flex-order: 0; - order: 0; } - .flex-order-xl-1 { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - .flex-order-xl-2 { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - .flex-order-xl-3 { - -webkit-order: 3; - -ms-flex-order: 3; - order: 3; } - .flex-order-xl-4 { - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; } - .flex-order-xl-5 { - -webkit-order: 5; - -ms-flex-order: 5; - order: 5; } - .flex-order-xl-6 { - -webkit-order: 6; - -ms-flex-order: 6; - order: 6; } - .flex-order-xl-7 { - -webkit-order: 7; - -ms-flex-order: 7; - order: 7; } - .flex-order-xl-8 { - -webkit-order: 8; - -ms-flex-order: 8; - order: 8; } - .flex-order-xl-9 { - -webkit-order: 9; - -ms-flex-order: 9; - order: 9; } - .flex-order-xl-10 { - -webkit-order: 10; - -ms-flex-order: 10; - order: 10; } - .flex-order-xl-11 { - -webkit-order: 11; - -ms-flex-order: 11; - order: 11; } - .flex-order-xl-12 { - -webkit-order: 12; - -ms-flex-order: 12; - order: 12; } - .flex-order-xl-13 { - -webkit-order: 13; - -ms-flex-order: 13; - order: 13; } - .flex-order-xl-14 { - -webkit-order: 14; - -ms-flex-order: 14; - order: 14; } - .flex-order-xl-15 { - -webkit-order: 15; - -ms-flex-order: 15; - order: 15; } - .flex-order-xl-16 { - -webkit-order: 16; - -ms-flex-order: 16; - order: 16; } - .flex-order-xl-17 { - -webkit-order: 17; - -ms-flex-order: 17; - order: 17; } - .flex-order-xl-18 { - -webkit-order: 18; - -ms-flex-order: 18; - order: 18; } - .flex-order-xl-19 { - -webkit-order: 19; - -ms-flex-order: 19; - order: 19; } - .flex-order-xl-20 { - -webkit-order: 20; - -ms-flex-order: 20; - order: 20; } - .offset-xl-0, .flex-offset-xl-0 { - margin-left: 0%; } - .offset-xl-5, .flex-offset-xl-5 { - margin-left: 5%; } - .offset-xl-10, .flex-offset-xl-10 { - margin-left: 10%; } - .offset-xl-15, .flex-offset-xl-15 { - margin-left: 15%; } - .offset-xl-20, .flex-offset-xl-20 { - margin-left: 20%; } - .offset-xl-25, .flex-offset-xl-25 { - margin-left: 25%; } - .offset-xl-30, .flex-offset-xl-30 { - margin-left: 30%; } - .offset-xl-35, .flex-offset-xl-35 { - margin-left: 35%; } - .offset-xl-40, .flex-offset-xl-40 { - margin-left: 40%; } - .offset-xl-45, .flex-offset-xl-45 { - margin-left: 45%; } - .offset-xl-50, .flex-offset-xl-50 { - margin-left: 50%; } - .offset-xl-55, .flex-offset-xl-55 { - margin-left: 55%; } - .offset-xl-60, .flex-offset-xl-60 { - margin-left: 60%; } - .offset-xl-65, .flex-offset-xl-65 { - margin-left: 65%; } - .offset-xl-70, .flex-offset-xl-70 { - margin-left: 70%; } - .offset-xl-75, .flex-offset-xl-75 { - margin-left: 75%; } - .offset-xl-80, .flex-offset-xl-80 { - margin-left: 80%; } - .offset-xl-85, .flex-offset-xl-85 { - margin-left: 85%; } - .offset-xl-90, .flex-offset-xl-90 { - margin-left: 90%; } - .offset-xl-95, .flex-offset-xl-95 { - margin-left: 95%; } - .offset-xl-33, .flex-offset-xl-33 { - margin-left: calc(100% / 3); } - .offset-xl-66, .flex-offset-xl-66 { - margin-left: calc(200% / 3); } - .layout-align-xl { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; } - .layout-align-xl-start, - .layout-align-xl-start-start, - .layout-align-xl-start-center, - .layout-align-xl-start-end, - .layout-align-xl-start-stretch { - -webkit-justify-content: start; - -ms-flex-pack: start; - justify-content: start; } - .layout-align-xl-center, - .layout-align-xl-center-start, - .layout-align-xl-center-center, - .layout-align-xl-center-end, - .layout-align-xl-center-stretch { - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - .layout-align-xl-end, - .layout-align-xl-end-start, - .layout-align-xl-end-center, - .layout-align-xl-end-end, - .layout-align-xl-end-stretch { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; } - .layout-align-xl-space-around, - .layout-align-xl-space-around-center, - .layout-align-xl-space-around-start, - .layout-align-xl-space-around-end, - .layout-align-xl-space-around-stretch { - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; } - .layout-align-xl-space-between, - .layout-align-xl-space-between-center, - .layout-align-xl-space-between-start, - .layout-align-xl-space-between-end, - .layout-align-xl-space-between-stretch { - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } - .layout-align-xl-start-start, - .layout-align-xl-center-start, - .layout-align-xl-end-start, - .layout-align-xl-space-between-start, - .layout-align-xl-space-around-start { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; } - .layout-align-xl-start-center, - .layout-align-xl-center-center, - .layout-align-xl-end-center, - .layout-align-xl-space-between-center, - .layout-align-xl-space-around-center { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - max-width: 100%; } - .layout-align-xl-start-center > *, - .layout-align-xl-center-center > *, - .layout-align-xl-end-center > *, - .layout-align-xl-space-between-center > *, - .layout-align-xl-space-around-center > * { - max-width: 100%; - box-sizing: border-box; } - .layout-align-xl-start-end, - .layout-align-xl-center-end, - .layout-align-xl-end-end, - .layout-align-xl-space-between-end, - .layout-align-xl-space-around-end { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - -webkit-align-content: flex-end; - -ms-flex-line-pack: end; - align-content: flex-end; } - .layout-align-xl-start-stretch, - .layout-align-xl-center-stretch, - .layout-align-xl-end-stretch, - .layout-align-xl-space-between-stretch, - .layout-align-xl-space-around-stretch { - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - -webkit-align-content: stretch; - -ms-flex-line-pack: stretch; - align-content: stretch; } - .flex-xl { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - box-sizing: border-box; } } - -@media screen\0 and (min-width: 1920px) { - .flex-xl { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; } } - -@media (min-width: 1920px) { - .flex-xl-grow { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - box-sizing: border-box; } - .flex-xl-initial { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-xl-auto { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - box-sizing: border-box; } - .flex-xl-none { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - box-sizing: border-box; } - .flex-xl-noshrink { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - box-sizing: border-box; } - .flex-xl-nogrow { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - box-sizing: border-box; } - .flex-xl-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-0, - .layout-xl-row > .flex-xl-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 0%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-0, - .layout-xl-column > .flex-xl-0 { - -webkit-flex: 1 1 0%; - -ms-flex: 1 1 0%; - flex: 1 1 0%; - max-width: 100%; - max-height: 0%; - box-sizing: border-box; } - .flex-xl-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-5, - .layout-xl-row > .flex-xl-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 5%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-5, - .layout-xl-column > .flex-xl-5 { - -webkit-flex: 1 1 5%; - -ms-flex: 1 1 5%; - flex: 1 1 5%; - max-width: 100%; - max-height: 5%; - box-sizing: border-box; } - .flex-xl-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-10, - .layout-xl-row > .flex-xl-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 10%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-10, - .layout-xl-column > .flex-xl-10 { - -webkit-flex: 1 1 10%; - -ms-flex: 1 1 10%; - flex: 1 1 10%; - max-width: 100%; - max-height: 10%; - box-sizing: border-box; } - .flex-xl-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-15, - .layout-xl-row > .flex-xl-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 15%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-15, - .layout-xl-column > .flex-xl-15 { - -webkit-flex: 1 1 15%; - -ms-flex: 1 1 15%; - flex: 1 1 15%; - max-width: 100%; - max-height: 15%; - box-sizing: border-box; } - .flex-xl-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-20, - .layout-xl-row > .flex-xl-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 20%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-20, - .layout-xl-column > .flex-xl-20 { - -webkit-flex: 1 1 20%; - -ms-flex: 1 1 20%; - flex: 1 1 20%; - max-width: 100%; - max-height: 20%; - box-sizing: border-box; } - .flex-xl-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-25, - .layout-xl-row > .flex-xl-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-25, - .layout-xl-column > .flex-xl-25 { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 100%; - max-height: 25%; - box-sizing: border-box; } - .flex-xl-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-30, - .layout-xl-row > .flex-xl-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 30%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-30, - .layout-xl-column > .flex-xl-30 { - -webkit-flex: 1 1 30%; - -ms-flex: 1 1 30%; - flex: 1 1 30%; - max-width: 100%; - max-height: 30%; - box-sizing: border-box; } - .flex-xl-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-35, - .layout-xl-row > .flex-xl-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 35%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-35, - .layout-xl-column > .flex-xl-35 { - -webkit-flex: 1 1 35%; - -ms-flex: 1 1 35%; - flex: 1 1 35%; - max-width: 100%; - max-height: 35%; - box-sizing: border-box; } - .flex-xl-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-40, - .layout-xl-row > .flex-xl-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 40%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-40, - .layout-xl-column > .flex-xl-40 { - -webkit-flex: 1 1 40%; - -ms-flex: 1 1 40%; - flex: 1 1 40%; - max-width: 100%; - max-height: 40%; - box-sizing: border-box; } - .flex-xl-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-45, - .layout-xl-row > .flex-xl-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 45%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-45, - .layout-xl-column > .flex-xl-45 { - -webkit-flex: 1 1 45%; - -ms-flex: 1 1 45%; - flex: 1 1 45%; - max-width: 100%; - max-height: 45%; - box-sizing: border-box; } - .flex-xl-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-50, - .layout-xl-row > .flex-xl-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 50%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-50, - .layout-xl-column > .flex-xl-50 { - -webkit-flex: 1 1 50%; - -ms-flex: 1 1 50%; - flex: 1 1 50%; - max-width: 100%; - max-height: 50%; - box-sizing: border-box; } - .flex-xl-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-55, - .layout-xl-row > .flex-xl-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 55%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-55, - .layout-xl-column > .flex-xl-55 { - -webkit-flex: 1 1 55%; - -ms-flex: 1 1 55%; - flex: 1 1 55%; - max-width: 100%; - max-height: 55%; - box-sizing: border-box; } - .flex-xl-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-60, - .layout-xl-row > .flex-xl-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 60%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-60, - .layout-xl-column > .flex-xl-60 { - -webkit-flex: 1 1 60%; - -ms-flex: 1 1 60%; - flex: 1 1 60%; - max-width: 100%; - max-height: 60%; - box-sizing: border-box; } - .flex-xl-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-65, - .layout-xl-row > .flex-xl-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 65%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-65, - .layout-xl-column > .flex-xl-65 { - -webkit-flex: 1 1 65%; - -ms-flex: 1 1 65%; - flex: 1 1 65%; - max-width: 100%; - max-height: 65%; - box-sizing: border-box; } - .flex-xl-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-70, - .layout-xl-row > .flex-xl-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 70%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-70, - .layout-xl-column > .flex-xl-70 { - -webkit-flex: 1 1 70%; - -ms-flex: 1 1 70%; - flex: 1 1 70%; - max-width: 100%; - max-height: 70%; - box-sizing: border-box; } - .flex-xl-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-75, - .layout-xl-row > .flex-xl-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 75%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-75, - .layout-xl-column > .flex-xl-75 { - -webkit-flex: 1 1 75%; - -ms-flex: 1 1 75%; - flex: 1 1 75%; - max-width: 100%; - max-height: 75%; - box-sizing: border-box; } - .flex-xl-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-80, - .layout-xl-row > .flex-xl-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 80%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-80, - .layout-xl-column > .flex-xl-80 { - -webkit-flex: 1 1 80%; - -ms-flex: 1 1 80%; - flex: 1 1 80%; - max-width: 100%; - max-height: 80%; - box-sizing: border-box; } - .flex-xl-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-85, - .layout-xl-row > .flex-xl-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 85%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-85, - .layout-xl-column > .flex-xl-85 { - -webkit-flex: 1 1 85%; - -ms-flex: 1 1 85%; - flex: 1 1 85%; - max-width: 100%; - max-height: 85%; - box-sizing: border-box; } - .flex-xl-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-90, - .layout-xl-row > .flex-xl-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 90%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-90, - .layout-xl-column > .flex-xl-90 { - -webkit-flex: 1 1 90%; - -ms-flex: 1 1 90%; - flex: 1 1 90%; - max-width: 100%; - max-height: 90%; - box-sizing: border-box; } - .flex-xl-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-95, - .layout-xl-row > .flex-xl-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 95%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-95, - .layout-xl-column > .flex-xl-95 { - -webkit-flex: 1 1 95%; - -ms-flex: 1 1 95%; - flex: 1 1 95%; - max-width: 100%; - max-height: 95%; - box-sizing: border-box; } - .flex-xl-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-100, - .layout-xl-row > .flex-xl-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-100, - .layout-xl-column > .flex-xl-100 { - -webkit-flex: 1 1 100%; - -ms-flex: 1 1 100%; - flex: 1 1 100%; - max-width: 100%; - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-33, .layout-row > .flex-xl-33, .layout-xl-row > .flex-xl-33, .layout-xl-row > .flex-xl-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: calc(100% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-row > .flex-xl-66, .layout-row > .flex-xl-66, .layout-xl-row > .flex-xl-66, .layout-xl-row > .flex-xl-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: calc(200% / 3); - max-height: 100%; - box-sizing: border-box; } - .layout-column > .flex-xl-33, .layout-column > .flex-xl-33, .layout-xl-column > .flex-xl-33, .layout-xl-column > .flex-xl-33 { - -webkit-flex: 1 1 33%; - -ms-flex: 1 1 33%; - flex: 1 1 33%; - max-width: 100%; - max-height: calc(100% / 3); - box-sizing: border-box; } - .layout-column > .flex-xl-66, .layout-column > .flex-xl-66, .layout-xl-column > .flex-xl-66, .layout-xl-column > .flex-xl-66 { - -webkit-flex: 1 1 66%; - -ms-flex: 1 1 66%; - flex: 1 1 66%; - max-width: 100%; - max-height: calc(200% / 3); - box-sizing: border-box; } - .layout-xl, .layout-xl-column, .layout-xl-row { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - .layout-xl-column { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - .layout-xl-row { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - .hide:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-gt-lg):not(.show-xl):not(.show), .hide-gt-xs:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-gt-lg):not(.show-xl):not(.show), .hide-gt-sm:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-gt-lg):not(.show-xl):not(.show), .hide-gt-md:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-gt-lg):not(.show-xl):not(.show), .hide-gt-lg:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-gt-lg):not(.show-xl):not(.show) { - display: none; } - .hide-xl:not(.show-xl):not(.show-gt-lg):not(.show-gt-md):not(.show-gt-sm):not(.show-gt-xs):not(.show) { - display: none; } } - -@-webkit-keyframes md-autocomplete-list-out { - 0% { - -webkit-animation-timing-function: linear; - animation-timing-function: linear; } - 50% { - opacity: 0; - height: 40px; - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; } - 100% { - height: 0; - opacity: 0; } } - -@keyframes md-autocomplete-list-out { - 0% { - -webkit-animation-timing-function: linear; - animation-timing-function: linear; } - 50% { - opacity: 0; - height: 40px; - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; } - 100% { - height: 0; - opacity: 0; } } - -@-webkit-keyframes md-autocomplete-list-in { - 0% { - opacity: 0; - height: 0; - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; } - 50% { - opacity: 0; - height: 40px; } - 100% { - opacity: 1; - height: 40px; } } - -@keyframes md-autocomplete-list-in { - 0% { - opacity: 0; - height: 0; - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; } - 50% { - opacity: 0; - height: 40px; } - 100% { - opacity: 1; - height: 40px; } } - -md-autocomplete { - border-radius: 2px; - display: block; - height: 40px; - position: relative; - overflow: visible; - min-width: 190px; } - md-autocomplete[disabled] input { - cursor: default; } - md-autocomplete[md-floating-label] { - border-radius: 0; - background: transparent; - height: auto; } - md-autocomplete[md-floating-label] md-input-container { - padding-bottom: 26px; } - md-autocomplete[md-floating-label] md-input-container.md-input-has-messages { - padding-bottom: 2px; } - md-autocomplete[md-floating-label] md-autocomplete-wrap { - height: auto; } - md-autocomplete[md-floating-label] button { - position: absolute; - top: auto; - bottom: 0; - right: 0; - width: 30px; - height: 30px; } - md-autocomplete md-autocomplete-wrap { - display: block; - position: relative; - overflow: visible; - height: 40px; } - md-autocomplete md-autocomplete-wrap.md-menu-showing { - z-index: 51; } - md-autocomplete md-autocomplete-wrap md-progress-linear { - position: absolute; - bottom: -2px; - left: 0; } - md-autocomplete md-autocomplete-wrap md-progress-linear.md-inline { - bottom: 40px; - right: 2px; - left: 2px; - width: auto; } - md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 3px; - transition: none; } - md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate .md-container { - transition: none; - height: 3px; } - md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate.ng-enter { - transition: opacity 0.15s linear; } - md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate.ng-enter.ng-enter-active { - opacity: 1; } - md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate.ng-leave { - transition: opacity 0.15s linear; } - md-autocomplete md-autocomplete-wrap md-progress-linear .md-mode-indeterminate.ng-leave.ng-leave-active { - opacity: 0; } - md-autocomplete input:not(.md-input) { - font-size: 14px; - box-sizing: border-box; - border: none; - box-shadow: none; - outline: none; - background: transparent; - width: 100%; - padding: 0 15px; - line-height: 40px; - height: 40px; } - md-autocomplete input:not(.md-input)::-ms-clear { - display: none; } - md-autocomplete button { - position: relative; - line-height: 20px; - text-align: center; - width: 30px; - height: 30px; - cursor: pointer; - border: none; - border-radius: 50%; - padding: 0; - font-size: 12px; - background: transparent; - margin: auto 5px; } - md-autocomplete button:after { - content: ''; - position: absolute; - top: -6px; - right: -6px; - bottom: -6px; - left: -6px; - border-radius: 50%; - -webkit-transform: scale(0); - transform: scale(0); - opacity: 0; - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); } - md-autocomplete button:focus { - outline: none; } - md-autocomplete button:focus:after { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 1; } - md-autocomplete button md-icon { - position: absolute; - top: 50%; - left: 50%; - -webkit-transform: translate3d(-50%, -50%, 0) scale(0.9); - transform: translate3d(-50%, -50%, 0) scale(0.9); } - md-autocomplete button md-icon path { - stroke-width: 0; } - md-autocomplete button.ng-enter { - -webkit-transform: scale(0); - transform: scale(0); - transition: -webkit-transform 0.15s ease-out; - transition: transform 0.15s ease-out; } - md-autocomplete button.ng-enter.ng-enter-active { - -webkit-transform: scale(1); - transform: scale(1); } - md-autocomplete button.ng-leave { - transition: -webkit-transform 0.15s ease-out; - transition: transform 0.15s ease-out; } - md-autocomplete button.ng-leave.ng-leave-active { - -webkit-transform: scale(0); - transform: scale(0); } - @media screen and (-ms-high-contrast: active) { - md-autocomplete input { - border: 1px solid #fff; } - md-autocomplete li:focus { - color: #fff; } } - -.md-virtual-repeat-container.md-autocomplete-suggestions-container { - position: absolute; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); - height: 225.5px; - max-height: 225.5px; - z-index: 100; } - -.md-virtual-repeat-container.md-not-found { - height: 48px; } - -.md-autocomplete-suggestions { - margin: 0; - list-style: none; - padding: 0; } - .md-autocomplete-suggestions li { - font-size: 14px; - overflow: hidden; - padding: 0 15px; - line-height: 48px; - height: 48px; - transition: background 0.15s linear; - margin: 0; - white-space: nowrap; - text-overflow: ellipsis; } - .md-autocomplete-suggestions li:focus { - outline: none; } - .md-autocomplete-suggestions li:not(.md-not-found-wrapper) { - cursor: pointer; } - -@media screen and (-ms-high-contrast: active) { - md-autocomplete, - .md-autocomplete-suggestions { - border: 1px solid #fff; } } - -md-backdrop { - transition: opacity 450ms; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: 50; } - md-backdrop.md-menu-backdrop { - position: fixed !important; - z-index: 99; } - md-backdrop.md-select-backdrop { - z-index: 81; - transition-duration: 0; } - md-backdrop.md-dialog-backdrop { - z-index: 79; } - md-backdrop.md-bottom-sheet-backdrop { - z-index: 69; } - md-backdrop.md-sidenav-backdrop { - z-index: 59; } - md-backdrop.md-click-catcher { - position: absolute; } - md-backdrop.md-opaque { - opacity: .48; } - md-backdrop.md-opaque.ng-enter { - opacity: 0; } - md-backdrop.md-opaque.ng-enter.md-opaque.ng-enter-active { - opacity: .48; } - md-backdrop.md-opaque.ng-leave { - opacity: .48; - transition: opacity 400ms; } - md-backdrop.md-opaque.ng-leave.md-opaque.ng-leave-active { - opacity: 0; } - -md-bottom-sheet { - position: absolute; - left: 0; - right: 0; - bottom: 0; - padding: 8px 16px 88px 16px; - z-index: 70; - border-top-width: 1px; - border-top-style: solid; - -webkit-transform: translate3d(0, 80px, 0); - transform: translate3d(0, 80px, 0); - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - transition-property: -webkit-transform; - transition-property: transform; } - md-bottom-sheet.md-has-header { - padding-top: 0; } - md-bottom-sheet.ng-enter { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); } - md-bottom-sheet.ng-enter-active { - opacity: 1; - display: block; - -webkit-transform: translate3d(0, 80px, 0) !important; - transform: translate3d(0, 80px, 0) !important; } - md-bottom-sheet.ng-leave-active { - -webkit-transform: translate3d(0, 100%, 0) !important; - transform: translate3d(0, 100%, 0) !important; - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } - md-bottom-sheet .md-subheader { - background-color: transparent; - font-family: Roboto, "Helvetica Neue", sans-serif; - line-height: 56px; - padding: 0; - white-space: nowrap; } - md-bottom-sheet md-inline-icon { - display: inline-block; - height: 24px; - width: 24px; - fill: #444; } - md-bottom-sheet md-list-item { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - outline: none; } - md-bottom-sheet md-list-item:hover { - cursor: pointer; } - md-bottom-sheet.md-list md-list-item { - padding: 0; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - height: 48px; } - md-bottom-sheet.md-list md-list-item div.md-icon-container { - display: inline-block; - height: 24px; - margin-right: 32px; } - md-bottom-sheet.md-grid { - padding-left: 24px; - padding-right: 24px; - padding-top: 0; } - md-bottom-sheet.md-grid md-list { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - transition: all 0.5s; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; } - md-bottom-sheet.md-grid md-list-item { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - transition: all 0.5s; - height: 96px; - margin-top: 8px; - margin-bottom: 8px; - /* Mixin for how many grid items to show per row */ } - @media screen and (max-width: 960px) { - md-bottom-sheet.md-grid md-list-item { - -webkit-flex: 1 1 33.33333%; - -ms-flex: 1 1 33.33333%; - flex: 1 1 33.33333%; - max-width: 33.33333%; } - md-bottom-sheet.md-grid md-list-item:nth-of-type(3n + 1) { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; } - md-bottom-sheet.md-grid md-list-item:nth-of-type(3n) { - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; } } - @media screen and (min-width: 960px) and (max-width: 1279px) { - md-bottom-sheet.md-grid md-list-item { - -webkit-flex: 1 1 25%; - -ms-flex: 1 1 25%; - flex: 1 1 25%; - max-width: 25%; } } - @media screen and (min-width: 1280px) and (max-width: 1919px) { - md-bottom-sheet.md-grid md-list-item { - -webkit-flex: 1 1 16.66667%; - -ms-flex: 1 1 16.66667%; - flex: 1 1 16.66667%; - max-width: 16.66667%; } } - @media screen and (min-width: 1920px) { - md-bottom-sheet.md-grid md-list-item { - -webkit-flex: 1 1 14.28571%; - -ms-flex: 1 1 14.28571%; - flex: 1 1 14.28571%; - max-width: 14.28571%; } } - md-bottom-sheet.md-grid md-list-item .md-list-item-content { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - width: 48px; - padding-bottom: 16px; } - md-bottom-sheet.md-grid md-list-item .md-grid-item-content { - border: 1px solid transparent; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - width: 80px; } - md-bottom-sheet.md-grid md-list-item .md-icon-container { - display: inline-block; - box-sizing: border-box; - height: 48px; - width: 48px; - margin: 0 0; } - md-bottom-sheet.md-grid md-list-item .md-grid-text { - font-weight: 400; - line-height: 16px; - font-size: 13px; - margin: 0; - white-space: nowrap; - width: 64px; - text-align: center; - text-transform: none; - padding-top: 8px; } - -@media screen and (-ms-high-contrast: active) { - md-bottom-sheet { - border: 1px solid #fff; } } - -button.md-button::-moz-focus-inner { - border: 0; } - -.md-button { - border-radius: 3px; - box-sizing: border-box; - color: currentColor; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: relative; - outline: none; - border: 0; - display: inline-block; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - padding: 0 6px; - margin: 6px 8px; - line-height: 36px; - min-height: 36px; - background: transparent; - white-space: nowrap; - min-width: 88px; - text-align: center; - text-transform: uppercase; - font-weight: 500; - font-size: 14px; - font-style: inherit; - font-variant: inherit; - font-family: inherit; - text-decoration: none; - cursor: pointer; - overflow: hidden; - transition: box-shadow 0.4s cubic-bezier(0.25, 0.8, 0.25, 1), background-color 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); } - .md-button:focus { - outline: none; } - .md-button:hover, .md-button:focus { - text-decoration: none; } - .md-button.ng-hide, .md-button.ng-leave { - transition: none; } - .md-button.md-cornered { - border-radius: 0; } - .md-button.md-icon { - padding: 0; - background: none; } - .md-button.md-raised:not([disabled]) { - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); } - .md-button.md-icon-button { - margin: 0 6px; - height: 40px; - min-width: 0; - line-height: 24px; - padding: 8px; - width: 40px; - border-radius: 50%; } - .md-button.md-icon-button .md-ripple-container { - border-radius: 50%; - background-clip: padding-box; - overflow: hidden; - -webkit-mask-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC"); } - .md-button.md-fab { - z-index: 20; - line-height: 56px; - min-width: 0; - width: 56px; - height: 56px; - vertical-align: middle; - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); - border-radius: 50%; - background-clip: padding-box; - overflow: hidden; - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - transition-property: background-color, box-shadow, -webkit-transform; - transition-property: background-color, box-shadow, transform; } - .md-button.md-fab.md-fab-bottom-right { - top: auto; - right: 20px; - bottom: 20px; - left: auto; - position: absolute; } - .md-button.md-fab.md-fab-bottom-left { - top: auto; - right: auto; - bottom: 20px; - left: 20px; - position: absolute; } - .md-button.md-fab.md-fab-top-right { - top: 20px; - right: 20px; - bottom: auto; - left: auto; - position: absolute; } - .md-button.md-fab.md-fab-top-left { - top: 20px; - right: auto; - bottom: auto; - left: 20px; - position: absolute; } - .md-button.md-fab .md-ripple-container { - border-radius: 50%; - background-clip: padding-box; - overflow: hidden; - -webkit-mask-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC"); } - .md-button.md-fab.md-mini { - line-height: 40px; - width: 40px; - height: 40px; } - .md-button.md-fab.ng-hide, .md-button.md-fab.ng-leave { - transition: none; } - .md-button:not([disabled]).md-raised.md-focused, .md-button:not([disabled]).md-fab.md-focused { - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); } - .md-button:not([disabled]).md-raised:active, .md-button:not([disabled]).md-fab:active { - box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4); } - .md-button .md-ripple-container { - border-radius: 3px; - background-clip: padding-box; - overflow: hidden; - -webkit-mask-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC"); } - -.md-toast-open-top .md-button.md-fab-top-left, -.md-toast-open-top .md-button.md-fab-top-right { - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - -webkit-transform: translate3d(0, 42px, 0); - transform: translate3d(0, 42px, 0); } - .md-toast-open-top .md-button.md-fab-top-left:not([disabled]).md-focused, .md-toast-open-top .md-button.md-fab-top-left:not([disabled]):hover, - .md-toast-open-top .md-button.md-fab-top-right:not([disabled]).md-focused, - .md-toast-open-top .md-button.md-fab-top-right:not([disabled]):hover { - -webkit-transform: translate3d(0, 41px, 0); - transform: translate3d(0, 41px, 0); } - -.md-toast-open-bottom .md-button.md-fab-bottom-left, -.md-toast-open-bottom .md-button.md-fab-bottom-right { - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - -webkit-transform: translate3d(0, -42px, 0); - transform: translate3d(0, -42px, 0); } - .md-toast-open-bottom .md-button.md-fab-bottom-left:not([disabled]).md-focused, .md-toast-open-bottom .md-button.md-fab-bottom-left:not([disabled]):hover, - .md-toast-open-bottom .md-button.md-fab-bottom-right:not([disabled]).md-focused, - .md-toast-open-bottom .md-button.md-fab-bottom-right:not([disabled]):hover { - -webkit-transform: translate3d(0, -43px, 0); - transform: translate3d(0, -43px, 0); } - -.md-button-group { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - width: 100%; } - -.md-button-group > .md-button { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - display: block; - overflow: hidden; - width: 0; - border-width: 1px 0px 1px 1px; - border-radius: 0; - text-align: center; - text-overflow: ellipsis; - white-space: nowrap; } - .md-button-group > .md-button:first-child { - border-radius: 2px 0px 0px 2px; } - .md-button-group > .md-button:last-child { - border-right-width: 1px; - border-radius: 0px 2px 2px 0px; } - -@media screen and (-ms-high-contrast: active) { - .md-button.md-raised, - .md-button.md-fab { - border: 1px solid #fff; } } - -md-card { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - margin: 8px; - box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); } - md-card md-card-header { - padding: 16px; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - md-card md-card-header:first-child md-card-avatar { - margin-right: 12px; } - md-card md-card-header:last-child md-card-avatar { - margin-left: 12px; } - md-card md-card-header md-card-avatar { - width: 40px; - height: 40px; } - md-card md-card-header md-card-avatar .md-user-avatar, - md-card md-card-header md-card-avatar md-icon { - border-radius: 50%; } - md-card md-card-header md-card-avatar md-icon { - padding: 8px; } - md-card md-card-header md-card-avatar + md-card-header-text { - max-height: 40px; } - md-card md-card-header md-card-avatar + md-card-header-text .md-title { - font-size: 14px; } - md-card md-card-header md-card-header-text { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - md-card md-card-header md-card-header-text .md-subhead { - font-size: 14px; } - md-card > img, - md-card > :not(md-card-content) img { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - width: 100%; - height: auto; } - md-card md-card-title { - padding: 24px 16px 16px; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - md-card md-card-title + md-card-content { - padding-top: 0; } - md-card md-card-title md-card-title-text { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - md-card md-card-title md-card-title-text .md-subhead { - padding-top: 0; - font-size: 14px; } - md-card md-card-title md-card-title-text:only-child .md-subhead { - padding-top: 12px; } - md-card md-card-title md-card-title-media { - margin-top: -8px; } - md-card md-card-title md-card-title-media .md-media-sm { - height: 80px; - width: 80px; } - md-card md-card-title md-card-title-media .md-media-md { - height: 112px; - width: 112px; } - md-card md-card-title md-card-title-media .md-media-lg { - height: 152px; - width: 152px; } - md-card md-card-content { - display: block; - padding: 16px; } - md-card md-card-content > p:first-child { - margin-top: 0; } - md-card md-card-content > p:last-child { - margin-bottom: 0; } - md-card md-card-content .md-media-xl { - height: 240px; - width: 240px; } - md-card .md-actions, md-card md-card-actions { - margin: 8px; } - md-card .md-actions.layout-column .md-button:not(.md-icon-button), md-card md-card-actions.layout-column .md-button:not(.md-icon-button) { - margin: 2px 0; } - md-card .md-actions.layout-column .md-button:not(.md-icon-button):first-of-type, md-card md-card-actions.layout-column .md-button:not(.md-icon-button):first-of-type { - margin-top: 0; } - md-card .md-actions.layout-column .md-button:not(.md-icon-button):last-of-type, md-card md-card-actions.layout-column .md-button:not(.md-icon-button):last-of-type { - margin-bottom: 0; } - md-card .md-actions.layout-column .md-button.md-icon-button, md-card md-card-actions.layout-column .md-button.md-icon-button { - margin-top: 6px; - margin-bottom: 6px; } - md-card .md-actions md-card-icon-actions, md-card md-card-actions md-card-icon-actions { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - -webkit-justify-content: flex-start; - -ms-flex-pack: start; - justify-content: flex-start; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - md-card .md-actions:not(.layout-column) .md-button:not(.md-icon-button), md-card md-card-actions:not(.layout-column) .md-button:not(.md-icon-button) { - margin: 0 4px; } - md-card .md-actions:not(.layout-column) .md-button:not(.md-icon-button):first-of-type, md-card md-card-actions:not(.layout-column) .md-button:not(.md-icon-button):first-of-type { - margin-left: 0; } - md-card .md-actions:not(.layout-column) .md-button:not(.md-icon-button):last-of-type, md-card md-card-actions:not(.layout-column) .md-button:not(.md-icon-button):last-of-type { - margin-right: 0; } - md-card .md-actions:not(.layout-column) .md-button.md-icon-button, md-card md-card-actions:not(.layout-column) .md-button.md-icon-button { - margin-left: 6px; - margin-right: 6px; } - md-card .md-actions:not(.layout-column) .md-button.md-icon-button:first-of-type, md-card md-card-actions:not(.layout-column) .md-button.md-icon-button:first-of-type { - margin-left: 12px; } - md-card .md-actions:not(.layout-column) .md-button.md-icon-button:last-of-type, md-card md-card-actions:not(.layout-column) .md-button.md-icon-button:last-of-type { - margin-right: 12px; } - md-card .md-actions:not(.layout-column) .md-button + md-card-icon-actions, md-card md-card-actions:not(.layout-column) .md-button + md-card-icon-actions { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - md-card md-card-footer { - margin-top: auto; - padding: 16px; } - -@media screen and (-ms-high-contrast: active) { - md-card { - border: 1px solid #fff; } } - -.md-inline-form md-checkbox { - margin: 19px 0 18px; } - -md-checkbox { - box-sizing: border-box; - display: inline-block; - margin-bottom: 16px; - white-space: nowrap; - cursor: pointer; - outline: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - position: relative; - min-width: 20px; - min-height: 20px; - margin-left: inherit; - margin-right: 16px; } - html[dir=rtl] md-checkbox { - margin-left: 16px; - unicode-bidi: embed; } - body[dir=rtl] md-checkbox { - margin-left: 16px; - unicode-bidi: embed; } - md-checkbox bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-checkbox bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-checkbox { - margin-right: inherit; - unicode-bidi: embed; } - body[dir=rtl] md-checkbox { - margin-right: inherit; - unicode-bidi: embed; } - md-checkbox bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-checkbox bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-checkbox:last-of-type { - margin-left: inherit; - margin-right: 0; } - html[dir=rtl] md-checkbox:last-of-type { - margin-left: 0; - unicode-bidi: embed; } - body[dir=rtl] md-checkbox:last-of-type { - margin-left: 0; - unicode-bidi: embed; } - md-checkbox:last-of-type bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-checkbox:last-of-type bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-checkbox:last-of-type { - margin-right: inherit; - unicode-bidi: embed; } - body[dir=rtl] md-checkbox:last-of-type { - margin-right: inherit; - unicode-bidi: embed; } - md-checkbox:last-of-type bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-checkbox:last-of-type bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-checkbox.md-focused:not([disabled]) .md-container:before { - left: -8px; - top: -8px; - right: -8px; - bottom: -8px; } - md-checkbox.md-focused:not([disabled]):not(.md-checked) .md-container:before { - background-color: rgba(0, 0, 0, 0.12); } - md-checkbox .md-container { - position: absolute; - top: 50%; - -webkit-transform: translateY(-50%); - transform: translateY(-50%); - box-sizing: border-box; - display: inline-block; - width: 20px; - height: 20px; - left: 0; - right: auto; } - html[dir=rtl] md-checkbox .md-container { - left: auto; - unicode-bidi: embed; } - body[dir=rtl] md-checkbox .md-container { - left: auto; - unicode-bidi: embed; } - md-checkbox .md-container bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-checkbox .md-container bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-checkbox .md-container { - right: 0; - unicode-bidi: embed; } - body[dir=rtl] md-checkbox .md-container { - right: 0; - unicode-bidi: embed; } - md-checkbox .md-container bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-checkbox .md-container bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-checkbox .md-container:before { - box-sizing: border-box; - background-color: transparent; - border-radius: 50%; - content: ''; - position: absolute; - display: block; - height: auto; - left: 0; - top: 0; - right: 0; - bottom: 0; - transition: all 0.5s; - width: auto; } - md-checkbox .md-container:after { - box-sizing: border-box; - content: ''; - position: absolute; - top: -10px; - right: -10px; - bottom: -10px; - left: -10px; } - md-checkbox .md-container .md-ripple-container { - position: absolute; - display: block; - width: auto; - height: auto; - left: -15px; - top: -15px; - right: -15px; - bottom: -15px; } - md-checkbox.md-align-top-left > div.md-container { - top: 12px; } - md-checkbox .md-icon { - box-sizing: border-box; - transition: 240ms; - position: absolute; - top: 0; - left: 0; - width: 20px; - height: 20px; - border-width: 2px; - border-style: solid; - border-radius: 2px; } - md-checkbox.md-checked .md-icon { - border: none; } - md-checkbox[disabled] { - cursor: default; } - md-checkbox.md-checked .md-icon:after { - box-sizing: border-box; - -webkit-transform: rotate(45deg); - transform: rotate(45deg); - position: absolute; - left: 6.66667px; - top: 2.22222px; - display: table; - width: 6.66667px; - height: 13.33333px; - border-width: 2px; - border-style: solid; - border-top: 0; - border-left: 0; - content: ''; } - md-checkbox .md-label { - box-sizing: border-box; - position: relative; - display: inline-block; - vertical-align: middle; - white-space: normal; - -webkit-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - margin-left: 30px; - margin-right: 0; } - html[dir=rtl] md-checkbox .md-label { - margin-left: 0; - unicode-bidi: embed; } - body[dir=rtl] md-checkbox .md-label { - margin-left: 0; - unicode-bidi: embed; } - md-checkbox .md-label bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-checkbox .md-label bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-checkbox .md-label { - margin-right: 30px; - unicode-bidi: embed; } - body[dir=rtl] md-checkbox .md-label { - margin-right: 30px; - unicode-bidi: embed; } - md-checkbox .md-label bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-checkbox .md-label bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - -.md-contact-chips .md-chips .md-chip { - padding: 0 25px 0 0; } - .md-contact-chips .md-chips .md-chip .md-contact-avatar { - float: left; } - .md-contact-chips .md-chips .md-chip .md-contact-avatar img { - height: 32px; - border-radius: 16px; } - .md-contact-chips .md-chips .md-chip .md-contact-name { - display: inline-block; - height: 32px; - margin-left: 8px; } - -.md-contact-suggestion { - height: 56px; } - .md-contact-suggestion img { - height: 40px; - border-radius: 20px; - margin-top: 8px; } - .md-contact-suggestion .md-contact-name { - margin-left: 8px; - width: 120px; } - .md-contact-suggestion .md-contact-name, .md-contact-suggestion .md-contact-email { - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; } - -.md-contact-chips-suggestions li { - height: 100%; } - -.md-chips { - display: block; - font-family: Roboto, "Helvetica Neue", sans-serif; - font-size: 16px; - padding: 0 0 8px 3px; - vertical-align: middle; } - .md-chips:after { - content: ''; - display: table; - clear: both; } - .md-chips:not(.md-readonly) { - cursor: text; } - .md-chips:not(.md-readonly) .md-chip:not(.md-readonly) { - padding-right: 22px; } - .md-chips:not(.md-readonly) .md-chip:not(.md-readonly) .md-chip-content { - padding-right: 4px; } - .md-chips .md-chip { - cursor: default; - border-radius: 16px; - display: block; - height: 32px; - line-height: 32px; - margin: 8px 8px 0 0; - padding: 0 12px 0 12px; - float: left; - box-sizing: border-box; - max-width: 100%; - position: relative; } - .md-chips .md-chip .md-chip-content { - display: block; - float: left; - white-space: nowrap; - max-width: 100%; - overflow: hidden; - text-overflow: ellipsis; } - .md-chips .md-chip .md-chip-content:focus { - outline: none; } - .md-chips .md-chip .md-chip-remove-container { - position: absolute; - right: 0; - line-height: 22px; } - .md-chips .md-chip .md-chip-remove { - text-align: center; - width: 32px; - height: 32px; - min-width: 0; - padding: 0; - background: transparent; - border: none; - box-shadow: none; - margin: 0; - position: relative; } - .md-chips .md-chip .md-chip-remove md-icon { - height: 18px; - width: 18px; - position: absolute; - top: 50%; - left: 50%; - -webkit-transform: translate3d(-50%, -50%, 0); - transform: translate3d(-50%, -50%, 0); } - .md-chips .md-chip-input-container { - display: block; - line-height: 32px; - margin: 8px 8px 0 0; - padding: 0; - float: left; } - .md-chips .md-chip-input-container input:not([type]), .md-chips .md-chip-input-container input[type="email"], .md-chips .md-chip-input-container input[type="number"], .md-chips .md-chip-input-container input[type="tel"], .md-chips .md-chip-input-container input[type="url"], .md-chips .md-chip-input-container input[type="text"] { - border: 0; - height: 32px; - line-height: 32px; - padding: 0; } - .md-chips .md-chip-input-container input:not([type]):focus, .md-chips .md-chip-input-container input[type="email"]:focus, .md-chips .md-chip-input-container input[type="number"]:focus, .md-chips .md-chip-input-container input[type="tel"]:focus, .md-chips .md-chip-input-container input[type="url"]:focus, .md-chips .md-chip-input-container input[type="text"]:focus { - outline: none; } - .md-chips .md-chip-input-container md-autocomplete, .md-chips .md-chip-input-container md-autocomplete-wrap { - background: transparent; - height: 32px; } - .md-chips .md-chip-input-container md-autocomplete md-autocomplete-wrap { - box-shadow: none; } - .md-chips .md-chip-input-container md-autocomplete input { - position: relative; } - .md-chips .md-chip-input-container input { - border: 0; - height: 32px; - line-height: 32px; - padding: 0; } - .md-chips .md-chip-input-container input:focus { - outline: none; } - .md-chips .md-chip-input-container md-autocomplete, .md-chips .md-chip-input-container md-autocomplete-wrap { - height: 32px; } - .md-chips .md-chip-input-container md-autocomplete { - box-shadow: none; } - .md-chips .md-chip-input-container md-autocomplete input { - position: relative; } - .md-chips .md-chip-input-container:not(:first-child) { - margin: 8px 8px 0 0; } - .md-chips .md-chip-input-container input { - background: transparent; - border-width: 0; } - .md-chips md-autocomplete button { - display: none; } - -@media screen and (-ms-high-contrast: active) { - .md-chip-input-container, - md-chip { - border: 1px solid #fff; } - .md-chip-input-container md-autocomplete { - border: none; } } - -md-content { - display: block; - position: relative; - overflow: auto; - -webkit-overflow-scrolling: touch; } - md-content[md-scroll-y] { - overflow-y: auto; - overflow-x: hidden; } - md-content[md-scroll-x] { - overflow-x: auto; - overflow-y: hidden; } - md-content.autoScroll { - -webkit-overflow-scrolling: auto; } - -/** Styles for mdCalendar. */ -md-calendar { - font-size: 13px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; } - -.md-calendar-scroll-mask { - display: inline-block; - overflow: hidden; - height: 308px; } - .md-calendar-scroll-mask .md-virtual-repeat-scroller { - overflow-y: scroll; - -webkit-overflow-scrolling: touch; } - .md-calendar-scroll-mask .md-virtual-repeat-scroller::-webkit-scrollbar { - display: none; } - .md-calendar-scroll-mask .md-virtual-repeat-offsetter { - width: 100%; } - -.md-calendar-scroll-container { - box-shadow: inset -3px 3px 6px rgba(0, 0, 0, 0.2); - display: inline-block; - height: 308px; - width: 346px; } - -.md-calendar-date { - height: 44px; - width: 44px; - text-align: center; - padding: 0; - border: none; } - .md-calendar-date:first-child { - padding-left: 16px; } - .md-calendar-date:last-child { - padding-right: 16px; } - .md-calendar-date.md-calendar-date-disabled { - cursor: default; } - -.md-calendar-date-selection-indicator { - transition: background-color, color 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - border-radius: 50%; - display: inline-block; - width: 40px; - height: 40px; - line-height: 40px; } - .md-calendar-date:not(.md-disabled) .md-calendar-date-selection-indicator { - cursor: pointer; } - -.md-calendar-month-label { - height: 44px; - font-size: 14px; - font-weight: 500; - padding: 0 0 0 24px; } - -.md-calendar-day-header { - table-layout: fixed; - border-spacing: 0; - border-collapse: collapse; } - .md-calendar-day-header th { - height: 44px; - width: 44px; - text-align: center; - padding: 0; - border: none; - font-weight: normal; - height: 40px; } - .md-calendar-day-header th:first-child { - padding-left: 16px; } - .md-calendar-day-header th:last-child { - padding-right: 16px; } - -.md-calendar { - table-layout: fixed; - border-spacing: 0; - border-collapse: collapse; } - .md-calendar tr:last-child td { - border-bottom-width: 1px; - border-bottom-style: solid; } - .md-calendar:first-child { - border-top: 1px solid transparent; } - -/** Styles for mdDatepicker. */ -md-datepicker { - white-space: nowrap; - overflow: hidden; - padding-right: 18px; - margin-right: -18px; - vertical-align: middle; } - -.md-inline-form md-datepicker { - margin-top: 12px; } - -.md-datepicker-button { - display: inline-block; - box-sizing: border-box; - background: none; } - -.md-datepicker-input { - font-size: 14px; - box-sizing: border-box; - border: none; - box-shadow: none; - outline: none; - background: transparent; - min-width: 120px; - max-width: 328px; } - .md-datepicker-input::-ms-clear { - display: none; } - -.md-datepicker-input-container { - position: relative; - padding-bottom: 5px; - border-bottom-width: 1px; - border-bottom-style: solid; - display: inline-block; - width: auto; - margin-left: 12px; } - .md-datepicker-input-container.md-datepicker-focused { - border-bottom-width: 2px; } - -.md-datepicker-calendar-pane { - position: absolute; - top: 0; - left: 0; - z-index: 100; - border-width: 1px; - border-style: solid; - background: transparent; - -webkit-transform: scale(0); - transform: scale(0); - -webkit-transform-origin: 0 0; - transform-origin: 0 0; - transition: -webkit-transform 0.2s cubic-bezier(0.25, 0.8, 0.25, 1); - transition: transform 0.2s cubic-bezier(0.25, 0.8, 0.25, 1); } - .md-datepicker-calendar-pane.md-pane-open { - -webkit-transform: scale(1); - transform: scale(1); } - -.md-datepicker-input-mask { - height: 40px; - width: 340px; - position: relative; - background: transparent; - pointer-events: none; - cursor: text; } - -.md-datepicker-input-mask-opaque { - position: absolute; - right: 0; - left: 120px; - height: 100%; } - -.md-datepicker-calendar { - opacity: 0; - transition: opacity 0.2s cubic-bezier(0.5, 0, 0.25, 1); } - .md-pane-open .md-datepicker-calendar { - opacity: 1; } - .md-datepicker-calendar md-calendar:focus { - outline: none; } - -.md-datepicker-expand-triangle { - position: absolute; - top: 50%; - left: 50%; - -webkit-transform: translate(-50%, -50%); - transform: translate(-50%, -50%); - width: 0; - height: 0; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-top: 5px solid; } - -.md-datepicker-triangle-button { - position: absolute; - right: 0; - top: 0; - -webkit-transform: translateY(-25%) translateX(45%); - transform: translateY(-25%) translateX(45%); } - -.md-datepicker-triangle-button.md-button.md-icon-button { - height: 100%; - width: 36px; - position: absolute; } - -md-datepicker[disabled] .md-datepicker-input-container { - border-bottom-color: transparent; } - -md-datepicker[disabled] .md-datepicker-triangle-button { - display: none; } - -.md-datepicker-open .md-datepicker-input-container { - margin-left: -12px; - border: none; } - -.md-datepicker-open .md-datepicker-input { - margin-left: 24px; - height: 40px; } - -.md-datepicker-open .md-datepicker-triangle-button { - display: none; } - -.md-datepicker-pos-adjusted .md-datepicker-input-mask { - display: none; } - -.md-datepicker-calendar-pane .md-calendar { - -webkit-transform: translateY(-85px); - transform: translateY(-85px); - transition: -webkit-transform 0.65s cubic-bezier(0.25, 0.8, 0.25, 1); - transition: transform 0.65s cubic-bezier(0.25, 0.8, 0.25, 1); - transition-delay: 0.125s; } - -.md-datepicker-calendar-pane.md-pane-open .md-calendar { - -webkit-transform: translateY(0); - transform: translateY(0); } - -.md-dialog-is-showing { - max-height: 100%; } - -.md-dialog-container { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 80; - overflow: hidden; } - -md-dialog { - opacity: 0; - min-width: 240px; - max-width: 80%; - max-height: 80%; - position: relative; - overflow: auto; - box-shadow: 0px 7px 8px -4px rgba(0, 0, 0, 0.2), 0px 13px 19px 2px rgba(0, 0, 0, 0.14), 0px 5px 24px 4px rgba(0, 0, 0, 0.12); - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - md-dialog.md-transition-in { - opacity: 1; - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - -webkit-transform: translate3d(0, 0, 0) scale(1); - transform: translate3d(0, 0, 0) scale(1); } - md-dialog.md-transition-out { - opacity: 0; - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - -webkit-transform: translate3d(0, 100%, 0) scale(0.2); - transform: translate3d(0, 100%, 0) scale(0.2); } - md-dialog > form { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - overflow: auto; } - md-dialog .md-dialog-content { - padding: 24px; } - md-dialog md-dialog-content { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - overflow: auto; - -webkit-overflow-scrolling: touch; } - md-dialog md-dialog-content:not([layout=row]) > *:first-child:not(.md-subheader) { - margin-top: 0; } - md-dialog md-dialog-content:focus { - outline: none; } - md-dialog md-dialog-content .md-subheader { - margin: 0; } - md-dialog md-dialog-content .md-subheader.sticky-clone { - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16); } - md-dialog md-dialog-content.sticky-container { - padding: 0; } - md-dialog md-dialog-content.sticky-container > div { - padding: 24px; - padding-top: 0; } - md-dialog md-dialog-content .md-dialog-content-body { - width: 100%; } - md-dialog .md-actions, md-dialog md-dialog-actions { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; - box-sizing: border-box; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; - margin-bottom: 0; - padding-right: 8px; - padding-left: 16px; - min-height: 52px; - overflow: hidden; } - md-dialog .md-actions .md-button, md-dialog md-dialog-actions .md-button { - margin-bottom: 8px; - margin-left: 8px; - margin-right: 0; - margin-top: 8px; } - md-dialog.md-content-overflow .md-actions, md-dialog.md-content-overflow md-dialog-actions { - border-top-width: 1px; - border-top-style: solid; } - -@media screen and (-ms-high-contrast: active) { - md-dialog { - border: 1px solid #fff; } } - -@media (max-width: 959px) { - md-dialog.md-dialog-fullscreen { - min-height: 100%; - min-width: 100%; - border-radius: 0; } } - -md-divider { - display: block; - border-top-width: 1px; - border-top-style: solid; - margin: 0; } - md-divider[md-inset] { - margin-left: 80px; } - -.layout-row > md-divider { - border-top-width: 0; - border-right-width: 1px; - border-right-style: solid; } - -md-fab-speed-dial { - position: relative; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - z-index: 20; - /* - * Hide some graphics glitches if switching animation types - */ - /* - * Handle the animations - */ } - md-fab-speed-dial.md-fab-bottom-right { - top: auto; - right: 20px; - bottom: 20px; - left: auto; - position: absolute; } - md-fab-speed-dial.md-fab-bottom-left { - top: auto; - right: auto; - bottom: 20px; - left: 20px; - position: absolute; } - md-fab-speed-dial.md-fab-top-right { - top: 20px; - right: 20px; - bottom: auto; - left: auto; - position: absolute; } - md-fab-speed-dial.md-fab-top-left { - top: 20px; - right: auto; - bottom: auto; - left: 20px; - position: absolute; } - md-fab-speed-dial:not(.md-hover-full) { - pointer-events: none; } - md-fab-speed-dial:not(.md-hover-full) md-fab-trigger, md-fab-speed-dial:not(.md-hover-full) .md-fab-action-item { - pointer-events: auto; } - md-fab-speed-dial:not(.md-hover-full).md-is-open { - pointer-events: auto; } - md-fab-speed-dial .md-css-variables { - z-index: 20; } - md-fab-speed-dial.md-is-open .md-fab-action-item { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; } - md-fab-speed-dial md-fab-actions { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - height: auto; } - md-fab-speed-dial md-fab-actions .md-fab-action-item { - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } - md-fab-speed-dial.md-down { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - md-fab-speed-dial.md-down md-fab-trigger { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - md-fab-speed-dial.md-down md-fab-actions { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - md-fab-speed-dial.md-up { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; } - md-fab-speed-dial.md-up md-fab-trigger { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - md-fab-speed-dial.md-up md-fab-actions { - -webkit-flex-direction: column-reverse; - -ms-flex-direction: column-reverse; - flex-direction: column-reverse; - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - md-fab-speed-dial.md-left { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - md-fab-speed-dial.md-left md-fab-trigger { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - md-fab-speed-dial.md-left md-fab-actions { - -webkit-flex-direction: row-reverse; - -ms-flex-direction: row-reverse; - flex-direction: row-reverse; - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - md-fab-speed-dial.md-left md-fab-actions .md-fab-action-item { - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } - md-fab-speed-dial.md-right { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - md-fab-speed-dial.md-right md-fab-trigger { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - md-fab-speed-dial.md-right md-fab-actions { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - md-fab-speed-dial.md-right md-fab-actions .md-fab-action-item { - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } - md-fab-speed-dial.md-fling-remove .md-fab-action-item > *, md-fab-speed-dial.md-scale-remove .md-fab-action-item > * { - visibility: hidden; } - md-fab-speed-dial.md-fling .md-fab-action-item { - opacity: 1; } - md-fab-speed-dial.md-fling.md-animations-waiting .md-fab-action-item { - opacity: 0; - transition-duration: 0s; } - md-fab-speed-dial.md-scale .md-fab-action-item { - -webkit-transform: scale(0.1); - transform: scale(0.1); - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - transition-duration: 0.14286s; } - -md-fab-toolbar { - display: block; - /* - * Closed styling - */ - /* - * Hover styling - */ } - md-fab-toolbar.md-fab-bottom-right { - top: auto; - right: 20px; - bottom: 20px; - left: auto; - position: absolute; } - md-fab-toolbar.md-fab-bottom-left { - top: auto; - right: auto; - bottom: 20px; - left: 20px; - position: absolute; } - md-fab-toolbar.md-fab-top-right { - top: 20px; - right: 20px; - bottom: auto; - left: auto; - position: absolute; } - md-fab-toolbar.md-fab-top-left { - top: 20px; - right: auto; - bottom: auto; - left: 20px; - position: absolute; } - md-fab-toolbar .md-fab-toolbar-wrapper { - display: block; - position: relative; - overflow: hidden; - height: 68px; } - md-fab-toolbar md-fab-trigger { - position: absolute; - z-index: 20; } - md-fab-toolbar md-fab-trigger button { - overflow: visible !important; } - md-fab-toolbar md-fab-trigger .md-fab-toolbar-background { - display: block; - position: absolute; - z-index: 21; - opacity: 1; - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } - md-fab-toolbar md-fab-trigger md-icon { - position: relative; - z-index: 22; - opacity: 1; - transition: all 200ms ease-in; } - md-fab-toolbar.md-left md-fab-trigger { - right: 0; } - md-fab-toolbar.md-left .md-toolbar-tools { - -webkit-flex-direction: row-reverse; - -ms-flex-direction: row-reverse; - flex-direction: row-reverse; } - md-fab-toolbar.md-left .md-toolbar-tools > .md-button:first-child { - margin-right: 0.6rem; } - md-fab-toolbar.md-left .md-toolbar-tools > .md-button:first-child { - margin-left: -0.8rem; } - md-fab-toolbar.md-left .md-toolbar-tools > .md-button:last-child { - margin-right: 8px; } - md-fab-toolbar.md-right md-fab-trigger { - left: 0; } - md-fab-toolbar.md-right .md-toolbar-tools { - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - md-fab-toolbar md-toolbar { - background-color: transparent !important; - pointer-events: none; - z-index: 23; } - md-fab-toolbar md-toolbar .md-toolbar-tools { - padding: 0 20px; - margin-top: 3px; } - md-fab-toolbar md-toolbar .md-fab-action-item { - opacity: 0; - -webkit-transform: scale(0); - transform: scale(0); - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - transition-duration: 0.15s; } - md-fab-toolbar.md-is-open md-fab-trigger > button { - box-shadow: none; } - md-fab-toolbar.md-is-open md-fab-trigger > button md-icon { - opacity: 0; } - md-fab-toolbar.md-is-open .md-fab-action-item { - opacity: 1; - -webkit-transform: scale(1); - transform: scale(1); } - -md-grid-list { - box-sizing: border-box; - display: block; - position: relative; } - md-grid-list md-grid-tile, - md-grid-list md-grid-tile > figure, - md-grid-list md-grid-tile-header, - md-grid-list md-grid-tile-footer { - box-sizing: border-box; } - md-grid-list md-grid-tile { - display: block; - position: absolute; } - md-grid-list md-grid-tile figure { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - height: 100%; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: 0; - margin: 0; } - md-grid-list md-grid-tile md-grid-tile-header, - md-grid-list md-grid-tile md-grid-tile-footer { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - height: 48px; - color: #fff; - background: rgba(0, 0, 0, 0.18); - overflow: hidden; - position: absolute; - left: 0; - right: 0; } - md-grid-list md-grid-tile md-grid-tile-header h3, - md-grid-list md-grid-tile md-grid-tile-header h4, - md-grid-list md-grid-tile md-grid-tile-footer h3, - md-grid-list md-grid-tile md-grid-tile-footer h4 { - font-weight: 400; - margin: 0 0 0 16px; } - md-grid-list md-grid-tile md-grid-tile-header h3, - md-grid-list md-grid-tile md-grid-tile-footer h3 { - font-size: 14px; } - md-grid-list md-grid-tile md-grid-tile-header h4, - md-grid-list md-grid-tile md-grid-tile-footer h4 { - font-size: 12px; } - md-grid-list md-grid-tile md-grid-tile-header { - top: 0; } - md-grid-list md-grid-tile md-grid-tile-footer { - bottom: 0; } - -@media screen and (-ms-high-contrast: active) { - md-grid-tile { - border: 1px solid #fff; } - md-grid-tile-footer { - border-top: 1px solid #fff; } } - -md-icon { - margin: auto; - background-repeat: no-repeat no-repeat; - display: inline-block; - vertical-align: middle; - fill: currentColor; - height: 24px; - width: 24px; } - md-icon svg { - pointer-events: none; } - md-icon[md-font-icon] { - line-height: 1; - width: auto; } - -md-input-container { - display: inline-block; - position: relative; - padding: 2px; - margin: 18px 0; - vertical-align: middle; - /* - * The .md-input class is added to the input/textarea - */ } - md-input-container:after { - content: ''; - display: table; - clear: both; } - md-input-container.md-block { - display: block; } - md-input-container .md-errors-spacer { - float: right; - min-height: 24px; - min-width: 1px; } - html[dir=rtl] md-input-container .md-errors-spacer { - float: left; - unicode-bidi: embed; } - body[dir=rtl] md-input-container .md-errors-spacer { - float: left; - unicode-bidi: embed; } - md-input-container .md-errors-spacer bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container .md-errors-spacer bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container > md-icon { - position: absolute; - top: 5px; - left: 2px; - right: auto; } - html[dir=rtl] md-input-container > md-icon { - left: auto; - unicode-bidi: embed; } - body[dir=rtl] md-input-container > md-icon { - left: auto; - unicode-bidi: embed; } - md-input-container > md-icon bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container > md-icon bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container > md-icon { - right: 2px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container > md-icon { - right: 2px; - unicode-bidi: embed; } - md-input-container > md-icon bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container > md-icon bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container textarea, - md-input-container input[type="text"], - md-input-container input[type="password"], - md-input-container input[type="datetime"], - md-input-container input[type="datetime-local"], - md-input-container input[type="date"], - md-input-container input[type="month"], - md-input-container input[type="time"], - md-input-container input[type="week"], - md-input-container input[type="number"], - md-input-container input[type="email"], - md-input-container input[type="url"], - md-input-container input[type="search"], - md-input-container input[type="tel"], - md-input-container input[type="color"] { - /* remove default appearance from all input/textarea */ - -moz-appearance: none; - -webkit-appearance: none; } - md-input-container input[type="date"], - md-input-container input[type="datetime-local"], - md-input-container input[type="month"], - md-input-container input[type="time"], - md-input-container input[type="week"] { - min-height: 26px; } - md-input-container textarea { - resize: none; - overflow: hidden; } - md-input-container textarea.md-input { - min-height: 26px; - -ms-flex-preferred-size: auto; } - md-input-container label:not(.md-container-ignore) { - position: absolute; - bottom: 100%; - left: 0; - right: auto; } - html[dir=rtl] md-input-container label:not(.md-container-ignore) { - left: auto; - unicode-bidi: embed; } - body[dir=rtl] md-input-container label:not(.md-container-ignore) { - left: auto; - unicode-bidi: embed; } - md-input-container label:not(.md-container-ignore) bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container label:not(.md-container-ignore) bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container label:not(.md-container-ignore) { - right: 0; - unicode-bidi: embed; } - body[dir=rtl] md-input-container label:not(.md-container-ignore) { - right: 0; - unicode-bidi: embed; } - md-input-container label:not(.md-container-ignore) bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container label:not(.md-container-ignore) bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container.md-has-icon { - padding-left: 36px; - padding-right: 0; } - html[dir=rtl] md-input-container.md-has-icon { - padding-left: 0; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-has-icon { - padding-left: 0; - unicode-bidi: embed; } - md-input-container.md-has-icon bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-has-icon bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container.md-has-icon { - padding-right: 36px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-has-icon { - padding-right: 36px; - unicode-bidi: embed; } - md-input-container.md-has-icon bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-has-icon bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container.md-has-icon > label { - left: 36px; - right: auto; } - html[dir=rtl] md-input-container.md-has-icon > label { - left: auto; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-has-icon > label { - left: auto; - unicode-bidi: embed; } - md-input-container.md-has-icon > label bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-has-icon > label bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container.md-has-icon > label { - right: 36px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-has-icon > label { - right: 36px; - unicode-bidi: embed; } - md-input-container.md-has-icon > label bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-has-icon > label bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container label:not(.md-no-float):not(.md-container-ignore), - md-input-container .md-placeholder { - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; - pointer-events: none; - -webkit-font-smoothing: antialiased; - padding-left: 3px; - padding-right: 0; - z-index: 1; - -webkit-transform: translate3d(0, 28px, 0) scale(1); - transform: translate3d(0, 28px, 0) scale(1); - transition: -webkit-transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.25s; - transition: transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.25s; - -webkit-transform-origin: left top; - transform-origin: left top; } - html[dir=rtl] md-input-container label:not(.md-no-float):not(.md-container-ignore), html[dir=rtl] - md-input-container .md-placeholder { - padding-left: 0; - unicode-bidi: embed; } - body[dir=rtl] md-input-container label:not(.md-no-float):not(.md-container-ignore), body[dir=rtl] - md-input-container .md-placeholder { - padding-left: 0; - unicode-bidi: embed; } - md-input-container label:not(.md-no-float):not(.md-container-ignore) bdo[dir=rtl], - md-input-container .md-placeholder bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container label:not(.md-no-float):not(.md-container-ignore) bdo[dir=ltr], - md-input-container .md-placeholder bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container label:not(.md-no-float):not(.md-container-ignore), html[dir=rtl] - md-input-container .md-placeholder { - padding-right: 3px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container label:not(.md-no-float):not(.md-container-ignore), body[dir=rtl] - md-input-container .md-placeholder { - padding-right: 3px; - unicode-bidi: embed; } - md-input-container label:not(.md-no-float):not(.md-container-ignore) bdo[dir=rtl], - md-input-container .md-placeholder bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container label:not(.md-no-float):not(.md-container-ignore) bdo[dir=ltr], - md-input-container .md-placeholder bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container label:not(.md-no-float):not(.md-container-ignore), html[dir=rtl] - md-input-container .md-placeholder { - -webkit-transform-origin: right top; - transform-origin: right top; - unicode-bidi: embed; } - body[dir=rtl] md-input-container label:not(.md-no-float):not(.md-container-ignore), body[dir=rtl] - md-input-container .md-placeholder { - -webkit-transform-origin: right top; - transform-origin: right top; - unicode-bidi: embed; } - md-input-container label:not(.md-no-float):not(.md-container-ignore) bdo[dir=rtl], - md-input-container .md-placeholder bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container label:not(.md-no-float):not(.md-container-ignore) bdo[dir=ltr], - md-input-container .md-placeholder bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container .md-placeholder { - position: absolute; - top: 0; - opacity: 0; - transition-property: opacity, -webkit-transform; - transition-property: opacity, transform; - -webkit-transform: translate3d(0, 30px, 0); - transform: translate3d(0, 30px, 0); } - md-input-container.md-input-focused .md-placeholder { - opacity: 1; - -webkit-transform: translate3d(0, 24px, 0); - transform: translate3d(0, 24px, 0); } - md-input-container.md-input-has-value .md-placeholder { - transition: none; - opacity: 0; } - md-input-container:not(.md-input-has-value) input:not(:focus), - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-ampm-field, - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-day-field, - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-hour-field, - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-millisecond-field, - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-minute-field, - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-month-field, - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-second-field, - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-week-field, - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-year-field, - md-input-container:not(.md-input-has-value) input:not(:focus)::-webkit-datetime-edit-text { - color: transparent; } - md-input-container .md-input { - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; - display: block; - margin-top: 0; - background: none; - padding-top: 2px; - padding-bottom: 1px; - padding-left: 2px; - padding-right: 2px; - border-width: 0 0 1px 0; - line-height: 26px; - height: 30px; - -ms-flex-preferred-size: 26px; - border-radius: 0; - border-style: solid; - width: 100%; - box-sizing: border-box; - float: left; } - html[dir=rtl] md-input-container .md-input { - float: right; - unicode-bidi: embed; } - body[dir=rtl] md-input-container .md-input { - float: right; - unicode-bidi: embed; } - md-input-container .md-input bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container .md-input bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container .md-input:focus { - outline: none; } - md-input-container .md-input:invalid { - outline: none; - box-shadow: none; } - md-input-container .md-input.md-no-flex { - -webkit-flex: none !important; - -ms-flex: none !important; - flex: none !important; } - md-input-container .md-char-counter { - text-align: right; - padding-right: 2px; - padding-left: 0; } - html[dir=rtl] md-input-container .md-char-counter { - text-align: left; - unicode-bidi: embed; } - body[dir=rtl] md-input-container .md-char-counter { - text-align: left; - unicode-bidi: embed; } - md-input-container .md-char-counter bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container .md-char-counter bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container .md-char-counter { - padding-right: 0; - unicode-bidi: embed; } - body[dir=rtl] md-input-container .md-char-counter { - padding-right: 0; - unicode-bidi: embed; } - md-input-container .md-char-counter bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container .md-char-counter bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container .md-char-counter { - padding-left: 2px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container .md-char-counter { - padding-left: 2px; - unicode-bidi: embed; } - md-input-container .md-char-counter bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container .md-char-counter bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container ng-messages, md-input-container data-ng-messages, md-input-container x-ng-messages, - md-input-container [ng-messages], md-input-container [data-ng-messages], md-input-container [x-ng-messages] { - position: relative; - -webkit-order: 4; - -ms-flex-order: 4; - order: 4; - overflow: hidden; - clear: left; } - html[dir=rtl] md-input-container ng-messages, html[dir=rtl] md-input-container data-ng-messages, html[dir=rtl] md-input-container x-ng-messages, html[dir=rtl] - md-input-container [ng-messages], html[dir=rtl] md-input-container [data-ng-messages], html[dir=rtl] md-input-container [x-ng-messages] { - clear: right; - unicode-bidi: embed; } - body[dir=rtl] md-input-container ng-messages, body[dir=rtl] md-input-container data-ng-messages, body[dir=rtl] md-input-container x-ng-messages, body[dir=rtl] - md-input-container [ng-messages], body[dir=rtl] md-input-container [data-ng-messages], body[dir=rtl] md-input-container [x-ng-messages] { - clear: right; - unicode-bidi: embed; } - md-input-container ng-messages bdo[dir=rtl], md-input-container data-ng-messages bdo[dir=rtl], md-input-container x-ng-messages bdo[dir=rtl], - md-input-container [ng-messages] bdo[dir=rtl], md-input-container [data-ng-messages] bdo[dir=rtl], md-input-container [x-ng-messages] bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container ng-messages bdo[dir=ltr], md-input-container data-ng-messages bdo[dir=ltr], md-input-container x-ng-messages bdo[dir=ltr], - md-input-container [ng-messages] bdo[dir=ltr], md-input-container [data-ng-messages] bdo[dir=ltr], md-input-container [x-ng-messages] bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container ng-messages.ng-enter ng-message, md-input-container ng-messages.ng-enter data-ng-message, md-input-container ng-messages.ng-enter x-ng-message, - md-input-container ng-messages.ng-enter [ng-message], md-input-container ng-messages.ng-enter [data-ng-message], md-input-container ng-messages.ng-enter [x-ng-message], - md-input-container ng-messages.ng-enter [ng-message-exp], md-input-container ng-messages.ng-enter [data-ng-message-exp], md-input-container ng-messages.ng-enter [x-ng-message-exp], md-input-container data-ng-messages.ng-enter ng-message, md-input-container data-ng-messages.ng-enter data-ng-message, md-input-container data-ng-messages.ng-enter x-ng-message, - md-input-container data-ng-messages.ng-enter [ng-message], md-input-container data-ng-messages.ng-enter [data-ng-message], md-input-container data-ng-messages.ng-enter [x-ng-message], - md-input-container data-ng-messages.ng-enter [ng-message-exp], md-input-container data-ng-messages.ng-enter [data-ng-message-exp], md-input-container data-ng-messages.ng-enter [x-ng-message-exp], md-input-container x-ng-messages.ng-enter ng-message, md-input-container x-ng-messages.ng-enter data-ng-message, md-input-container x-ng-messages.ng-enter x-ng-message, - md-input-container x-ng-messages.ng-enter [ng-message], md-input-container x-ng-messages.ng-enter [data-ng-message], md-input-container x-ng-messages.ng-enter [x-ng-message], - md-input-container x-ng-messages.ng-enter [ng-message-exp], md-input-container x-ng-messages.ng-enter [data-ng-message-exp], md-input-container x-ng-messages.ng-enter [x-ng-message-exp], - md-input-container [ng-messages].ng-enter ng-message, - md-input-container [ng-messages].ng-enter data-ng-message, - md-input-container [ng-messages].ng-enter x-ng-message, - md-input-container [ng-messages].ng-enter [ng-message], - md-input-container [ng-messages].ng-enter [data-ng-message], - md-input-container [ng-messages].ng-enter [x-ng-message], - md-input-container [ng-messages].ng-enter [ng-message-exp], - md-input-container [ng-messages].ng-enter [data-ng-message-exp], - md-input-container [ng-messages].ng-enter [x-ng-message-exp], md-input-container [data-ng-messages].ng-enter ng-message, md-input-container [data-ng-messages].ng-enter data-ng-message, md-input-container [data-ng-messages].ng-enter x-ng-message, - md-input-container [data-ng-messages].ng-enter [ng-message], md-input-container [data-ng-messages].ng-enter [data-ng-message], md-input-container [data-ng-messages].ng-enter [x-ng-message], - md-input-container [data-ng-messages].ng-enter [ng-message-exp], md-input-container [data-ng-messages].ng-enter [data-ng-message-exp], md-input-container [data-ng-messages].ng-enter [x-ng-message-exp], md-input-container [x-ng-messages].ng-enter ng-message, md-input-container [x-ng-messages].ng-enter data-ng-message, md-input-container [x-ng-messages].ng-enter x-ng-message, - md-input-container [x-ng-messages].ng-enter [ng-message], md-input-container [x-ng-messages].ng-enter [data-ng-message], md-input-container [x-ng-messages].ng-enter [x-ng-message], - md-input-container [x-ng-messages].ng-enter [ng-message-exp], md-input-container [x-ng-messages].ng-enter [data-ng-message-exp], md-input-container [x-ng-messages].ng-enter [x-ng-message-exp] { - opacity: 0; - margin-top: -100px; } - md-input-container ng-message, md-input-container data-ng-message, md-input-container x-ng-message, - md-input-container [ng-message], md-input-container [data-ng-message], md-input-container [x-ng-message], - md-input-container [ng-message-exp], md-input-container [data-ng-message-exp], md-input-container [x-ng-message-exp], - md-input-container .md-char-counter { - font-size: 12px; - line-height: 14px; - overflow: hidden; - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - opacity: 1; - margin-top: 0; - padding-top: 5px; } - md-input-container ng-message:not(.md-char-counter), md-input-container data-ng-message:not(.md-char-counter), md-input-container x-ng-message:not(.md-char-counter), - md-input-container [ng-message]:not(.md-char-counter), md-input-container [data-ng-message]:not(.md-char-counter), md-input-container [x-ng-message]:not(.md-char-counter), - md-input-container [ng-message-exp]:not(.md-char-counter), md-input-container [data-ng-message-exp]:not(.md-char-counter), md-input-container [x-ng-message-exp]:not(.md-char-counter), - md-input-container .md-char-counter:not(.md-char-counter) { - padding-right: 5px; - padding-left: 0; } - html[dir=rtl] md-input-container ng-message:not(.md-char-counter), html[dir=rtl] md-input-container data-ng-message:not(.md-char-counter), html[dir=rtl] md-input-container x-ng-message:not(.md-char-counter), html[dir=rtl] - md-input-container [ng-message]:not(.md-char-counter), html[dir=rtl] md-input-container [data-ng-message]:not(.md-char-counter), html[dir=rtl] md-input-container [x-ng-message]:not(.md-char-counter), html[dir=rtl] - md-input-container [ng-message-exp]:not(.md-char-counter), html[dir=rtl] md-input-container [data-ng-message-exp]:not(.md-char-counter), html[dir=rtl] md-input-container [x-ng-message-exp]:not(.md-char-counter), html[dir=rtl] - md-input-container .md-char-counter:not(.md-char-counter) { - padding-right: 0; - unicode-bidi: embed; } - body[dir=rtl] md-input-container ng-message:not(.md-char-counter), body[dir=rtl] md-input-container data-ng-message:not(.md-char-counter), body[dir=rtl] md-input-container x-ng-message:not(.md-char-counter), body[dir=rtl] - md-input-container [ng-message]:not(.md-char-counter), body[dir=rtl] md-input-container [data-ng-message]:not(.md-char-counter), body[dir=rtl] md-input-container [x-ng-message]:not(.md-char-counter), body[dir=rtl] - md-input-container [ng-message-exp]:not(.md-char-counter), body[dir=rtl] md-input-container [data-ng-message-exp]:not(.md-char-counter), body[dir=rtl] md-input-container [x-ng-message-exp]:not(.md-char-counter), body[dir=rtl] - md-input-container .md-char-counter:not(.md-char-counter) { - padding-right: 0; - unicode-bidi: embed; } - md-input-container ng-message:not(.md-char-counter) bdo[dir=rtl], md-input-container data-ng-message:not(.md-char-counter) bdo[dir=rtl], md-input-container x-ng-message:not(.md-char-counter) bdo[dir=rtl], - md-input-container [ng-message]:not(.md-char-counter) bdo[dir=rtl], md-input-container [data-ng-message]:not(.md-char-counter) bdo[dir=rtl], md-input-container [x-ng-message]:not(.md-char-counter) bdo[dir=rtl], - md-input-container [ng-message-exp]:not(.md-char-counter) bdo[dir=rtl], md-input-container [data-ng-message-exp]:not(.md-char-counter) bdo[dir=rtl], md-input-container [x-ng-message-exp]:not(.md-char-counter) bdo[dir=rtl], - md-input-container .md-char-counter:not(.md-char-counter) bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container ng-message:not(.md-char-counter) bdo[dir=ltr], md-input-container data-ng-message:not(.md-char-counter) bdo[dir=ltr], md-input-container x-ng-message:not(.md-char-counter) bdo[dir=ltr], - md-input-container [ng-message]:not(.md-char-counter) bdo[dir=ltr], md-input-container [data-ng-message]:not(.md-char-counter) bdo[dir=ltr], md-input-container [x-ng-message]:not(.md-char-counter) bdo[dir=ltr], - md-input-container [ng-message-exp]:not(.md-char-counter) bdo[dir=ltr], md-input-container [data-ng-message-exp]:not(.md-char-counter) bdo[dir=ltr], md-input-container [x-ng-message-exp]:not(.md-char-counter) bdo[dir=ltr], - md-input-container .md-char-counter:not(.md-char-counter) bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container ng-message:not(.md-char-counter), html[dir=rtl] md-input-container data-ng-message:not(.md-char-counter), html[dir=rtl] md-input-container x-ng-message:not(.md-char-counter), html[dir=rtl] - md-input-container [ng-message]:not(.md-char-counter), html[dir=rtl] md-input-container [data-ng-message]:not(.md-char-counter), html[dir=rtl] md-input-container [x-ng-message]:not(.md-char-counter), html[dir=rtl] - md-input-container [ng-message-exp]:not(.md-char-counter), html[dir=rtl] md-input-container [data-ng-message-exp]:not(.md-char-counter), html[dir=rtl] md-input-container [x-ng-message-exp]:not(.md-char-counter), html[dir=rtl] - md-input-container .md-char-counter:not(.md-char-counter) { - padding-left: 5px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container ng-message:not(.md-char-counter), body[dir=rtl] md-input-container data-ng-message:not(.md-char-counter), body[dir=rtl] md-input-container x-ng-message:not(.md-char-counter), body[dir=rtl] - md-input-container [ng-message]:not(.md-char-counter), body[dir=rtl] md-input-container [data-ng-message]:not(.md-char-counter), body[dir=rtl] md-input-container [x-ng-message]:not(.md-char-counter), body[dir=rtl] - md-input-container [ng-message-exp]:not(.md-char-counter), body[dir=rtl] md-input-container [data-ng-message-exp]:not(.md-char-counter), body[dir=rtl] md-input-container [x-ng-message-exp]:not(.md-char-counter), body[dir=rtl] - md-input-container .md-char-counter:not(.md-char-counter) { - padding-left: 5px; - unicode-bidi: embed; } - md-input-container ng-message:not(.md-char-counter) bdo[dir=rtl], md-input-container data-ng-message:not(.md-char-counter) bdo[dir=rtl], md-input-container x-ng-message:not(.md-char-counter) bdo[dir=rtl], - md-input-container [ng-message]:not(.md-char-counter) bdo[dir=rtl], md-input-container [data-ng-message]:not(.md-char-counter) bdo[dir=rtl], md-input-container [x-ng-message]:not(.md-char-counter) bdo[dir=rtl], - md-input-container [ng-message-exp]:not(.md-char-counter) bdo[dir=rtl], md-input-container [data-ng-message-exp]:not(.md-char-counter) bdo[dir=rtl], md-input-container [x-ng-message-exp]:not(.md-char-counter) bdo[dir=rtl], - md-input-container .md-char-counter:not(.md-char-counter) bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container ng-message:not(.md-char-counter) bdo[dir=ltr], md-input-container data-ng-message:not(.md-char-counter) bdo[dir=ltr], md-input-container x-ng-message:not(.md-char-counter) bdo[dir=ltr], - md-input-container [ng-message]:not(.md-char-counter) bdo[dir=ltr], md-input-container [data-ng-message]:not(.md-char-counter) bdo[dir=ltr], md-input-container [x-ng-message]:not(.md-char-counter) bdo[dir=ltr], - md-input-container [ng-message-exp]:not(.md-char-counter) bdo[dir=ltr], md-input-container [data-ng-message-exp]:not(.md-char-counter) bdo[dir=ltr], md-input-container [x-ng-message-exp]:not(.md-char-counter) bdo[dir=ltr], - md-input-container .md-char-counter:not(.md-char-counter) bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container:not(.md-input-invalid) .md-auto-hide .md-input-message-animation { - opacity: 0; - margin-top: -100px; } - md-input-container .md-auto-hide .md-input-message-animation:not(.ng-animate) { - opacity: 0; - margin-top: -100px; } - md-input-container .md-input-message-animation.ng-enter { - opacity: 0; - margin-top: -100px; } - md-input-container.md-input-focused label:not(.md-no-float), md-input-container.md-input-has-placeholder label:not(.md-no-float), md-input-container.md-input-has-value label:not(.md-no-float) { - -webkit-transform: translate3d(0, 6px, 0) scale(0.75); - transform: translate3d(0, 6px, 0) scale(0.75); } - md-input-container.md-input-has-value label { - transition: none; } - md-input-container.md-input-focused .md-input, - md-input-container .md-input.ng-invalid.ng-dirty { - padding-bottom: 0; - border-width: 0 0 2px 0; } - md-input-container .md-input[disabled], - [disabled] md-input-container .md-input { - background-position: 0 bottom; - background-size: 4px 1px; - background-repeat: repeat-x; - margin-bottom: -1px; } - -md-input-container.md-icon-float { - transition: margin-top 0.5s cubic-bezier(0.25, 0.8, 0.25, 1); } - md-input-container.md-icon-float > label { - pointer-events: none; - position: absolute; } - md-input-container.md-icon-float > md-icon { - top: 2px; - left: 2px; - right: auto; } - html[dir=rtl] md-input-container.md-icon-float > md-icon { - left: auto; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-icon-float > md-icon { - left: auto; - unicode-bidi: embed; } - md-input-container.md-icon-float > md-icon bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-icon-float > md-icon bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container.md-icon-float > md-icon { - right: 2px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-icon-float > md-icon { - right: 2px; - unicode-bidi: embed; } - md-input-container.md-icon-float > md-icon bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-icon-float > md-icon bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container.md-icon-float.md-input-focused label, md-input-container.md-icon-float.md-input-has-value label { - -webkit-transform: translate3d(0, 6px, 0) scale(0.75); - transform: translate3d(0, 6px, 0) scale(0.75); - transition: -webkit-transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.5s; - transition: transform cubic-bezier(0.25, 0.8, 0.25, 1) 0.5s; } - -md-input-container.md-icon-right { - padding-right: 36px; - padding-left: 36px; } - html[dir=rtl] md-input-container.md-icon-right { - padding-right: 36px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-icon-right { - padding-right: 36px; - unicode-bidi: embed; } - md-input-container.md-icon-right bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-icon-right bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container.md-icon-right { - padding-left: 36px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-icon-right { - padding-left: 36px; - unicode-bidi: embed; } - md-input-container.md-icon-right bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-icon-right bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-input-container.md-icon-right .md-errors-spacer + md-icon { - margin: 0; - right: 2px; - left: auto; } - html[dir=rtl] md-input-container.md-icon-right .md-errors-spacer + md-icon { - right: auto; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-icon-right .md-errors-spacer + md-icon { - right: auto; - unicode-bidi: embed; } - md-input-container.md-icon-right .md-errors-spacer + md-icon bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-icon-right .md-errors-spacer + md-icon bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-input-container.md-icon-right .md-errors-spacer + md-icon { - left: 2px; - unicode-bidi: embed; } - body[dir=rtl] md-input-container.md-icon-right .md-errors-spacer + md-icon { - left: 2px; - unicode-bidi: embed; } - md-input-container.md-icon-right .md-errors-spacer + md-icon bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-input-container.md-icon-right .md-errors-spacer + md-icon bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - -@media screen and (-ms-high-contrast: active) { - md-input-container.md-default-theme > md-icon { - fill: #fff; } } - -md-list { - display: block; - padding: 8px 0px 8px 0px; } - md-list .md-subheader { - font-size: 14px; - font-weight: 500; - letter-spacing: 0.010em; - line-height: 1.2em; } - -md-list-item { - position: relative; } - md-list-item.md-proxy-focus.md-focused .md-no-style { - transition: background-color 0.15s linear; } - md-list-item.md-no-proxy, - md-list-item .md-no-style { - position: relative; - padding: 0px 16px; - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; } - md-list-item.md-no-proxy.md-button, - md-list-item .md-no-style.md-button { - font-size: inherit; - height: inherit; - text-align: left; - text-transform: none; - width: 100%; - white-space: normal; - -webkit-flex-direction: inherit; - -ms-flex-direction: inherit; - flex-direction: inherit; - -webkit-align-items: inherit; - -ms-flex-align: inherit; - align-items: inherit; - border-radius: 0; } - md-list-item.md-no-proxy.md-button > .md-ripple-container, - md-list-item .md-no-style.md-button > .md-ripple-container { - border-radius: 0; } - md-list-item.md-no-proxy:focus, - md-list-item .md-no-style:focus { - outline: none; } - md-list-item.md-with-secondary { - position: relative; } - md-list-item.md-clickable:hover { - cursor: pointer; } - md-list-item md-divider { - position: absolute; - bottom: 0; - left: 0; - width: 100%; } - md-list-item md-divider[md-inset] { - left: 96px; - width: calc(100% - 96px); - margin: 0; } - -md-list-item, md-list-item .md-list-item-inner { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-justify-content: flex-start; - -ms-flex-pack: start; - justify-content: flex-start; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - min-height: 48px; - height: auto; } - md-list-item > div.md-primary > md-icon:not(.md-avatar-icon), - md-list-item > div.md-secondary > md-icon:not(.md-avatar-icon), - md-list-item > md-icon:first-child:not(.md-avatar-icon), - md-list-item > md-icon.md-secondary:not(.md-avatar-icon), md-list-item .md-list-item-inner > div.md-primary > md-icon:not(.md-avatar-icon), - md-list-item .md-list-item-inner > div.md-secondary > md-icon:not(.md-avatar-icon), - md-list-item .md-list-item-inner > md-icon:first-child:not(.md-avatar-icon), - md-list-item .md-list-item-inner > md-icon.md-secondary:not(.md-avatar-icon) { - width: 24px; - margin-top: 16px; - margin-bottom: 12px; - box-sizing: content-box; } - md-list-item > div.md-primary > md-checkbox, - md-list-item > div.md-secondary > md-checkbox, - md-list-item > md-checkbox, - md-list-item md-checkbox.md-secondary, md-list-item .md-list-item-inner > div.md-primary > md-checkbox, - md-list-item .md-list-item-inner > div.md-secondary > md-checkbox, - md-list-item .md-list-item-inner > md-checkbox, - md-list-item .md-list-item-inner md-checkbox.md-secondary { - -webkit-align-self: center; - -ms-flex-item-align: center; - align-self: center; } - md-list-item > div.md-primary > md-checkbox .md-label, - md-list-item > div.md-secondary > md-checkbox .md-label, - md-list-item > md-checkbox .md-label, - md-list-item md-checkbox.md-secondary .md-label, md-list-item .md-list-item-inner > div.md-primary > md-checkbox .md-label, - md-list-item .md-list-item-inner > div.md-secondary > md-checkbox .md-label, - md-list-item .md-list-item-inner > md-checkbox .md-label, - md-list-item .md-list-item-inner md-checkbox.md-secondary .md-label { - display: none; } - md-list-item > md-icon:first-child:not(.md-avatar-icon), md-list-item .md-list-item-inner > md-icon:first-child:not(.md-avatar-icon) { - margin-right: 32px; } - md-list-item > md-checkbox, md-list-item .md-list-item-inner > md-checkbox { - width: 24px; - margin-left: 3px; - margin-right: 29px; - margin-top: 16px; } - md-list-item .md-avatar, md-list-item .md-avatar-icon, md-list-item .md-list-item-inner .md-avatar, md-list-item .md-list-item-inner .md-avatar-icon { - margin-top: 8px; - margin-bottom: 8px; - margin-right: 16px; - border-radius: 50%; - box-sizing: content-box; } - md-list-item .md-avatar, md-list-item .md-list-item-inner .md-avatar { - width: 40px; - height: 40px; } - md-list-item .md-avatar-icon, md-list-item .md-list-item-inner .md-avatar-icon { - padding: 8px; } - md-list-item md-checkbox.md-secondary, - md-list-item md-switch.md-secondary, md-list-item .md-list-item-inner md-checkbox.md-secondary, - md-list-item .md-list-item-inner md-switch.md-secondary { - margin-top: 0; - margin-bottom: 0; } - md-list-item md-checkbox.md-secondary, md-list-item .md-list-item-inner md-checkbox.md-secondary { - margin-right: 0; } - md-list-item md-switch.md-secondary, md-list-item .md-list-item-inner md-switch.md-secondary { - margin-right: -6px; } - md-list-item button.md-button.md-secondary-container, md-list-item .md-list-item-inner button.md-button.md-secondary-container { - background-color: transparent; - -webkit-align-self: center; - -ms-flex-item-align: center; - align-self: center; - border-radius: 50%; - margin: 0px; - min-width: 0px; } - md-list-item button.md-button.md-secondary-container .md-ripple, - md-list-item button.md-button.md-secondary-container .md-ripple-container, md-list-item .md-list-item-inner button.md-button.md-secondary-container .md-ripple, - md-list-item .md-list-item-inner button.md-button.md-secondary-container .md-ripple-container { - border-radius: 50%; } - md-list-item button.md-button.md-secondary-container.md-icon-button, md-list-item .md-list-item-inner button.md-button.md-secondary-container.md-icon-button { - margin-right: -12px; } - md-list-item .md-secondary-container, - md-list-item .md-secondary, md-list-item .md-list-item-inner .md-secondary-container, - md-list-item .md-list-item-inner .md-secondary { - position: absolute; - top: 50%; - right: 16px; - margin: 0 0 0 16px; - -webkit-transform: translate3d(0, -50%, 0); - transform: translate3d(0, -50%, 0); } - md-list-item > .md-button.md-secondary-container > .md-secondary, md-list-item .md-list-item-inner > .md-button.md-secondary-container > .md-secondary { - margin-left: 0; - position: static; } - md-list-item > p, md-list-item > .md-list-item-inner > p, md-list-item .md-list-item-inner > p, md-list-item .md-list-item-inner > .md-list-item-inner > p { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - margin: 0; } - -md-list-item.md-2-line, -md-list-item.md-2-line > .md-no-style, -md-list-item.md-3-line, -md-list-item.md-3-line > .md-no-style { - -webkit-align-items: flex-start; - -ms-flex-align: start; - align-items: flex-start; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; } - md-list-item.md-2-line .md-list-item-text, - md-list-item.md-2-line > .md-no-style .md-list-item-text, - md-list-item.md-3-line .md-list-item-text, - md-list-item.md-3-line > .md-no-style .md-list-item-text { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - margin: auto; - text-overflow: ellipsis; } - md-list-item.md-2-line .md-list-item-text.md-offset, - md-list-item.md-2-line > .md-no-style .md-list-item-text.md-offset, - md-list-item.md-3-line .md-list-item-text.md-offset, - md-list-item.md-3-line > .md-no-style .md-list-item-text.md-offset { - margin-left: 56px; } - md-list-item.md-2-line .md-list-item-text h3, - md-list-item.md-2-line > .md-no-style .md-list-item-text h3, - md-list-item.md-3-line .md-list-item-text h3, - md-list-item.md-3-line > .md-no-style .md-list-item-text h3 { - font-size: 16px; - font-weight: 400; - letter-spacing: 0.010em; - margin: 0 0 0px 0; - line-height: 1.2em; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; } - md-list-item.md-2-line .md-list-item-text h4, - md-list-item.md-2-line > .md-no-style .md-list-item-text h4, - md-list-item.md-3-line .md-list-item-text h4, - md-list-item.md-3-line > .md-no-style .md-list-item-text h4 { - font-size: 14px; - letter-spacing: 0.010em; - margin: 3px 0 1px 0; - font-weight: 400; - line-height: 1.2em; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; } - md-list-item.md-2-line .md-list-item-text p, - md-list-item.md-2-line > .md-no-style .md-list-item-text p, - md-list-item.md-3-line .md-list-item-text p, - md-list-item.md-3-line > .md-no-style .md-list-item-text p { - font-size: 14px; - font-weight: 500; - letter-spacing: 0.010em; - margin: 0 0 0 0; - line-height: 1.6em; } - -md-list-item.md-2-line, -md-list-item.md-2-line > .md-no-style { - height: auto; - min-height: 72px; } - md-list-item.md-2-line.md-long-text, - md-list-item.md-2-line > .md-no-style.md-long-text { - margin: 1.6em; } - md-list-item.md-2-line > .md-avatar, md-list-item.md-2-line .md-avatar-icon, - md-list-item.md-2-line > .md-no-style > .md-avatar, - md-list-item.md-2-line > .md-no-style .md-avatar-icon { - margin-top: 12px; } - md-list-item.md-2-line > md-icon:first-child, - md-list-item.md-2-line > .md-no-style > md-icon:first-child { - -webkit-align-self: flex-start; - -ms-flex-item-align: start; - align-self: flex-start; } - md-list-item.md-2-line .md-list-item-text, - md-list-item.md-2-line > .md-no-style .md-list-item-text { - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; } - -md-list-item.md-3-line, -md-list-item.md-3-line > .md-no-style { - height: auto; - min-height: 88px; } - md-list-item.md-3-line.md-long-text, - md-list-item.md-3-line > .md-no-style.md-long-text { - margin: 1.6em; } - md-list-item.md-3-line > md-icon:first-child, - md-list-item.md-3-line > .md-avatar, - md-list-item.md-3-line > .md-no-style > md-icon:first-child, - md-list-item.md-3-line > .md-no-style > .md-avatar { - margin-top: 16px; } - -.md-open-menu-container { - position: fixed; - left: 0; - top: 0; - z-index: 100; - opacity: 0; - border-radius: 2px; } - .md-open-menu-container md-menu-divider { - margin-top: 4px; - margin-bottom: 4px; - height: 1px; - min-height: 1px; - max-height: 1px; - width: 100%; } - .md-open-menu-container md-menu-content > * { - opacity: 0; } - .md-open-menu-container:not(.md-clickable) { - pointer-events: none; } - .md-open-menu-container.md-active { - opacity: 1; - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - transition-duration: 200ms; } - .md-open-menu-container.md-active > md-menu-content > * { - opacity: 1; - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - transition-duration: 200ms; - transition-delay: 100ms; } - .md-open-menu-container.md-leave { - opacity: 0; - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - transition-duration: 250ms; } - -md-menu-content { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - padding: 8px 0; - max-height: 304px; - overflow-y: auto; } - md-menu-content.md-dense { - max-height: 208px; } - md-menu-content.md-dense md-menu-item { - height: 32px; - min-height: 0px; } - -md-menu-item { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - min-height: 48px; - height: 48px; - -webkit-align-content: center; - -ms-flex-line-pack: center; - align-content: center; - -webkit-justify-content: flex-start; - -ms-flex-pack: start; - justify-content: flex-start; } - md-menu-item > * { - width: 100%; - margin: auto 0; - padding-left: 16px; - padding-right: 16px; } - md-menu-item > a.md-button { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - md-menu-item > .md-button { - border-radius: 0; - margin: auto 0; - font-size: 15px; - text-transform: none; - font-weight: 400; - text-align: left; - text-align: start; - height: 100%; - padding-left: 16px; - padding-right: 16px; - display: inline-block; - -webkit-align-items: baseline; - -ms-flex-align: baseline; - align-items: baseline; - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; - width: 100%; } - md-menu-item > .md-button md-icon { - margin: auto 16px auto 0; } - md-menu-item > .md-button p { - display: inline-block; - margin: auto; } - md-menu-item > .md-button span { - margin-top: auto; - margin-bottom: auto; } - md-menu-item > .md-button .md-ripple-container { - border-radius: inherit; } - -.md-menu { - padding: 8px 0; } - -md-toolbar .md-menu { - height: auto; - margin: auto; - padding: 0; } - -@media (max-width: 959px) { - md-menu-content { - min-width: 112px; } - md-menu-content[width="3"] { - min-width: 168px; } - md-menu-content[width="4"] { - min-width: 224px; } - md-menu-content[width="5"] { - min-width: 280px; } - md-menu-content[width="6"] { - min-width: 336px; } - md-menu-content[width="7"] { - min-width: 392px; } } - -@media (min-width: 960px) { - md-menu-content { - min-width: 96px; } - md-menu-content[width="3"] { - min-width: 192px; } - md-menu-content[width="4"] { - min-width: 256px; } - md-menu-content[width="5"] { - min-width: 320px; } - md-menu-content[width="6"] { - min-width: 384px; } - md-menu-content[width="7"] { - min-width: 448px; } } - -md-toolbar.md-menu-toolbar h2.md-toolbar-tools { - line-height: 1rem; - height: auto; - padding: 28px; - padding-bottom: 12px; } - -md-menu-bar { - padding: 0 20px; - display: block; - position: relative; - z-index: 2; } - md-menu-bar .md-menu { - display: inline-block; - padding: 0; - position: relative; } - md-menu-bar button { - font-size: 14px; - padding: 0 10px; - margin: 0; - border: 0; - background-color: transparent; - height: 40px; } - md-menu-bar md-backdrop.md-menu-backdrop { - z-index: -2; } - -md-menu-content.md-menu-bar-menu.md-dense { - max-height: none; - padding: 16px 0; } - md-menu-content.md-menu-bar-menu.md-dense md-menu-item.md-indent { - position: relative; } - md-menu-content.md-menu-bar-menu.md-dense md-menu-item.md-indent > md-icon { - position: absolute; - padding: 0; - width: 24px; - top: 6px; - left: 24px; } - md-menu-content.md-menu-bar-menu.md-dense md-menu-item.md-indent > .md-button, md-menu-content.md-menu-bar-menu.md-dense md-menu-item.md-indent .md-menu > .md-button { - padding: 0 32px 0 64px; } - md-menu-content.md-menu-bar-menu.md-dense .md-button { - min-height: 0; - height: 32px; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; } - md-menu-content.md-menu-bar-menu.md-dense .md-button span { - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; } - md-menu-content.md-menu-bar-menu.md-dense .md-button span.md-alt-text { - -webkit-flex-grow: 0; - -ms-flex-positive: 0; - flex-grow: 0; - -webkit-align-self: flex-end; - -ms-flex-item-align: end; - align-self: flex-end; - margin: 0 8px; } - md-menu-content.md-menu-bar-menu.md-dense md-menu-divider { - margin: 8px 0; } - md-menu-content.md-menu-bar-menu.md-dense md-menu-item > .md-button, md-menu-content.md-menu-bar-menu.md-dense .md-menu > .md-button { - text-align: left; - text-align: start; } - md-menu-content.md-menu-bar-menu.md-dense .md-menu { - padding: 0; } - md-menu-content.md-menu-bar-menu.md-dense .md-menu > .md-button { - position: relative; - margin: 0; - width: 100%; - text-transform: none; - font-weight: normal; - border-radius: 0px; - padding-left: 16px; } - md-menu-content.md-menu-bar-menu.md-dense .md-menu > .md-button:after { - display: block; - content: '\25BC'; - position: absolute; - top: 0px; - speak: none; - -webkit-transform: rotate(270deg) scaleY(0.45) scaleX(0.9); - transform: rotate(270deg) scaleY(0.45) scaleX(0.9); - right: 28px; } - -md-progress-circular { - display: block; - position: relative; - width: 100px; - height: 100px; - padding-top: 0 !important; - margin-bottom: 0 !important; - z-index: 2; } - md-progress-circular .md-spinner-wrapper { - display: block; - position: absolute; - overflow: hidden; - top: 50%; - left: 50%; } - md-progress-circular .md-spinner-wrapper .md-inner { - width: 100px; - height: 100px; - position: relative; } - md-progress-circular .md-spinner-wrapper .md-inner .md-gap { - position: absolute; - left: 49px; - right: 49px; - top: 0; - bottom: 0; - border-top-width: 10px; - border-top-style: solid; - box-sizing: border-box; } - md-progress-circular .md-spinner-wrapper .md-inner .md-left, md-progress-circular .md-spinner-wrapper .md-inner .md-right { - position: absolute; - top: 0; - height: 100px; - width: 50px; - overflow: hidden; } - md-progress-circular .md-spinner-wrapper .md-inner .md-left .md-half-circle, md-progress-circular .md-spinner-wrapper .md-inner .md-right .md-half-circle { - position: absolute; - top: 0; - width: 100px; - height: 100px; - box-sizing: border-box; - border-width: 10px; - border-style: solid; - border-bottom-color: transparent; - border-radius: 50%; } - md-progress-circular .md-spinner-wrapper .md-inner .md-left { - left: 0; } - md-progress-circular .md-spinner-wrapper .md-inner .md-left .md-half-circle { - left: 0; - border-right-color: transparent; } - md-progress-circular .md-spinner-wrapper .md-inner .md-right { - right: 0; } - md-progress-circular .md-spinner-wrapper .md-inner .md-right .md-half-circle { - right: 0; - border-left-color: transparent; } - md-progress-circular .md-mode-indeterminate .md-spinner-wrapper { - -webkit-animation: outer-rotate 2.91667s linear infinite; - animation: outer-rotate 2.91667s linear infinite; } - md-progress-circular .md-mode-indeterminate .md-spinner-wrapper .md-inner { - -webkit-animation: sporadic-rotate 5.25s cubic-bezier(0.35, 0, 0.25, 1) infinite; - animation: sporadic-rotate 5.25s cubic-bezier(0.35, 0, 0.25, 1) infinite; } - md-progress-circular .md-mode-indeterminate .md-spinner-wrapper .md-inner .md-left .md-half-circle, md-progress-circular .md-mode-indeterminate .md-spinner-wrapper .md-inner .md-right .md-half-circle { - -webkit-animation-iteration-count: infinite; - animation-iteration-count: infinite; - -webkit-animation-duration: 1.3125s; - animation-duration: 1.3125s; - -webkit-animation-timing-function: cubic-bezier(0.35, 0, 0.25, 1); - animation-timing-function: cubic-bezier(0.35, 0, 0.25, 1); } - md-progress-circular .md-mode-indeterminate .md-spinner-wrapper .md-inner .md-left .md-half-circle { - -webkit-animation-name: left-wobble; - animation-name: left-wobble; } - md-progress-circular .md-mode-indeterminate .md-spinner-wrapper .md-inner .md-right .md-half-circle { - -webkit-animation-name: right-wobble; - animation-name: right-wobble; } - md-progress-circular md-progress-circular.ng-hide .md-spinner-wrapper { - -webkit-animation: none; - animation: none; } - md-progress-circular md-progress-circular.ng-hide .md-spinner-wrapper .md-inner { - -webkit-animation: none; - animation: none; } - md-progress-circular md-progress-circular.ng-hide .md-spinner-wrapper .md-inner .md-left .md-half-circle { - -webkit-animation-name: none; - animation-name: none; } - md-progress-circular md-progress-circular.ng-hide .md-spinner-wrapper .md-inner .md-right .md-half-circle { - -webkit-animation-name: none; - animation-name: none; } - md-progress-circular .md-spinner-wrapper.ng-hide { - -webkit-animation: none; - animation: none; } - md-progress-circular .md-spinner-wrapper.ng-hide .md-inner { - -webkit-animation: none; - animation: none; } - md-progress-circular .md-spinner-wrapper.ng-hide .md-inner .md-left .md-half-circle { - -webkit-animation-name: none; - animation-name: none; } - md-progress-circular .md-spinner-wrapper.ng-hide .md-inner .md-right .md-half-circle { - -webkit-animation-name: none; - animation-name: none; } - -@-webkit-keyframes outer-rotate { - 0% { - -webkit-transform: rotate(0deg) scale(0.5); - transform: rotate(0deg) scale(0.5); } - 100% { - -webkit-transform: rotate(360deg) scale(0.5); - transform: rotate(360deg) scale(0.5); } } - -@keyframes outer-rotate { - 0% { - -webkit-transform: rotate(0deg) scale(0.5); - transform: rotate(0deg) scale(0.5); } - 100% { - -webkit-transform: rotate(360deg) scale(0.5); - transform: rotate(360deg) scale(0.5); } } - -@-webkit-keyframes left-wobble { - 0%, 100% { - -webkit-transform: rotate(130deg); - transform: rotate(130deg); } - 50% { - -webkit-transform: rotate(-5deg); - transform: rotate(-5deg); } } - -@keyframes left-wobble { - 0%, 100% { - -webkit-transform: rotate(130deg); - transform: rotate(130deg); } - 50% { - -webkit-transform: rotate(-5deg); - transform: rotate(-5deg); } } - -@-webkit-keyframes right-wobble { - 0%, 100% { - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); } - 50% { - -webkit-transform: rotate(5deg); - transform: rotate(5deg); } } - -@keyframes right-wobble { - 0%, 100% { - -webkit-transform: rotate(-130deg); - transform: rotate(-130deg); } - 50% { - -webkit-transform: rotate(5deg); - transform: rotate(5deg); } } - -@-webkit-keyframes sporadic-rotate { - 12.5% { - -webkit-transform: rotate(135deg); - transform: rotate(135deg); } - 25% { - -webkit-transform: rotate(270deg); - transform: rotate(270deg); } - 37.5% { - -webkit-transform: rotate(405deg); - transform: rotate(405deg); } - 50% { - -webkit-transform: rotate(540deg); - transform: rotate(540deg); } - 62.5% { - -webkit-transform: rotate(675deg); - transform: rotate(675deg); } - 75% { - -webkit-transform: rotate(810deg); - transform: rotate(810deg); } - 87.5% { - -webkit-transform: rotate(945deg); - transform: rotate(945deg); } - 100% { - -webkit-transform: rotate(1080deg); - transform: rotate(1080deg); } } - -@keyframes sporadic-rotate { - 12.5% { - -webkit-transform: rotate(135deg); - transform: rotate(135deg); } - 25% { - -webkit-transform: rotate(270deg); - transform: rotate(270deg); } - 37.5% { - -webkit-transform: rotate(405deg); - transform: rotate(405deg); } - 50% { - -webkit-transform: rotate(540deg); - transform: rotate(540deg); } - 62.5% { - -webkit-transform: rotate(675deg); - transform: rotate(675deg); } - 75% { - -webkit-transform: rotate(810deg); - transform: rotate(810deg); } - 87.5% { - -webkit-transform: rotate(945deg); - transform: rotate(945deg); } - 100% { - -webkit-transform: rotate(1080deg); - transform: rotate(1080deg); } } - -md-progress-linear { - display: block; - position: relative; - width: 100%; - height: 5px; - padding-top: 0 !important; - margin-bottom: 0 !important; } - md-progress-linear .md-container { - display: block; - position: relative; - overflow: hidden; - width: 100%; - height: 5px; - -webkit-transform: translate(0, 0) scale(1, 1); - transform: translate(0, 0) scale(1, 1); } - md-progress-linear .md-container .md-bar { - position: absolute; - left: 0; - top: 0; - bottom: 0; - width: 100%; - height: 5px; } - md-progress-linear .md-container .md-dashed:before { - content: ""; - display: none; - position: absolute; - margin-top: 0; - height: 5px; - width: 100%; - background-color: transparent; - background-size: 10px 10px !important; - background-position: 0px -23px; } - md-progress-linear .md-container .md-bar1, md-progress-linear .md-container .md-bar2 { - transition: -webkit-transform 0.2s linear; - transition: transform 0.2s linear; } - md-progress-linear .md-container.md-mode-query .md-bar1 { - display: none; } - md-progress-linear .md-container.md-mode-query .md-bar2 { - transition: all 0.2s linear; - -webkit-animation: query 0.8s infinite cubic-bezier(0.39, 0.575, 0.565, 1); - animation: query 0.8s infinite cubic-bezier(0.39, 0.575, 0.565, 1); } - md-progress-linear .md-container.md-mode-determinate .md-bar1 { - display: none; } - md-progress-linear .md-container.md-mode-indeterminate .md-bar1 { - -webkit-animation: md-progress-linear-indeterminate-scale-1 4s infinite, md-progress-linear-indeterminate-1 4s infinite; - animation: md-progress-linear-indeterminate-scale-1 4s infinite, md-progress-linear-indeterminate-1 4s infinite; } - md-progress-linear .md-container.md-mode-indeterminate .md-bar2 { - -webkit-animation: md-progress-linear-indeterminate-scale-2 4s infinite, md-progress-linear-indeterminate-2 4s infinite; - animation: md-progress-linear-indeterminate-scale-2 4s infinite, md-progress-linear-indeterminate-2 4s infinite; } - md-progress-linear .md-container.ng-hide { - -webkit-animation: none; - animation: none; } - md-progress-linear .md-container.ng-hide .md-bar1 { - -webkit-animation-name: none; - animation-name: none; } - md-progress-linear .md-container.ng-hide .md-bar2 { - -webkit-animation-name: none; - animation-name: none; } - md-progress-linear .md-container.md-mode-buffer { - background-color: transparent !important; - transition: all 0.2s linear; } - md-progress-linear .md-container.md-mode-buffer .md-dashed:before { - display: block; - -webkit-animation: buffer 3s infinite linear; - animation: buffer 3s infinite linear; } - -@-webkit-keyframes query { - 0% { - opacity: 1; - -webkit-transform: translateX(35%) scale(0.3, 1); - transform: translateX(35%) scale(0.3, 1); } - 100% { - opacity: 0; - -webkit-transform: translateX(-50%) scale(0, 1); - transform: translateX(-50%) scale(0, 1); } } - -@keyframes query { - 0% { - opacity: 1; - -webkit-transform: translateX(35%) scale(0.3, 1); - transform: translateX(35%) scale(0.3, 1); } - 100% { - opacity: 0; - -webkit-transform: translateX(-50%) scale(0, 1); - transform: translateX(-50%) scale(0, 1); } } - -@-webkit-keyframes buffer { - 0% { - opacity: 1; - background-position: 0px -23px; } - 50% { - opacity: 0; } - 100% { - opacity: 1; - background-position: -200px -23px; } } - -@keyframes buffer { - 0% { - opacity: 1; - background-position: 0px -23px; } - 50% { - opacity: 0; } - 100% { - opacity: 1; - background-position: -200px -23px; } } - -@-webkit-keyframes md-progress-linear-indeterminate-scale-1 { - 0% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); - -webkit-animation-timing-function: linear; - animation-timing-function: linear; } - 36.6% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); - -webkit-animation-timing-function: cubic-bezier(0.33473, 0.12482, 0.78584, 1); - animation-timing-function: cubic-bezier(0.33473, 0.12482, 0.78584, 1); } - 69.15% { - -webkit-transform: scaleX(0.83); - transform: scaleX(0.83); - -webkit-animation-timing-function: cubic-bezier(0.22573, 0, 0.23365, 1.37098); - animation-timing-function: cubic-bezier(0.22573, 0, 0.23365, 1.37098); } - 100% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); } } - -@keyframes md-progress-linear-indeterminate-scale-1 { - 0% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); - -webkit-animation-timing-function: linear; - animation-timing-function: linear; } - 36.6% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); - -webkit-animation-timing-function: cubic-bezier(0.33473, 0.12482, 0.78584, 1); - animation-timing-function: cubic-bezier(0.33473, 0.12482, 0.78584, 1); } - 69.15% { - -webkit-transform: scaleX(0.83); - transform: scaleX(0.83); - -webkit-animation-timing-function: cubic-bezier(0.22573, 0, 0.23365, 1.37098); - animation-timing-function: cubic-bezier(0.22573, 0, 0.23365, 1.37098); } - 100% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); } } - -@-webkit-keyframes md-progress-linear-indeterminate-1 { - 0% { - left: -105.16667%; - -webkit-animation-timing-function: linear; - animation-timing-function: linear; } - 20% { - left: -105.16667%; - -webkit-animation-timing-function: cubic-bezier(0.5, 0, 0.70173, 0.49582); - animation-timing-function: cubic-bezier(0.5, 0, 0.70173, 0.49582); } - 69.15% { - left: 21.5%; - -webkit-animation-timing-function: cubic-bezier(0.30244, 0.38135, 0.55, 0.95635); - animation-timing-function: cubic-bezier(0.30244, 0.38135, 0.55, 0.95635); } - 100% { - left: 95.44444%; } } - -@keyframes md-progress-linear-indeterminate-1 { - 0% { - left: -105.16667%; - -webkit-animation-timing-function: linear; - animation-timing-function: linear; } - 20% { - left: -105.16667%; - -webkit-animation-timing-function: cubic-bezier(0.5, 0, 0.70173, 0.49582); - animation-timing-function: cubic-bezier(0.5, 0, 0.70173, 0.49582); } - 69.15% { - left: 21.5%; - -webkit-animation-timing-function: cubic-bezier(0.30244, 0.38135, 0.55, 0.95635); - animation-timing-function: cubic-bezier(0.30244, 0.38135, 0.55, 0.95635); } - 100% { - left: 95.44444%; } } - -@-webkit-keyframes md-progress-linear-indeterminate-scale-2 { - 0% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); - -webkit-animation-timing-function: cubic-bezier(0.20503, 0.05705, 0.57661, 0.45397); - animation-timing-function: cubic-bezier(0.20503, 0.05705, 0.57661, 0.45397); } - 19.15% { - -webkit-transform: scaleX(0.57); - transform: scaleX(0.57); - -webkit-animation-timing-function: cubic-bezier(0.15231, 0.19643, 0.64837, 1.00432); - animation-timing-function: cubic-bezier(0.15231, 0.19643, 0.64837, 1.00432); } - 44.15% { - -webkit-transform: scaleX(0.91); - transform: scaleX(0.91); - -webkit-animation-timing-function: cubic-bezier(0.25776, -0.00316, 0.21176, 1.38179); - animation-timing-function: cubic-bezier(0.25776, -0.00316, 0.21176, 1.38179); } - 100% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); } } - -@keyframes md-progress-linear-indeterminate-scale-2 { - 0% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); - -webkit-animation-timing-function: cubic-bezier(0.20503, 0.05705, 0.57661, 0.45397); - animation-timing-function: cubic-bezier(0.20503, 0.05705, 0.57661, 0.45397); } - 19.15% { - -webkit-transform: scaleX(0.57); - transform: scaleX(0.57); - -webkit-animation-timing-function: cubic-bezier(0.15231, 0.19643, 0.64837, 1.00432); - animation-timing-function: cubic-bezier(0.15231, 0.19643, 0.64837, 1.00432); } - 44.15% { - -webkit-transform: scaleX(0.91); - transform: scaleX(0.91); - -webkit-animation-timing-function: cubic-bezier(0.25776, -0.00316, 0.21176, 1.38179); - animation-timing-function: cubic-bezier(0.25776, -0.00316, 0.21176, 1.38179); } - 100% { - -webkit-transform: scaleX(0.1); - transform: scaleX(0.1); } } - -@-webkit-keyframes md-progress-linear-indeterminate-2 { - 0% { - left: -54.88889%; - -webkit-animation-timing-function: cubic-bezier(0.15, 0, 0.51506, 0.40968); - animation-timing-function: cubic-bezier(0.15, 0, 0.51506, 0.40968); } - 25% { - left: -17.25%; - -webkit-animation-timing-function: cubic-bezier(0.31033, 0.28406, 0.8, 0.73372); - animation-timing-function: cubic-bezier(0.31033, 0.28406, 0.8, 0.73372); } - 48.35% { - left: 29.5%; - -webkit-animation-timing-function: cubic-bezier(0.4, 0.62703, 0.6, 0.90203); - animation-timing-function: cubic-bezier(0.4, 0.62703, 0.6, 0.90203); } - 100% { - left: 117.38889%; } } - -@keyframes md-progress-linear-indeterminate-2 { - 0% { - left: -54.88889%; - -webkit-animation-timing-function: cubic-bezier(0.15, 0, 0.51506, 0.40968); - animation-timing-function: cubic-bezier(0.15, 0, 0.51506, 0.40968); } - 25% { - left: -17.25%; - -webkit-animation-timing-function: cubic-bezier(0.31033, 0.28406, 0.8, 0.73372); - animation-timing-function: cubic-bezier(0.31033, 0.28406, 0.8, 0.73372); } - 48.35% { - left: 29.5%; - -webkit-animation-timing-function: cubic-bezier(0.4, 0.62703, 0.6, 0.90203); - animation-timing-function: cubic-bezier(0.4, 0.62703, 0.6, 0.90203); } - 100% { - left: 117.38889%; } } - -md-radio-button { - box-sizing: border-box; - display: block; - margin-bottom: 16px; - white-space: nowrap; - cursor: pointer; - position: relative; } - md-radio-button[disabled] { - cursor: default; } - md-radio-button[disabled] .md-container { - cursor: default; } - md-radio-button .md-container { - position: absolute; - top: 50%; - -webkit-transform: translateY(-50%); - transform: translateY(-50%); - box-sizing: border-box; - display: inline-block; - width: 20px; - height: 20px; - cursor: pointer; - left: 0; - right: auto; } - html[dir=rtl] md-radio-button .md-container { - left: auto; - unicode-bidi: embed; } - body[dir=rtl] md-radio-button .md-container { - left: auto; - unicode-bidi: embed; } - md-radio-button .md-container bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-radio-button .md-container bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-radio-button .md-container { - right: 0; - unicode-bidi: embed; } - body[dir=rtl] md-radio-button .md-container { - right: 0; - unicode-bidi: embed; } - md-radio-button .md-container bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-radio-button .md-container bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-radio-button .md-container .md-ripple-container { - position: absolute; - display: block; - width: auto; - height: auto; - left: -15px; - top: -15px; - right: -15px; - bottom: -15px; } - md-radio-button .md-container:before { - box-sizing: border-box; - background-color: transparent; - border-radius: 50%; - content: ''; - position: absolute; - display: block; - height: auto; - left: 0; - top: 0; - right: 0; - bottom: 0; - transition: all 0.5s; - width: auto; } - md-radio-button.md-align-top-left > div.md-container { - top: 12px; } - md-radio-button .md-off { - box-sizing: border-box; - position: absolute; - top: 0; - left: 0; - width: 20px; - height: 20px; - border-style: solid; - border-width: 2px; - border-radius: 50%; - transition: border-color ease 0.28s; } - md-radio-button .md-on { - box-sizing: border-box; - position: absolute; - top: 0; - left: 0; - width: 20px; - height: 20px; - border-radius: 50%; - transition: -webkit-transform ease 0.28s; - transition: transform ease 0.28s; - -webkit-transform: scale(0); - transform: scale(0); } - md-radio-button.md-checked .md-on { - -webkit-transform: scale(0.5); - transform: scale(0.5); } - md-radio-button .md-label { - box-sizing: border-box; - position: relative; - display: inline-block; - margin-left: 30px; - margin-right: 0; - vertical-align: middle; - white-space: normal; - pointer-events: none; - width: auto; } - html[dir=rtl] md-radio-button .md-label { - margin-left: 0; - unicode-bidi: embed; } - body[dir=rtl] md-radio-button .md-label { - margin-left: 0; - unicode-bidi: embed; } - md-radio-button .md-label bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-radio-button .md-label bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-radio-button .md-label { - margin-right: 30px; - unicode-bidi: embed; } - body[dir=rtl] md-radio-button .md-label { - margin-right: 30px; - unicode-bidi: embed; } - md-radio-button .md-label bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-radio-button .md-label bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-radio-button .circle { - border-radius: 50%; } - -md-radio-group md-radio-button:not(:first-child) { - margin-top: 16px; } - -md-radio-group.layout-row md-radio-button { - margin-top: 0; - margin-bottom: 0; - margin-left: inherit; - margin-right: 16px; } - html[dir=rtl] md-radio-group.layout-row md-radio-button { - margin-left: 16px; - unicode-bidi: embed; } - body[dir=rtl] md-radio-group.layout-row md-radio-button { - margin-left: 16px; - unicode-bidi: embed; } - md-radio-group.layout-row md-radio-button bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-radio-group.layout-row md-radio-button bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-radio-group.layout-row md-radio-button { - margin-right: inherit; - unicode-bidi: embed; } - body[dir=rtl] md-radio-group.layout-row md-radio-button { - margin-right: inherit; - unicode-bidi: embed; } - md-radio-group.layout-row md-radio-button bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-radio-group.layout-row md-radio-button bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-radio-group.layout-row md-radio-button:last-of-type { - margin-left: inherit; - margin-right: 0; } - html[dir=rtl] md-radio-group.layout-row md-radio-button:last-of-type { - margin-left: 0; - unicode-bidi: embed; } - body[dir=rtl] md-radio-group.layout-row md-radio-button:last-of-type { - margin-left: 0; - unicode-bidi: embed; } - md-radio-group.layout-row md-radio-button:last-of-type bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-radio-group.layout-row md-radio-button:last-of-type bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-radio-group.layout-row md-radio-button:last-of-type { - margin-right: inherit; - unicode-bidi: embed; } - body[dir=rtl] md-radio-group.layout-row md-radio-button:last-of-type { - margin-right: inherit; - unicode-bidi: embed; } - md-radio-group.layout-row md-radio-button:last-of-type bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-radio-group.layout-row md-radio-button:last-of-type bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - -md-radio-group:focus { - outline: none; } - -md-radio-group.md-focused .md-checked .md-container:before { - left: -8px; - top: -8px; - right: -8px; - bottom: -8px; } - -.md-inline-form md-radio-group { - margin: 18px 0 19px; } - .md-inline-form md-radio-group md-radio-button { - display: inline-block; - height: 30px; - padding: 2px; - box-sizing: border-box; - margin-top: 0; - margin-bottom: 0; } - -@media screen and (-ms-high-contrast: active) { - md-radio-button.md-default-theme .md-on { - background-color: #fff; } } - -.md-select-menu-container { - position: fixed; - left: 0; - top: 0; - z-index: 90; - opacity: 0; - display: none; } - .md-select-menu-container:not(.md-clickable) { - pointer-events: none; } - .md-select-menu-container md-progress-circular { - display: table; - margin: 24px auto !important; } - .md-select-menu-container.md-active { - display: block; - opacity: 1; } - .md-select-menu-container.md-active md-select-menu { - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - transition-duration: 150ms; } - .md-select-menu-container.md-active md-select-menu > * { - opacity: 1; - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - transition-duration: 150ms; - transition-delay: 100ms; } - .md-select-menu-container.md-leave { - opacity: 0; - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - transition-duration: 250ms; } - -md-input-container > md-select { - margin: 0; - -webkit-order: 2; - -ms-flex-order: 2; - order: 2; } - -md-select { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - margin: 20px 0 26px 0; } - md-select[disabled] .md-select-value { - background-position: 0 bottom; - background-size: 4px 1px; - background-repeat: repeat-x; - margin-bottom: -1px; } - md-select:focus { - outline: none; } - md-select[disabled]:hover { - cursor: default; } - md-select:not([disabled]):hover { - cursor: pointer; } - md-select:not([disabled]).ng-invalid.ng-dirty .md-select-value { - border-bottom: 2px solid; - padding-bottom: 0; } - md-select:not([disabled]):focus .md-select-value { - border-bottom-width: 2px; - border-bottom-style: solid; - padding-bottom: 0; } - -.md-select-value { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 2px 1px; - border-bottom-width: 1px; - border-bottom-style: solid; - background-color: transparent; - position: relative; - box-sizing: content-box; - min-width: 64px; - min-height: 26px; - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; } - .md-select-value .md-text { - display: inline; } - .md-select-value *:first-child { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - -webkit-transform: translate3d(0, 2px, 0); - transform: translate3d(0, 2px, 0); } - .md-select-value .md-select-icon { - display: block; - -webkit-align-items: flex-end; - -ms-flex-align: end; - align-items: flex-end; - text-align: end; - width: 24px; - margin: 0 4px; - -webkit-transform: translate3d(0, 1px, 0); - transform: translate3d(0, 1px, 0); } - .md-select-value .md-select-icon:after { - display: block; - content: '\25BC'; - position: relative; - top: 2px; - speak: none; - -webkit-transform: scaleY(0.6) scaleX(1); - transform: scaleY(0.6) scaleX(1); } - .md-select-value.md-select-placeholder { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; - pointer-events: none; - -webkit-font-smoothing: antialiased; - padding-left: 2px; - z-index: 1; } - -md-select-menu { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); - max-height: 256px; - min-height: 48px; - overflow-y: hidden; - -webkit-transform-origin: left top; - transform-origin: left top; - -webkit-transform: scale(1); - transform: scale(1); } - md-select-menu.md-reverse { - -webkit-flex-direction: column-reverse; - -ms-flex-direction: column-reverse; - flex-direction: column-reverse; } - md-select-menu:not(.md-overflow) md-content { - padding-top: 8px; - padding-bottom: 8px; } - html[dir=rtl] md-select-menu { - -webkit-transform-origin: right top; - transform-origin: right top; - unicode-bidi: embed; } - body[dir=rtl] md-select-menu { - -webkit-transform-origin: right top; - transform-origin: right top; - unicode-bidi: embed; } - md-select-menu bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-select-menu bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-select-menu md-content { - min-width: 136px; - min-height: 48px; - max-height: 256px; - overflow-y: auto; } - md-select-menu > * { - opacity: 0; } - -md-option { - cursor: pointer; - position: relative; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - width: auto; - padding: 0 16px 0 16px; - height: 48px; } - md-option[disabled] { - cursor: default; } - md-option:focus { - outline: none; } - md-option .md-text { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - width: auto; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - font-size: 16px; } - -md-optgroup { - display: block; } - md-optgroup label { - display: block; - font-size: 14px; - text-transform: uppercase; - padding: 16px; - font-weight: 500; } - md-optgroup md-option { - padding-left: 32px; - padding-right: 32px; } - -@media screen and (-ms-high-contrast: active) { - .md-select-backdrop { - background-color: transparent; } - md-select-menu { - border: 1px solid #fff; } } - -md-sidenav { - box-sizing: border-box; - position: absolute; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - z-index: 60; - width: 320px; - max-width: 320px; - bottom: 0; - overflow: auto; } - md-sidenav ul { - list-style: none; } - md-sidenav.md-closed { - display: none; } - md-sidenav.md-closed-add, md-sidenav.md-closed-remove { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - transition: 0.2s ease-in all; } - md-sidenav.md-closed-add.md-closed-add-active, md-sidenav.md-closed-remove.md-closed-remove-active { - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); } - md-sidenav.md-locked-open-add, md-sidenav.md-locked-open-remove { - position: static; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); } - md-sidenav.md-locked-open, md-sidenav.md-locked-open.md-closed, md-sidenav.md-locked-open.md-closed.md-sidenav-left, md-sidenav.md-locked-open.md-closed, md-sidenav.md-locked-open.md-closed.md-sidenav-right, md-sidenav.md-locked-open-remove.md-closed { - position: static; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); } - md-sidenav.md-locked-open-remove-active { - transition: width 0.3s cubic-bezier(0.55, 0, 0.55, 0.2), min-width 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - width: 0; - min-width: 0; } - md-sidenav.md-closed.md-locked-open-add { - width: 0; - min-width: 0; - -webkit-transform: translate3d(0%, 0, 0); - transform: translate3d(0%, 0, 0); } - md-sidenav.md-closed.md-locked-open-add-active { - transition: width 0.3s cubic-bezier(0.55, 0, 0.55, 0.2), min-width 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); - width: 320px; - min-width: 320px; - -webkit-transform: translate3d(0%, 0, 0); - transform: translate3d(0%, 0, 0); } - -.md-sidenav-backdrop.md-locked-open { - display: none; } - -.md-sidenav-left, md-sidenav { - left: 0; - top: 0; - -webkit-transform: translate3d(0%, 0, 0); - transform: translate3d(0%, 0, 0); } - .md-sidenav-left.md-closed, md-sidenav.md-closed { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); } - -.md-sidenav-right { - left: 100%; - top: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); } - .md-sidenav-right.md-closed { - -webkit-transform: translate3d(0%, 0, 0); - transform: translate3d(0%, 0, 0); } - -@media screen and (min-width: 600px) { - md-sidenav { - max-width: 400px; } } - -@media screen and (max-width: 456px) { - md-sidenav { - width: calc(100% - 56px); - min-width: calc(100% - 56px); - max-width: calc(100% - 56px); } } - -@media screen and (-ms-high-contrast: active) { - .md-sidenav-left, md-sidenav { - border-right: 1px solid #fff; } - .md-sidenav-right { - border-left: 1px solid #fff; } } - -@-webkit-keyframes sliderFocusThumb { - 0% { - opacity: 0; - -webkit-transform: scale(0); - transform: scale(0); } - 50% { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 1; } - 100% { - opacity: 0; } } - -@keyframes sliderFocusThumb { - 0% { - opacity: 0; - -webkit-transform: scale(0); - transform: scale(0); } - 50% { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 1; } - 100% { - opacity: 0; } } - -md-slider { - height: 48px; - position: relative; - display: block; - margin-left: 4px; - margin-right: 4px; - padding: 0; - /** - * Track - */ - /** - * Slider thumb - */ - /* The sign that's focused in discrete mode */ - /** - * The border/background that comes in when focused in non-discrete mode - */ - /* Don't animate left/right while panning */ } - md-slider *, md-slider *:after { - box-sizing: border-box; } - md-slider .md-slider-wrapper { - position: relative; } - md-slider .md-track-container { - width: 100%; - position: absolute; - top: 23px; - height: 2px; } - md-slider .md-track { - position: absolute; - left: 0; - right: 0; - height: 100%; } - md-slider .md-track-fill { - transition: width 0.05s linear; } - md-slider .md-track-ticks { - position: absolute; - left: 0; - right: 0; - height: 100%; } - md-slider .md-track-ticks canvas { - width: 100%; } - md-slider .md-thumb-container { - position: absolute; - left: 0; - top: 50%; - -webkit-transform: translate3d(-50%, -50%, 0); - transform: translate3d(-50%, -50%, 0); - transition: left 0.1s linear; } - md-slider .md-thumb { - z-index: 1; - position: absolute; - left: -19px; - top: 5px; - width: 38px; - height: 38px; - border-radius: 38px; - -webkit-transform: scale(0.5); - transform: scale(0.5); - transition: all 0.1s linear; } - md-slider .md-thumb:after { - content: ''; - position: absolute; - left: 3px; - top: 3px; - width: 32px; - height: 32px; - border-radius: 32px; - border-width: 3px; - border-style: solid; } - md-slider .md-sign { - /* Center the children (slider-thumb-text) */ - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - position: absolute; - left: -14px; - top: -20px; - width: 28px; - height: 28px; - border-radius: 28px; - -webkit-transform: scale(0.4) translate3d(0, 70px, 0); - transform: scale(0.4) translate3d(0, 70px, 0); - transition: all 0.2s ease-in-out; - /* The arrow pointing down under the sign */ } - md-slider .md-sign:after { - position: absolute; - content: ''; - left: 0px; - border-radius: 16px; - top: 19px; - border-left: 14px solid transparent; - border-right: 14px solid transparent; - border-top-width: 16px; - border-top-style: solid; - opacity: 0; - -webkit-transform: translate3d(0, -8px, 0); - transform: translate3d(0, -8px, 0); - transition: all 0.2s ease-in-out; } - md-slider .md-sign .md-thumb-text { - z-index: 1; - font-size: 12px; - font-weight: bold; } - md-slider .md-focus-thumb { - position: absolute; - left: -24px; - top: 0px; - width: 48px; - height: 48px; - border-radius: 48px; - display: none; - opacity: 0; - background-color: #C0C0C0; - -webkit-animation: sliderFocusThumb 0.4s linear; - animation: sliderFocusThumb 0.4s linear; } - md-slider .md-focus-ring { - position: absolute; - left: -24px; - top: 0px; - width: 48px; - height: 48px; - border-radius: 48px; - -webkit-transform: scale(0); - transform: scale(0); - transition: all 0.2s linear; - opacity: 0.26; } - md-slider .md-disabled-thumb { - position: absolute; - left: -22px; - top: 2px; - width: 44px; - height: 44px; - border-radius: 44px; - -webkit-transform: scale(0.35); - transform: scale(0.35); - border-width: 6px; - border-style: solid; - display: none; } - md-slider.md-min .md-thumb:after { - background-color: white; } - md-slider.md-min .md-sign { - opacity: 0; } - md-slider:focus { - outline: none; } - md-slider.md-dragging .md-thumb-container, - md-slider.md-dragging .md-track-fill { - transition: none; } - md-slider:not([md-discrete]) { - /* Hide the sign and ticks in non-discrete mode */ } - md-slider:not([md-discrete]) .md-track-ticks, - md-slider:not([md-discrete]) .md-sign { - display: none; } - md-slider:not([md-discrete]):not([disabled]):hover .md-thumb { - -webkit-transform: scale(0.6); - transform: scale(0.6); } - md-slider:not([md-discrete]):not([disabled]):focus .md-focus-thumb, md-slider:not([md-discrete]):not([disabled]).md-active .md-focus-thumb { - display: block; } - md-slider:not([md-discrete]):not([disabled]):focus .md-focus-ring, md-slider:not([md-discrete]):not([disabled]).md-active .md-focus-ring { - -webkit-transform: scale(1); - transform: scale(1); } - md-slider:not([md-discrete]):not([disabled]):focus .md-thumb, md-slider:not([md-discrete]):not([disabled]).md-active .md-thumb { - -webkit-transform: scale(0.85); - transform: scale(0.85); } - md-slider[md-discrete] { - /* Hide the focus thumb in discrete mode */ } - md-slider[md-discrete] .md-focus-thumb, - md-slider[md-discrete] .md-focus-ring { - display: none; } - md-slider[md-discrete]:not([disabled]):focus .md-sign, - md-slider[md-discrete]:not([disabled]):focus .md-sign:after, md-slider[md-discrete]:not([disabled]).md-active .md-sign, - md-slider[md-discrete]:not([disabled]).md-active .md-sign:after { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0) scale(1); - transform: translate3d(0, 0, 0) scale(1); } - md-slider[disabled] .md-track-fill { - display: none; } - md-slider[disabled] .md-sign { - display: none; } - md-slider[disabled] .md-thumb { - -webkit-transform: scale(0.35); - transform: scale(0.35); } - md-slider[disabled] .md-disabled-thumb { - display: block; } - -@media screen and (-ms-high-contrast: active) { - md-slider.md-default-theme .md-track { - border-bottom: 1px solid #fff; } } - -.md-sticky-clone { - z-index: 2; - top: 0; - left: 0; - right: 0; - position: absolute !important; - -webkit-transform: translate3d(-9999px, -9999px, 0); - transform: translate3d(-9999px, -9999px, 0); } - .md-sticky-clone[sticky-state="active"] { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); } - .md-sticky-clone[sticky-state="active"]:not(.md-sticky-no-effect) .md-subheader-inner { - -webkit-animation: subheaderStickyHoverIn 0.3s ease-out both; - animation: subheaderStickyHoverIn 0.3s ease-out both; } - -@-webkit-keyframes subheaderStickyHoverIn { - 0% { - box-shadow: 0 0 0 0 transparent; } - 100% { - box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.16); } } - -@keyframes subheaderStickyHoverIn { - 0% { - box-shadow: 0 0 0 0 transparent; } - 100% { - box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.16); } } - -@-webkit-keyframes subheaderStickyHoverOut { - 0% { - box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.16); } - 100% { - box-shadow: 0 0 0 0 transparent; } } - -@keyframes subheaderStickyHoverOut { - 0% { - box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.16); } - 100% { - box-shadow: 0 0 0 0 transparent; } } - -.md-subheader-wrapper:not(.md-sticky-no-effect) { - transition: 0.2s ease-out margin; } - .md-subheader-wrapper:not(.md-sticky-no-effect) .md-subheader { - margin: 0; } - .md-subheader-wrapper:not(.md-sticky-no-effect).md-sticky-clone { - z-index: 2; } - .md-subheader-wrapper:not(.md-sticky-no-effect)[sticky-state="active"] { - margin-top: -2px; } - .md-subheader-wrapper:not(.md-sticky-no-effect):not(.md-sticky-clone)[sticky-prev-state="active"] .md-subheader-inner:after { - -webkit-animation: subheaderStickyHoverOut 0.3s ease-out both; - animation: subheaderStickyHoverOut 0.3s ease-out both; } - -.md-subheader { - display: block; - font-size: 14px; - font-weight: 500; - line-height: 1em; - margin: 0 0 0 0; - position: relative; } - .md-subheader .md-subheader-inner { - display: block; - padding: 16px; } - .md-subheader .md-subheader-content { - display: block; - z-index: 1; - position: relative; } - -.md-inline-form md-switch { - margin-top: 18px; - margin-bottom: 19px; } - -md-switch { - margin: 16px 0; - white-space: nowrap; - cursor: pointer; - outline: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - height: 30px; - line-height: 28px; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - margin-left: inherit; - margin-right: 16px; } - html[dir=rtl] md-switch { - margin-left: 16px; - unicode-bidi: embed; } - body[dir=rtl] md-switch { - margin-left: 16px; - unicode-bidi: embed; } - md-switch bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-switch bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-switch { - margin-right: inherit; - unicode-bidi: embed; } - body[dir=rtl] md-switch { - margin-right: inherit; - unicode-bidi: embed; } - md-switch bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-switch bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-switch:last-of-type { - margin-left: inherit; - margin-right: 0; } - html[dir=rtl] md-switch:last-of-type { - margin-left: 0; - unicode-bidi: embed; } - body[dir=rtl] md-switch:last-of-type { - margin-left: 0; - unicode-bidi: embed; } - md-switch:last-of-type bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-switch:last-of-type bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - html[dir=rtl] md-switch:last-of-type { - margin-right: inherit; - unicode-bidi: embed; } - body[dir=rtl] md-switch:last-of-type { - margin-right: inherit; - unicode-bidi: embed; } - md-switch:last-of-type bdo[dir=rtl] { - direction: rtl; - unicode-bidi: bidi-override; } - md-switch:last-of-type bdo[dir=ltr] { - direction: ltr; - unicode-bidi: bidi-override; } - md-switch[disabled] { - cursor: default; } - md-switch[disabled] .md-container { - cursor: default; } - md-switch .md-container { - cursor: -webkit-grab; - cursor: grab; - width: 36px; - height: 24px; - position: relative; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - margin-right: 8px; - float: left; } - md-switch:not([disabled]) .md-dragging, - md-switch:not([disabled]).md-dragging .md-container { - cursor: -webkit-grabbing; - cursor: grabbing; } - md-switch.md-focused:not([disabled]) .md-thumb:before { - left: -8px; - top: -8px; - right: -8px; - bottom: -8px; } - md-switch.md-focused:not([disabled]):not(.md-checked) .md-thumb:before { - background-color: rgba(0, 0, 0, 0.12); } - md-switch .md-label { - border-color: transparent; - border-width: 0; - float: left; } - md-switch .md-bar { - left: 1px; - width: 34px; - top: 5px; - height: 14px; - border-radius: 8px; - position: absolute; } - md-switch .md-thumb-container { - top: 2px; - left: 0; - width: 16px; - position: absolute; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - z-index: 1; } - md-switch.md-checked .md-thumb-container { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); } - md-switch .md-thumb { - position: absolute; - margin: 0; - left: 0; - top: 0; - outline: none; - height: 20px; - width: 20px; - border-radius: 50%; - box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); } - md-switch .md-thumb:before { - background-color: transparent; - border-radius: 50%; - content: ''; - position: absolute; - display: block; - height: auto; - left: 0; - top: 0; - right: 0; - bottom: 0; - transition: all 0.5s; - width: auto; } - md-switch .md-thumb .md-ripple-container { - position: absolute; - display: block; - width: auto; - height: auto; - left: -20px; - top: -20px; - right: -20px; - bottom: -20px; } - md-switch:not(.md-dragging) .md-bar, - md-switch:not(.md-dragging) .md-thumb-container, - md-switch:not(.md-dragging) .md-thumb { - transition: all 0.08s linear; - transition-property: -webkit-transform, background-color; - transition-property: transform, background-color; } - md-switch:not(.md-dragging) .md-bar, - md-switch:not(.md-dragging) .md-thumb { - transition-delay: 0.05s; } - -@media screen and (-ms-high-contrast: active) { - md-switch.md-default-theme .md-bar { - background-color: #666; } - md-switch.md-default-theme.md-checked .md-bar { - background-color: #9E9E9E; } - md-switch.md-default-theme .md-thumb { - background-color: #fff; } } - -@-webkit-keyframes md-tab-content-hide { - 0% { - opacity: 1; } - 50% { - opacity: 1; } - 100% { - opacity: 0; } } - -@keyframes md-tab-content-hide { - 0% { - opacity: 1; } - 50% { - opacity: 1; } - 100% { - opacity: 0; } } - -md-tab-data { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: -1; - opacity: 0; } - -md-tabs { - display: block; - margin: 0; - border-radius: 2px; - overflow: hidden; - position: relative; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; } - md-tabs:not(.md-no-tab-content):not(.md-dynamic-height) { - min-height: 248px; } - md-tabs[md-align-tabs="bottom"] { - padding-bottom: 48px; } - md-tabs[md-align-tabs="bottom"] md-tabs-wrapper { - position: absolute; - bottom: 0; - left: 0; - right: 0; - height: 48px; - z-index: 2; } - md-tabs[md-align-tabs="bottom"] md-tabs-content-wrapper { - top: 0; - bottom: 48px; } - md-tabs.md-dynamic-height md-tabs-content-wrapper { - min-height: 0; - position: relative; - top: auto; - left: auto; - right: auto; - bottom: auto; - overflow: visible; } - md-tabs.md-dynamic-height md-tab-content.md-active { - position: relative; } - md-tabs[md-border-bottom] md-tabs-wrapper { - border-width: 0 0 1px; - border-style: solid; } - md-tabs[md-border-bottom]:not(.md-dynamic-height) md-tabs-content-wrapper { - top: 49px; } - -md-tabs-wrapper { - display: block; - position: relative; } - md-tabs-wrapper md-prev-button, md-tabs-wrapper md-next-button { - height: 100%; - width: 32px; - position: absolute; - top: 50%; - -webkit-transform: translateY(-50%); - transform: translateY(-50%); - line-height: 1em; - z-index: 2; - cursor: pointer; - font-size: 16px; - background: transparent no-repeat center center; - transition: all 0.5s cubic-bezier(0.35, 0, 0.25, 1); } - md-tabs-wrapper md-prev-button:focus, md-tabs-wrapper md-next-button:focus { - outline: none; } - md-tabs-wrapper md-prev-button.md-disabled, md-tabs-wrapper md-next-button.md-disabled { - opacity: 0.25; - cursor: default; } - md-tabs-wrapper md-prev-button.ng-leave, md-tabs-wrapper md-next-button.ng-leave { - transition: none; } - md-tabs-wrapper md-prev-button md-icon, md-tabs-wrapper md-next-button md-icon { - position: absolute; - top: 50%; - left: 50%; - -webkit-transform: translate3d(-50%, -50%, 0); - transform: translate3d(-50%, -50%, 0); } - md-tabs-wrapper md-prev-button { - left: 0; - background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE3LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPiA8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPiA8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjQgMjQiIHhtbDpzcGFjZT0icHJlc2VydmUiPiA8ZyBpZD0iSGVhZGVyIj4gPGc+IDxyZWN0IHg9Ii02MTgiIHk9Ii0xMjA4IiBmaWxsPSJub25lIiB3aWR0aD0iMTQwMCIgaGVpZ2h0PSIzNjAwIi8+IDwvZz4gPC9nPiA8ZyBpZD0iTGFiZWwiPiA8L2c+IDxnIGlkPSJJY29uIj4gPGc+IDxwb2x5Z29uIHBvaW50cz0iMTUuNCw3LjQgMTQsNiA4LDEyIDE0LDE4IDE1LjQsMTYuNiAxMC44LDEyIAkJIiBzdHlsZT0iZmlsbDp3aGl0ZTsiLz4gPHJlY3QgZmlsbD0ibm9uZSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ii8+IDwvZz4gPC9nPiA8ZyBpZD0iR3JpZCIgZGlzcGxheT0ibm9uZSI+IDxnIGRpc3BsYXk9ImlubGluZSI+IDwvZz4gPC9nPiA8L3N2Zz4NCg=="); } - md-tabs-wrapper md-next-button { - right: 0; - background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE3LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPiA8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPiA8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjQgMjQiIHhtbDpzcGFjZT0icHJlc2VydmUiPiA8ZyBpZD0iSGVhZGVyIj4gPGc+IDxyZWN0IHg9Ii02MTgiIHk9Ii0xMzM2IiBmaWxsPSJub25lIiB3aWR0aD0iMTQwMCIgaGVpZ2h0PSIzNjAwIi8+IDwvZz4gPC9nPiA8ZyBpZD0iTGFiZWwiPiA8L2c+IDxnIGlkPSJJY29uIj4gPGc+IDxwb2x5Z29uIHBvaW50cz0iMTAsNiA4LjYsNy40IDEzLjIsMTIgOC42LDE2LjYgMTAsMTggMTYsMTIgCQkiIHN0eWxlPSJmaWxsOndoaXRlOyIvPiA8cmVjdCBmaWxsPSJub25lIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiLz4gPC9nPiA8L2c+IDxnIGlkPSJHcmlkIiBkaXNwbGF5PSJub25lIj4gPGcgZGlzcGxheT0iaW5saW5lIj4gPC9nPiA8L2c+IDwvc3ZnPg0K"); } - md-tabs-wrapper md-next-button md-icon { - -webkit-transform: translate3d(-50%, -50%, 0) rotate(180deg); - transform: translate3d(-50%, -50%, 0) rotate(180deg); } - md-tabs-wrapper.md-stretch-tabs md-pagination-wrapper { - width: 100%; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; } - md-tabs-wrapper.md-stretch-tabs md-pagination-wrapper md-tab-item { - -webkit-flex-grow: 1; - -ms-flex-positive: 1; - flex-grow: 1; } - -md-tabs-canvas { - position: relative; - overflow: hidden; - display: block; - height: 48px; } - md-tabs-canvas:after { - content: ''; - display: table; - clear: both; } - md-tabs-canvas .md-dummy-wrapper { - position: absolute; - top: 0; - left: 0; } - md-tabs-canvas.md-paginated { - margin: 0 32px; } - md-tabs-canvas.md-center-tabs { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - text-align: center; } - md-tabs-canvas.md-center-tabs .md-tab { - float: none; - display: inline-block; } - -md-pagination-wrapper { - height: 48px; - display: block; - transition: -webkit-transform 0.5s cubic-bezier(0.35, 0, 0.25, 1); - transition: transform 0.5s cubic-bezier(0.35, 0, 0.25, 1); - position: absolute; - width: 999999px; - left: 0; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); } - md-pagination-wrapper:after { - content: ''; - display: table; - clear: both; } - md-pagination-wrapper.md-center-tabs { - position: relative; - width: initial; - margin: 0 auto; } - -md-tabs-content-wrapper { - display: block; - position: absolute; - top: 48px; - left: 0; - right: 0; - bottom: 0; - overflow: hidden; } - -md-tab-content { - display: block; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - transition: -webkit-transform 0.5s cubic-bezier(0.35, 0, 0.25, 1); - transition: transform 0.5s cubic-bezier(0.35, 0, 0.25, 1); - overflow: auto; } - md-tab-content.md-no-scroll { - bottom: auto; - overflow: hidden; } - md-tab-content.ng-leave, md-tab-content.md-no-transition { - transition: none; } - md-tab-content.md-left:not(.md-active) { - -webkit-transform: translateX(-100%); - transform: translateX(-100%); - -webkit-animation: 1s md-tab-content-hide; - animation: 1s md-tab-content-hide; - opacity: 0; } - md-tab-content.md-left:not(.md-active) * { - transition: visibility 0s linear; - transition-delay: 0.5s; - visibility: hidden; } - md-tab-content.md-right:not(.md-active) { - -webkit-transform: translateX(100%); - transform: translateX(100%); - -webkit-animation: 1s md-tab-content-hide; - animation: 1s md-tab-content-hide; - opacity: 0; } - md-tab-content.md-right:not(.md-active) * { - transition: visibility 0s linear; - transition-delay: 0.5s; - visibility: hidden; } - md-tab-content > div.ng-leave { - -webkit-animation: 1s md-tab-content-hide; - animation: 1s md-tab-content-hide; } - -md-ink-bar { - position: absolute; - left: auto; - right: auto; - bottom: 0; - height: 2px; } - md-ink-bar.md-left { - transition: left 0.125s cubic-bezier(0.35, 0, 0.25, 1), right 0.25s cubic-bezier(0.35, 0, 0.25, 1); } - md-ink-bar.md-right { - transition: left 0.25s cubic-bezier(0.35, 0, 0.25, 1), right 0.125s cubic-bezier(0.35, 0, 0.25, 1); } - -md-tab { - position: absolute; - z-index: -1; - left: -9999px; } - -.md-tab { - font-size: 14px; - text-align: center; - line-height: 24px; - padding: 12px 24px; - transition: background-color 0.35s cubic-bezier(0.35, 0, 0.25, 1); - cursor: pointer; - white-space: nowrap; - position: relative; - text-transform: uppercase; - float: left; - font-weight: 500; - box-sizing: border-box; - overflow: hidden; - text-overflow: ellipsis; } - .md-tab.md-focused { - box-shadow: none; - outline: none; } - .md-tab.md-active { - cursor: default; } - .md-tab.md-disabled { - pointer-events: none; - -ms-touch-action: pan-y; - touch-action: pan-y; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - -webkit-user-drag: none; - opacity: 0.5; - cursor: default; } - .md-tab.ng-leave { - transition: none; } - -md-toolbar + md-tabs { - border-top-left-radius: 0; - border-top-right-radius: 0; } - -md-toast { - position: absolute; - z-index: 105; - box-sizing: border-box; - cursor: default; - overflow: hidden; - padding: 8px; - opacity: 1; - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - /* Transition differently when swiping */ - /* - * When the toast doesn't take up the whole screen, - * make it rotate when the user swipes it away - */ } - md-toast .md-toast-content { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - height: 0; - max-height: 168px; - max-width: 100%; - min-height: 48px; - padding-left: 24px; - padding-right: 24px; - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); - border-radius: 2px; - font-size: 14px; - overflow: hidden; - -webkit-transform: translate3d(0, 0, 0) rotateZ(0deg); - transform: translate3d(0, 0, 0) rotateZ(0deg); - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); } - md-toast.md-capsule { - border-radius: 24px; } - md-toast.md-capsule .md-toast-content { - border-radius: 24px; } - md-toast.ng-leave-active .md-toast-content { - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } - md-toast.md-swipeleft .md-toast-content, md-toast.md-swiperight .md-toast-content, md-toast.md-swipeup .md-toast-content, md-toast.md-swipedown .md-toast-content { - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); } - md-toast.ng-enter { - opacity: 0; } - md-toast.ng-enter .md-toast-content { - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); } - md-toast.ng-enter.md-top .md-toast-content { - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); } - md-toast.ng-enter.ng-enter-active { - opacity: 1; } - md-toast.ng-enter.ng-enter-active .md-toast-content { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); } - md-toast.ng-leave.ng-leave-active .md-toast-content { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); } - md-toast.ng-leave.ng-leave-active.md-swipeup .md-toast-content { - -webkit-transform: translate3d(0, -50%, 0); - transform: translate3d(0, -50%, 0); } - md-toast.ng-leave.ng-leave-active.md-swipedown .md-toast-content { - -webkit-transform: translate3d(0, 50%, 0); - transform: translate3d(0, 50%, 0); } - md-toast.ng-leave.ng-leave-active.md-top .md-toast-content { - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); } - md-toast .md-action { - line-height: 19px; - margin-left: 24px; - margin-right: 0; - cursor: pointer; - text-transform: uppercase; - float: right; } - md-toast .md-action.md-button { - min-width: 0; } - -@media (max-width: 959px) { - md-toast { - left: 0; - right: 0; - width: 100%; - max-width: 100%; - min-width: 0; - border-radius: 0; - bottom: 0; } - md-toast.ng-leave.ng-leave-active.md-swipeup .md-toast-content { - -webkit-transform: translate3d(0, -50%, 0); - transform: translate3d(0, -50%, 0); } - md-toast.ng-leave.ng-leave-active.md-swipedown .md-toast-content { - -webkit-transform: translate3d(0, 50%, 0); - transform: translate3d(0, 50%, 0); } } - -@media (min-width: 960px) { - md-toast { - min-width: 304px; - /* - * When the toast doesn't take up the whole screen, - * make it rotate when the user swipes it away - */ } - md-toast.md-bottom { - bottom: 0; } - md-toast.md-left { - left: 0; } - md-toast.md-right { - right: 0; } - md-toast.md-top { - top: 0; } - md-toast.ng-leave.ng-leave-active.md-swipeleft .md-toast-content { - -webkit-transform: translate3d(-50%, 0, 0); - transform: translate3d(-50%, 0, 0); } - md-toast.ng-leave.ng-leave-active.md-swiperight .md-toast-content { - -webkit-transform: translate3d(50%, 0, 0); - transform: translate3d(50%, 0, 0); } } - -@media (min-width: 1920px) { - md-toast .md-toast-content { - max-width: 568px; } } - -@media screen and (-ms-high-contrast: active) { - md-toast { - border: 1px solid #fff; } } - -.md-toast-animating { - overflow: hidden !important; } - -md-toolbar { - box-sizing: border-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - position: relative; - z-index: 2; - font-size: 20px; - min-height: 64px; - width: 100%; } - md-toolbar.md-whiteframe-z1-add, md-toolbar.md-whiteframe-z1-remove { - transition: box-shadow 0.5s linear; } - md-toolbar md-toolbar-filler { - width: 72px; } - md-toolbar *, - md-toolbar *:before, - md-toolbar *:after { - box-sizing: border-box; } - md-toolbar.md-tall { - height: 128px; - min-height: 128px; - max-height: 128px; } - md-toolbar.md-medium-tall { - height: 88px; - min-height: 88px; - max-height: 88px; } - md-toolbar.md-medium-tall .md-toolbar-tools { - height: 48px; - min-height: 48px; - max-height: 48px; } - md-toolbar > .md-indent { - margin-left: 64px; } - md-toolbar ~ md-content > md-list { - padding: 0; } - md-toolbar ~ md-content > md-list md-list-item:last-child md-divider { - display: none; } - -.md-toolbar-tools { - font-size: 20px; - letter-spacing: 0.005em; - box-sizing: border-box; - font-weight: 400; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - width: 100%; - height: 64px; - max-height: 64px; - padding: 0 16px; - margin: 0; } - .md-toolbar-tools h1, .md-toolbar-tools h2, .md-toolbar-tools h3 { - font-size: inherit; - font-weight: inherit; - margin: inherit; } - .md-toolbar-tools a { - color: inherit; - text-decoration: none; } - .md-toolbar-tools .fill-height { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; } - .md-toolbar-tools .md-button { - margin-top: 0; - margin-bottom: 0; } - .md-toolbar-tools > .md-button:first-child { - margin-left: -8px; } - .md-toolbar-tools > .md-button:last-child { - margin-right: -8px; } - .md-toolbar-tools > md-menu:last-child { - margin-right: -8px; } - .md-toolbar-tools > md-menu:last-child > .md-button { - margin-right: 0; } - @media screen and (-ms-high-contrast: active) { - .md-toolbar-tools { - border-bottom: 1px solid #fff; } } - -@media only screen and (min-width: 0) and (max-width: 959px) and (orientation: portrait) { - md-toolbar { - min-height: 56px; } - .md-toolbar-tools { - height: 56px; - max-height: 56px; } } - -@media only screen and (min-width: 0) and (max-width: 959px) and (orientation: landscape) { - md-toolbar { - min-height: 48px; } - .md-toolbar-tools { - height: 48px; - max-height: 48px; } } - -md-tooltip { - position: absolute; - z-index: 100; - overflow: hidden; - pointer-events: none; - border-radius: 4px; - font-weight: 500; - font-size: 14px; } - @media screen and (min-width: 960px) { - md-tooltip { - font-size: 10px; } } - md-tooltip .md-content { - position: relative; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - -webkit-transform-origin: center top; - transform-origin: center top; - -webkit-transform: scale(0); - transform: scale(0); - opacity: 0; - height: 32px; - line-height: 32px; - padding-left: 16px; - padding-right: 16px; } - @media screen and (min-width: 960px) { - md-tooltip .md-content { - height: 22px; - line-height: 22px; - padding-left: 8px; - padding-right: 8px; } } - md-tooltip .md-content.md-show-add { - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - transition-duration: .2s; - -webkit-transform: scale(0); - transform: scale(0); - opacity: 0; } - md-tooltip .md-content.md-show, md-tooltip .md-content.md-show-add-active { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 1; - -webkit-transform-origin: center top; - transform-origin: center top; } - md-tooltip .md-content.md-show-remove { - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - transition-duration: .2s; } - md-tooltip .md-content.md-show-remove.md-show-remove-active { - -webkit-transform: scale(0); - transform: scale(0); - opacity: 0; } - md-tooltip.md-hide { - transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); } - md-tooltip.md-show { - transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); - pointer-events: auto; - will-change: opacity, height, width; } - -.md-virtual-repeat-container { - box-sizing: border-box; - display: block; - margin: 0; - overflow: hidden; - padding: 0; - position: relative; } - .md-virtual-repeat-container .md-virtual-repeat-scroller { - bottom: 0; - box-sizing: border-box; - left: 0; - margin: 0; - overflow-x: hidden; - padding: 0; - position: absolute; - right: 0; - top: 0; } - .md-virtual-repeat-container .md-virtual-repeat-sizer { - box-sizing: border-box; - height: 1px; - display: block; - margin: 0; - padding: 0; - width: 1px; } - .md-virtual-repeat-container .md-virtual-repeat-offsetter { - box-sizing: border-box; - left: 0; - margin: 0; - padding: 0; - position: absolute; - right: 0; - top: 0; } - -.md-virtual-repeat-container.md-orient-horizontal .md-virtual-repeat-scroller { - overflow-x: auto; - overflow-y: hidden; } - -.md-virtual-repeat-container.md-orient-horizontal .md-virtual-repeat-offsetter { - bottom: 16px; - right: auto; - white-space: nowrap; } - -.md-whiteframe-1dp, .md-whiteframe-z1 { - box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-2dp { - box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 3px 1px -2px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-3dp { - box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.2), 0px 3px 4px 0px rgba(0, 0, 0, 0.14), 0px 3px 3px -2px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-4dp, .md-whiteframe-z2 { - box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2), 0px 4px 5px 0px rgba(0, 0, 0, 0.14), 0px 1px 10px 0px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-5dp { - box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 5px 8px 0px rgba(0, 0, 0, 0.14), 0px 1px 14px 0px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-6dp { - box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2), 0px 6px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 18px 0px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-7dp, .md-whiteframe-z3 { - box-shadow: 0px 4px 5px -2px rgba(0, 0, 0, 0.2), 0px 7px 10px 1px rgba(0, 0, 0, 0.14), 0px 2px 16px 1px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-8dp { - box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2), 0px 8px 10px 1px rgba(0, 0, 0, 0.14), 0px 3px 14px 2px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-9dp { - box-shadow: 0px 5px 6px -3px rgba(0, 0, 0, 0.2), 0px 9px 12px 1px rgba(0, 0, 0, 0.14), 0px 3px 16px 2px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-10dp, .md-whiteframe-z4 { - box-shadow: 0px 6px 6px -3px rgba(0, 0, 0, 0.2), 0px 10px 14px 1px rgba(0, 0, 0, 0.14), 0px 4px 18px 3px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-11dp { - box-shadow: 0px 6px 7px -4px rgba(0, 0, 0, 0.2), 0px 11px 15px 1px rgba(0, 0, 0, 0.14), 0px 4px 20px 3px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-12dp { - box-shadow: 0px 7px 8px -4px rgba(0, 0, 0, 0.2), 0px 12px 17px 2px rgba(0, 0, 0, 0.14), 0px 5px 22px 4px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-13dp, .md-whiteframe-z5 { - box-shadow: 0px 7px 8px -4px rgba(0, 0, 0, 0.2), 0px 13px 19px 2px rgba(0, 0, 0, 0.14), 0px 5px 24px 4px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-14dp { - box-shadow: 0px 7px 9px -4px rgba(0, 0, 0, 0.2), 0px 14px 21px 2px rgba(0, 0, 0, 0.14), 0px 5px 26px 4px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-15dp { - box-shadow: 0px 8px 9px -5px rgba(0, 0, 0, 0.2), 0px 15px 22px 2px rgba(0, 0, 0, 0.14), 0px 6px 28px 5px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-16dp { - box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, 0.2), 0px 16px 24px 2px rgba(0, 0, 0, 0.14), 0px 6px 30px 5px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-17dp { - box-shadow: 0px 8px 11px -5px rgba(0, 0, 0, 0.2), 0px 17px 26px 2px rgba(0, 0, 0, 0.14), 0px 6px 32px 5px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-18dp { - box-shadow: 0px 9px 11px -5px rgba(0, 0, 0, 0.2), 0px 18px 28px 2px rgba(0, 0, 0, 0.14), 0px 7px 34px 6px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-19dp { - box-shadow: 0px 9px 12px -6px rgba(0, 0, 0, 0.2), 0px 19px 29px 2px rgba(0, 0, 0, 0.14), 0px 7px 36px 6px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-20dp { - box-shadow: 0px 10px 13px -6px rgba(0, 0, 0, 0.2), 0px 20px 31px 3px rgba(0, 0, 0, 0.14), 0px 8px 38px 7px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-21dp { - box-shadow: 0px 10px 13px -6px rgba(0, 0, 0, 0.2), 0px 21px 33px 3px rgba(0, 0, 0, 0.14), 0px 8px 40px 7px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-22dp { - box-shadow: 0px 10px 14px -6px rgba(0, 0, 0, 0.2), 0px 22px 35px 3px rgba(0, 0, 0, 0.14), 0px 8px 42px 7px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-23dp { - box-shadow: 0px 11px 14px -7px rgba(0, 0, 0, 0.2), 0px 23px 36px 3px rgba(0, 0, 0, 0.14), 0px 9px 44px 8px rgba(0, 0, 0, 0.12); } - -.md-whiteframe-24dp { - box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12); } - -@media screen and (-ms-high-contrast: active) { - md-whiteframe { - border: 1px solid #fff; } } - -md-card > md-data-table-toolbar:first-child, -md-card > md-data-table-container:first-child { - border-top-left-radius: 2px; - border-top-right-radius: 2px; -} -md-card > md-data-table-toolbar:last-child, -md-card > md-data-table-container:last-child, -md-card > md-data-table-pagination:last-child { - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; -} -md-data-table-toolbar { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - padding: 0 24px; - height: 64px; - background-color: #fff; - box-sizing: border-box; -} -md-data-table-toolbar > .md-title { - font-size: 20px; -} -md-data-table-toolbar > .md-button:first-child { - margin-left: -6px; -} -md-data-table-toolbar > .md-button:last-child { - margin-right: -6px; -} -md-data-table-container ~ md-data-table-toolbar { - height: 56px; - border-top: 1px rgba(0, 0, 0, 0.12) solid; - font-size: 12px; - font-weight: 500; - color: rgba(0, 0, 0, 0.54); -} -md-data-table-container ~ md-data-table-toolbar > *:not(:first-child) { - margin-left: 16px; -} -md-data-table-container ~ md-data-table-toolbar > *:not(:last-child) { - margin-right: 16px; -} -table[md-data-table]:not([md-row-select]) > thead:not([md-table-progress]) > tr > th[trim]:first-child > div { - right: 28px; - left: 24px; -} -table[md-data-table]:not([md-row-select]) > thead:not([md-table-progress]) > tr > th[trim]:nth-child(n+2):nth-last-child(n+2) > div { - right: 28px; - left: 28px; -} -table[md-data-table][md-row-select] > thead:not([md-table-progress]) > tr > th[trim]:nth-child(2) > div { - right: 28px; - left: 0; -} -table[md-data-table][md-row-select] > thead:not([md-table-progress]) > tr > th[trim]:nth-child(n+3):nth-last-child(n+2) > div { - right: 28px; - left: 28px; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th { - font-size: 12px; - color: rgba(0, 0, 0, 0.54); - white-space: nowrap; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th > div { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - height: 56px; - line-height: 18px; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th[numeric] > div { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th[trim] { - position: relative; - min-width: 60px; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th[trim][numeric]:hover > div { - left: 0 !important; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th[trim]:not([numeric]):hover > div { - right: 0 !important; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th[trim]:last-child > div { - right: 24px; - left: 24px; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th[trim] > div { - position: absolute; - top: 0; - bottom: 0; - transition: left 0.35s ease, right 0.35s ease; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th[trim] > div > div { - -webkit-flex: 0 1 auto; - -ms-flex: 0 1 auto; - flex: 0 1 auto; - overflow: hidden; - text-overflow: ellipsis; -} -table[md-data-table] > thead:not([md-table-progress])[md-order] > tr > th[order-by] { - transition: color 0.25s; -} -table[md-data-table] > thead:not([md-table-progress])[md-order] > tr > th[order-by]:not(.md-active):not(:hover) > div > md-icon { - fill: transparent; -} -table[md-data-table] > thead:not([md-table-progress])[md-order] > tr > th[order-by].md-active { - color: rgba(0, 0, 0, 0.87); -} -table[md-data-table] > thead:not([md-table-progress])[md-order] > tr > th[order-by].md-active > div > md-icon { - fill: rgba(0, 0, 0, 0.87); -} -table[md-data-table] > thead:not([md-table-progress])[md-order] > tr > th[order-by]:hover { - color: rgba(0, 0, 0, 0.87); - cursor: pointer; -} -table[md-data-table] > thead:not([md-table-progress])[md-order] > tr > th[order-by]:not(.md-active):hover > div > md-icon { - fill: rgba(0, 0, 0, 0.26); -} -table[md-data-table] > thead:not([md-table-progress])[md-order] > tr > th[order-by] > div > md-icon { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - height: 18px; - width: 18px; - margin: 0 4px; - transition: fill 0.25s, -webkit-transform 0.25s; - transition: fill 0.25s, transform 0.25s; -} -table[md-data-table] > thead:not([md-table-progress])[md-order] > tr > th[order-by] > div > md-icon.down { - -webkit-transform: rotate(180deg); - transform: rotate(180deg); -} -table[md-data-table] > thead:not([md-table-progress])[md-order] > tr > th[order-by] > div > md-icon.up { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); -} -table[md-data-table] > tbody > tr { - height: 48px; - transition: background-color 0.2s; -} -table[md-data-table] > tbody > tr[md-auto-select]:focus { - outline: none; -} -table[md-data-table] > tbody > tr:hover { - background-color: #eeeeee !important; -} -table[md-data-table] > tbody > tr[ng-repeat].ng-leave { - display: none; -} -table[md-data-table] > tbody > tr.md-selected { - background-color: #f5f5f5; -} -table[md-data-table] > tbody > tr > td { - font-size: 13px; - color: rgba(0, 0, 0, 0.87); - border-top: 1px rgba(0, 0, 0, 0.12) solid; -} -table[md-data-table] > tbody > tr > td.clickable { - cursor: pointer; -} -table[md-data-table] > tbody > tr > td.numeric { - text-align: right; -} -table[md-data-table] > tbody > tr > td.numeric md-select { - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} -table[md-data-table] > tbody > tr > td:not(.numeric) md-select > md-select-label { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; -} -table[md-data-table] > tbody > tr > td > md-select { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - padding: 0; - margin: 0; -} -table[md-data-table] > tbody > tr > td > md-select > md-select-value { - padding: 0; - min-width: 0; - min-height: 0; - border-bottom: 0 !important; -} -table[md-data-table] > tbody > tr > td > md-select > md-select-value > span:first-child { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - max-width: none; - -webkit-transform: none; - transform: none; -} -table[md-data-table] > tbody > tr > td > md-select > md-select-value > .md-select-icon { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - margin: 0; - color: rgba(0, 0, 0, 0.54) !important; - text-align: center; - -webkit-transform: none; - transform: none; -} -table[md-data-table] > tbody > tr > td > md-select > md-select-value > .md-select-icon:after { - -webkit-transform: scaleY(0.4) scaleX(0.8); - transform: scaleY(0.4) scaleX(0.8); -} -table[md-data-table] > tfoot > tr { - height: 48px; -} -table[md-data-table] > tfoot > tr > td { - font-size: 13px; - color: rgba(0, 0, 0, 0.87); - border-top: 1px rgba(0, 0, 0, 0.12) solid; - white-space: nowrap; -} -table[md-data-table] > tfoot > tr > td.numeric { - text-align: right; -} -md-data-table-pagination { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} -@media all and (max-width: 600px) { - md-data-table-pagination { - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - -webkit-align-items: stretch; - -ms-flex-align: stretch; - align-items: stretch; - } -} -md-data-table-pagination > div { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; - min-height: 56px; - font-size: 12px; - font-weight: 500; - color: rgba(0, 0, 0, 0.54); - border-top: 1px rgba(0, 0, 0, 0.12) solid; - box-sizing: border-box; -} -@media all and (min-width: 601px) { - md-data-table-pagination > div:nth-child(1) { - -webkit-flex: 1 1 auto; - -ms-flex: 1 1 auto; - flex: 1 1 auto; - } -} -md-data-table-pagination > div:nth-child(1) > .label { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin: 0 32px 0 24px; -} -md-data-table-pagination > div:nth-child(1) > md-select { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - padding: 0; - margin: 0 32px 0 0; -} -md-data-table-pagination > div:nth-child(1) > md-select > md-select-value { - padding: 0; - min-width: 0; - min-height: 0; - border-bottom: 0 !important; -} -md-data-table-pagination > div:nth-child(1) > md-select > md-select-value > span:first-child { - -webkit-flex: 1 0 auto; - -ms-flex: 1 0 auto; - flex: 1 0 auto; - max-width: none; - color: rgba(0, 0, 0, 0.54) !important; - -webkit-transform: none; - transform: none; -} -md-data-table-pagination > div:nth-child(1) > md-select > md-select-value > .md-select-icon { - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - margin: 0; - color: rgba(0, 0, 0, 0.54) !important; - text-align: center; - -webkit-transform: none; - transform: none; -} -md-data-table-pagination > div:nth-child(1) > md-select > md-select-value > .md-select-icon:after { - top: 1px; - -webkit-transform: scaleY(0.5) scaleX(1); - transform: scaleY(0.5) scaleX(1); -} -md-data-table-pagination > div:nth-child(1) > span:last-child { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; -} -@media all and (min-width: 601px) { - md-data-table-pagination > div:nth-child(1) > span:last-child { - margin-right: 32px; - } -} -@media all and (max-width: 600px) { - md-data-table-pagination > div:nth-child(1) > span:last-child { - margin-right: 24px; - } -} -md-data-table-pagination > div:nth-child(2) { - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; -} -md-data-table-pagination > div:nth-child(2) .md-button { - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex: 0 0 auto; - -ms-flex: 0 0 auto; - flex: 0 0 auto; - padding: 0; - min-height: 24px; - min-width: 24px; -} -md-data-table-pagination > div:nth-child(2) .md-button:not(:last-of-type) { - margin: 0 24px 0 0; -} -md-data-table-pagination > div:nth-child(2) .md-button:last-of-type { - margin: 0 18px 0 0; -} -.md-select-menu-container.md-pagination-select { - margin-top: -2px; - margin-left: -2px; -} -.md-select-menu-container.md-pagination-select md-content { - padding: 0; -} -.md-select-menu-container.md-pagination-select md-content md-option .md-text { - font-size: 12px; - font-weight: 500; -} -@-webkit-keyframes md-table-progress-enter { - from { - opacity: 0; - } - to { - opacity: 1; - } -} -@keyframes md-table-progress-enter { - from { - opacity: 0; - } - to { - opacity: 1; - } -} -@-webkit-keyframes md-table-progress-leave { - from { - opacity: 1; - } - to { - opacity: 0; - } -} -@keyframes md-table-progress-leave { - from { - opacity: 1; - } - to { - opacity: 0; - } -} -table[md-data-table] > thead[md-table-progress].ng-enter { - -webkit-animation: md-table-progress-enter 1s; - animation: md-table-progress-enter 1s; -} -table[md-data-table] > thead[md-table-progress].ng-leave { - -webkit-animation: md-table-progress-leave 1s 0.5s; - animation: md-table-progress-leave 1s 0.5s; -} -table[md-data-table] > thead[md-table-progress] tr > th { - padding: 0; -} -table[md-data-table] > thead[md-table-progress] tr > th > md-progress-linear { - height: 0; - top: -3px; -} -table[md-data-table] > thead[md-table-progress] tr > th > md-progress-linear > .md-container { - height: 3px; - top: 0; - transition: none; -} -table[md-data-table] > thead[md-table-progress] tr > th > md-progress-linear > .md-container > .md-bar { - height: 3px; -} -md-data-table-container { - display: block; - max-width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; -} -.md-select-menu-container.md-table-select { - margin-top: -2px; - margin-left: -2px; -} -.md-select-menu-container.md-table-select md-content { - padding: 0; -} -.md-select-menu-container.md-table-select md-content md-option .md-text { - font-size: 13px; -} -table[md-data-table] { - width: 100%; - border-spacing: 0; - background-color: #fff; - overflow: hidden; -} -table[md-data-table]:not([md-row-select]) > thead:not([md-table-progress]) > tr > th:first-child, -table[md-data-table]:not([md-row-select]) > tbody > tr > td:first-child, -table[md-data-table]:not([md-row-select]) > tfoot > tr > td:first-child { - padding: 0 28px 0 24px; -} -table[md-data-table]:not([md-row-select]) > thead:not([md-table-progress]) > tr > th:nth-child(n+2):nth-last-child(n+2), -table[md-data-table]:not([md-row-select]) > tbody > tr > td:nth-child(n+2):nth-last-child(n+2), -table[md-data-table]:not([md-row-select]) > tfoot > tr > td:nth-child(n+2):nth-last-child(n+2) { - padding: 0 28px; -} -table[md-data-table][md-row-select] > thead:not([md-table-progress]) > tr > th:first-child, -table[md-data-table][md-row-select] > tbody > tr > td:first-child, -table[md-data-table][md-row-select] > tfoot > tr > td:first-child { - width: 18px; - padding: 0 24px; -} -table[md-data-table][md-row-select] > thead:not([md-table-progress]) > tr > th:nth-child(2), -table[md-data-table][md-row-select] > tbody > tr > td:nth-child(2), -table[md-data-table][md-row-select] > tfoot > tr > td:nth-child(2) { - padding: 0 28px 0 0; -} -table[md-data-table][md-row-select] > thead:not([md-table-progress]) > tr > th:nth-child(n+3):nth-last-child(n+2), -table[md-data-table][md-row-select] > tbody > tr > td:nth-child(n+3):nth-last-child(n+2), -table[md-data-table][md-row-select] > tfoot > tr > td:nth-child(n+3):nth-last-child(n+2) { - padding: 0 28px; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th, -table[md-data-table] > tbody > tr > td, -table[md-data-table] > tfoot > tr > td { - text-align: left; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th:last-child, -table[md-data-table] > tbody > tr > td:last-child, -table[md-data-table] > tfoot > tr > td:last-child { - padding: 0 24px 0 28px; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th:focus, -table[md-data-table] > tbody > tr > td:focus, -table[md-data-table] > tfoot > tr > td:focus { - outline: none; -} -table[md-data-table] > thead:not([md-table-progress]) > tr > th > md-checkbox, -table[md-data-table] > tbody > tr > td > md-checkbox, -table[md-data-table] > tfoot > tr > td > md-checkbox { - margin: 0; -} - diff --git a/dist/public/images/avatar.png b/dist/public/images/avatar.png deleted file mode 100644 index d3e53011ecbb98368e4baf6d8c87b022c97e8f56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12735 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 TU4J6@Z_dp5Gp>H;^Yi}!0k(J; diff --git a/dist/public/images/social-icons/bloggr.png b/dist/public/images/social-icons/bloggr.png deleted file mode 100644 index 456b98fa10f4e0bcb631249ba3519b00f6e71ed9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3337 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 diff --git a/dist/public/images/social-icons/digg.png b/dist/public/images/social-icons/digg.png deleted file mode 100644 index b05b57743325a544bf552bf44763336cd5d7ee5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1754 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 diff --git a/dist/public/images/social-icons/facebook.png b/dist/public/images/social-icons/facebook.png deleted file mode 100644 index 91e96d6ee9114564a974684a435a5eb582d130f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2049 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 bfmVQ?#V#_{%*% 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 E0FlMHK>z>% diff --git a/dist/public/images/social-icons/google-plus.png b/dist/public/images/social-icons/google-plus.png deleted file mode 100644 index 45a3c4e10bf443cbee94602042d5c5ed5cb3fad5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5473 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 diff --git a/dist/public/images/social-icons/readme.txt b/dist/public/images/social-icons/readme.txt deleted file mode 100644 index c43229d..0000000 --- a/dist/public/images/social-icons/readme.txt +++ /dev/null @@ -1,18 +0,0 @@ -Thank you for downloading the graphic resource from Softarea.in. - -TERMS OF USAGE: - -* The freebie resources provided on Softarea.in are royalty free, and can be used in both personal and commercial projects including but not limited to websites, templates, themes, skins , blogs, Themeforest themes, games, software programs, prints. - -* Attribution is not necessary, but is always appreciated. - -Please do not host source files on your / other's server and or distribute / redistribute them as your own either in part or whole. If you want to share the files on your site, please link back to the appropriate source page on Softarea. - -______________________________ - -http://www.softarea.in/ - -Subscribe to softarea at: http://feeds.feedburner.com/softareain - - - diff --git a/dist/public/images/social-icons/rss.png b/dist/public/images/social-icons/rss.png deleted file mode 100644 index dc3b6a86eae9eac8e58d8fc343a0f781c72de2de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4159 zcmaJ^cUV)|w*~1ilu!j6386_Rlt2PV3ndh3p=Cr`0)!BPN$65U5TX=A(E+3ffe{3y z3W$KK(-x)f0u;Dz~(^WOWuH}8D+-gC~rYpuP{-usVxDR!64xjDr+85kJ2 z5f*R<`b<2%*;(n&^qItH`Xov=btO9ze92*6L=1xwn&6EABJf^*7zd0OI^t>{MvsAk z34}$ul3i`AVLk-Biq|PdB^)12XEQM98H5LW`QR{Qpf|=38>A1~Y<&&_V$u2_7cCn# zn_v@+Kh`3Wh;fX(g!GBT`9RSigNs1Da2QQ7d7Y^n~`hQiJ0!xRbuLo`ivesJLgpAbAIi2Q?#{%@}Fzj9Ao0Uu2F495_$p%}Co zk$?yObz~U!-(%7FSG~Wv=zos|`mbD7dN8V|h5a9e{$Zkb&*}1?wxw_WX?#o&z1xZO zw)SUbUS(kTsSW`*LWWPTxpR<_+Oug zd{TsTgvMt3NnY%;ljzdAslbXPnU?moxrjjNC&Ss?T+*mBRe_g%eI&&D-ummh?5DT< z0#_N%nR>oD<=S!c%ByPA(wnK(fl59JcV}cXGMkf9A3K=kc1gA_zW0AvG2YfBP05AF zzqqBIdO0O#E&LYujjY?U_Jc2h&!lRp(g7mfGkPFmd{*KT_|#*_Sqe1hz>}Ng zwsgCiIl}@$OOSRj=9ibGWWg;hKr+%){{LmX18-D08%@kkg>;~pkuHqc7()b)M53tS zaR_i(LEI%SZ~41@Ng_X@mRa{$fVKX%5$+h|2@{W^G27`0xr51-L6$sF336NXo%f;X|ci^Ep zg62!9V!=o0G>Pam^E8LMK9HC`(pia%$&4%KWqkb@Sa~9dpe+qYT-fS&@3i0NNUH^IXY`>+|5R#GW1KXcmdfE{`klk*4OFBW*o7`t|*) z*iwY)SgH5mepj_!3E+ctX@{LpYIicB=(|en&8dflG%H5N;;$bgjGUNL06%-Cq$SDA zo{v14U&>?<65y$33I$7`9F-}7oGOcPXlissOv9g$>oOvErF@PcIk zjh~bA+v8l*LoKa8U7dQ&F)}CanL%Bi@K$*)!1wOe0$a?Z0tSd|{Wt#!ZFpMLY_VB{ z5@=v)5Se4JbqOX1R994p+a?xOrAW+3PM)0t3|q|^&DSCd@=tQy4YyN-^Zg)%BnCiE z-#Om{w^{K1f_=HNcvhW2v5d?b$!>rWn)s&jHel}$R8;UEV7p<@WljX`U2hBXwI=az zUwwQh(yj_`#*M$qYPpjhz#{WyRZH-(qCvd;kO_{enZBOB6@dWdi9xThrV-fMXE_CD z$O`XDKtR>>%y+;HE_S1VZ9KaecvNHG3$x_8u2z7v1hE*-eD;uIVw+T-cmz%Nc2mm8 zA3VYy>5fSfhr|*Lw&VRaWcD=W>Js-R0;GR5?KIYze#ZW}@D>7m0 z2z*r2IQ7mML|QN|_igDba>|s)q0d)x){humySSyUfiErats^uqNUHID8e#FDD>!;O zG_$yQETtZ^-|PpnMZI2wqWCMtj@RRoAX^jWE4es-8-N&R_wOWcoPGF~3A!r3^oqvk zGiXukm<)^bq6JUSse2v0JwrQ|QrZo)eCb1!x`wv0Lo7Z(9C2BOvU|2-f9XSN$DjGu zjwbob*=v*eFffby45aRbSmokJhy|E> zR19!%%Z^!ls8V)yN}@Cz4~6(fC%+FqX-&P&)b%1lGm3PiiWGUj$0YY+0#_wHvH(oI z9GX=*r+=#)Zbp3W=IESK@8VbTpbb7Q^N`=;9z2qT(RxvM!*4~~@QdJf9vE!cv$xYb z{byB+X4CJsUhB{@ZazfMRSy^AGhJ~kQKCLS3)ymTd_W7Y&BSL2w2ot>Go7Pov%qW7 zg^$b~j3of+^((V#VV~Jf7^ObUo%p>uWQp9&MT)o^+}|WS8(utg46-rrmMe5@C~(`F zK3m_fH^Q1sE(&_c7Bax{lj!X`2~+H1$3U{MYG6IIUz4Pv5e->1wfSvy+DzGW%<;L1 zw%+eyo%PYEBYv-6B%c&?u_j8Ar}+~uHjnMh5DTBNp9>#dl>eL~3$N1WCY8^6PZn8( zd-1}>Rh!m5%Ug7Kp|LSSE*T%Ghr{BvPFYbKgL22y7-`(=DQ7bPms#ajI5;llat*Rq~pAsgk{37s@RZj1Qha!-w@`Y{K3SyYA^Vt;kv z%%hsKl(yKm#T=Q6x5pi>lVaw_)dzLsUH8;({@(Q_?EW+5vT*^d+Itmm?Um5q6xJiI z9EjKH`2_r4jSiUXT$H~)`L%TWRa4i!BG~}W0+c>=rjz*;8KQu7V<@s zcLiweS^hOIE8=DN8YwkeD!;0BmrfRa7`3Oo|UiHmm4^1`%J;Av=dfXs} zBL7j-dw2+Q+Qhe?EZ3sE-3!Uvwjbd+DG^PWoVgr@qXok`ayruJ#D z>DX}fCXGav6qdHePY8_DWRdm?KX3ht>uEnu-O|{osPIfluG^nIC}Caw1%xQ8Q1;mq zn%zIOL+(M4uOE>Repxz|5<*%t_o^1nM{iO>D2}>41~p7( z)BAPbK%a&Wv%1Zjwi|y!<=72W&v> zW%NckvQ_ayfDK%>ieV#f_4qqQN&fk&*WzX6U(K7o>rNE4TyW8IvalfL?+gpvulAPb z#s31dd$WMwSrG@_C>7EgC}VZ(FBK?s;|j1$<4`m{E*D3d-lKu*5Budmb+*?xT$0AD zL*B$l)MutZB(a6PQOmWh{Na{tIa8gF_VIi$SQKL-7?C2JER;OH`gCAc^WrM?}^H_N+IROfKy!LKnLFLe% z+WTJc_?Zj{4zpJ5%!?V(hARXnlGw6ELS4tB&Z$!DqP<6YL)3D@k%?oU>} z%$`*y=!mBi6k1IPAG|Mi|0;B;nVRk{^l;a%@DBLN4P5nrFm6sQ0bUOR*|y1z@gS-t zddv-;?vb3GrM|l!gnewUdi-gmFAdwIsa}7C*Y+BRQFo;)U)Xre^?&ztdWJ5HXSs*U zkw2DxfV!^8D$|qWedbXqHOn>{=p=rkPJH$ zh7uS0iMG3Ru%3S_k!_IAZE(Z0UvqwEuFJXlT#_T3;ly2`=E~ZoPul`EjJ6TQzp8R^ zl74n~W|xg;Ej`?EVVrA>8gAT-y_hbpn*q=XQaQt#>J{Pa^0o?7(H1e@?ti(~PvbY@ zsL))=aIVa_>5(zgW;C;XZAc}O0GLwZel=Nhdl@+<%rCM$`xJ|9^PE8!e+oCCD$;1l zfJ;5cZ(Wu1CSdIBe6e^>fkw(Vj-W4c)r2Ze$JWEAedk|V*&5-5L0FNj*7ZAk?^8c~ zP4j8uj~233!woQtG2eEYRT$OcqV8gOxNrxn8-d-#Wmt*7^?V5&ve$P{Iky+(kn1h` zu3;h1G4J3yAgw<@ni|9=Sl{K*q&xJPd9STO3Wiz}i|o`59JohmW+imJeJ@b7p|hQX zT%f`4UlZV<)KlU?BkR?8UMLlR#f&RUE2W|zB}JkfcNT@Q9IxY>rFhou6+_Ci?^+i7b9cKr zPpt2j#)Brukd-;8GkC1r&^b4AaCT|sPNVh_NFy^7kr;sTF6j!fdbr)RD0rj9ku$JY zZg$u=!x-+MxL;lV$-eb`CC>S-V8P8TXwF2~RK?vVZvJkN7~@B4FI*LVHrjhXah9^kp}`K0s{*SB>9l($UrU7-@3>H`|ubF0{#tQcx!?F6O@yM zHPC=UBLGzulp#1p7z_x9E5KA#;c%EdP)QM{1XVnE;SiV#QWcI=QUm_;fDXLT@SaEv z%IF_o2Rkj07lT1XLZJZx0SW=i3KZHUC=7u>9BL>jK@JcQdJvg`4TO;C62BBs1UimJ zq%w#UGVo9l>p}5jXn_tQ{Z9%c>c6sN`afklC>S&lONGJ|6c1DS1+=jE|Dhz(zi2uG zL-=pJ|EDnBE{IBiVhD7K9}RcVI8TW~S5%|{jeuoPXm%8e&#x+4dr=q^x)+5CG_ZvO zWgLlQJSBh*{u^&$fkcz(3@jN(K%=xk2MP*AA|9y(H&D|<7%3YVAy6=wp^~1eks3-* zMG>a22Uk)=DF5Q3C^$b7fz0^D#s8P9@>}lVD3GWJo>2rE(Vu`fqESe|zf(pMe;*6% zw|f6@@xPBn>9<_yK`_w6#{REH|2jIDoYjG_fD;kORH;t%4w*{-@oE7 zsgn@ex=-8+ZJBA9v3)%<^3aX7{>ZSIm4j!E(%n=^2NvLn5FRTPlbTsphFu8R7b|m+ zv-=7ZLS6k<6Q4R>R&3bfcNyWdla|VGkd4dXsX6xE-@zyjPLo@$6hV}K)mmp|9)zgY zkOiV;Nu?tRZCRerjq4Iz{&;07=9h_;05(^~PMNbHjOwB%y?G*5WG6aSU#IHsCiqjY z>?G{u#+ZZ)0HfJV#F;U_vG{>nX6?C0h2>-wg>fF|aJuuHjMQMDCXfqmtjblo;ajpI zaBO-y;$>uc)f+jDzMuCaD=)J(JEOzI)AnnhrybWh8MbtHe^u&~#E&0O7Pe&rAfl?r zm}_cfq~~#xz^BYQ{L62C%hAbp0W86HWJmr1MrU_ z*N&Jt%7PwpI~0a8->j^d@{{Dyi7Mc$ycWODnXG^@TH^A2`BCFSf8OrkX|bPj%tI%a zP7Dbq8S2c{?YfzU&9xh)FqMR7nWfE+>~2O>pUxGN(50!4jrUu3-nOg^NMrHiN`}Zd z1Cp$Nau$uHmo0O*OeyHnScUF9G->l~M$IqSKb@s=CTj|O1mv5ywMSGrh3|#bGW8mG zPM$GbDle`$;^he?5TuzgJJC$nKwtm5qrv~3{Yi(s0RS)KPfxYg#?b;u3 zycBJ>sVSK7YEGx=yRc~KqxbZiXL*&}CV49hDxN-+(LQQ6jjVfki&E3<9PZPg((e57 zWBc*`b8Rn4t6#D&ja_tn_06aUF^ElLAsnT-o7?v^Qbi<>-7zIVK89rO9%6poTWZUqh^HoMU z?_UX!ut7=fredVwr;`>#U>d0^jHj7n>+(P?tYsWKoHq9<~@${ zZSKpUH=%wpxnqJNrPm!wzpmt@?nQ{@hk`kn8XP)#=QJ3WbiXFes3Gf#4Bz+i(NWOA#Z0$y(+3#>KCfD;x@4uB`}7SltS4aNiMjfl@9jql6Ki zokW=hN`|`21)M*KHTAQJ`KlK8xkC5um)g)y$EoJ^Ldn5LX2)5%3gMpYH&X&K}+I9|Au&M$T6YZFW?xZSR#>yn%xOd?G`_JbA%d z$Hgk?;{qKx-D$-SRE@D@j_bG??(;9or- z?v}i({X=!nD@F_K#+$NP^o3HhlQmT!Xn{?U+pX+b(wkiHIhzH%r+)X6)D!W0iC#ay zPN`=E9A9KTrMEm5cF%_Q`* zctXKB-(u>y8neWs$@nPwl{T*adiwI#t@N3T8)I|S9t`_6xNrhHq$8nZ*ro0Cz#W-{ z*Mg3YbDqyt&DY!CwU;<6q-J)zpWc(l6>deAjlHS5ABcOW#I{=>2JPOZFDF;8pR}8h z6&AIM`xsZyIo(r?YQM6r=IWlX)eq5q+_}^SylDies}GbvyKyYbGK=kM_Fr@UHRLnh zEi(#Dl$rA?Rg8&>^cZ!40M>b=NG z4GV)$<@7MIs3<^9{s1x%j~`C=l+h2F&bp^KU#tD*3aQ9rOg|@+c&oD&APENPr_6aw zlmb0BySuyyGoYQ*B^8CE-9(9{E(_e}mF}K}HW5>=C~V|bq@>>>sMp4u%G zfSPrD$PGJ3eSO_p7`!e`_lvdEh`~}1gc()DhUVhFoqR_?va?CddMSDy2tWP6-(u(c zcL}&diVk2PN=E~Rx^HaOW5)M>w4Ao4s4+v9AI;-TbX!k0INqCEo&+wiG`6mrU=p%h zUdt37)$pcIzZJ1QF#25K*+0`Ymx5LniR=Y(9jnjj3bwdKpP$~TcFP;=fSekYQ+6Nx z7QAt+nv_hh%plJ3X(G4*e&8|y_Xr`VTO%a&bgqGow=Vs z=||r{%bARZ|jMIo+M@hgLoWu3kOKhiEZwprp^A z6uPFse%m%I?!?i&LFF1Xkg82_y<^_f5HriPy1DOtZ)iccSJqpzJv{6#@UL?v^A>XH zT+dR!G|Oya`o4Ax!&AX6mV>AauBois&u~ zK3ZuIog~HkvV?w}rb3xN9%^Ix`v8k!GU$pv9*}PRMmzd5 z>duMM;jl$EX+9w>6o4~XpCvzeSg#o*>-?fAx2We)Y0z^JCs zrb$Bh*_0vA>pK%obt96_ofd{Gu{l1Eg>UYGa-%cOd3dV)P~WdgnGOC@=(=gH#=oi{ z;pulfk>>1O@HQRHcvw|cUplI7D6MNbv{pidP5H*_je>>X468boI-5#>$%I`t=4zC~ zR!NKS%}q3RusQDA(17Xep#R`0vYbbQkt_0vbb8y4NnOlj{2Rhp<>R3_-*547UyapD zoTJA6#kLgv(ro;KL33sNx5d4BD_5)h5lNa;>(aF0mjU~l=!t~X^JUf#3{694&rOuu q#%76xl#}Q4Z)T2f{rLQog@;MlJHy$vr!n^MMvFGIL{;ctjQk(!IOg^M diff --git a/dist/public/images/social-icons/simple-flat-social-icons.jpg b/dist/public/images/social-icons/simple-flat-social-icons.jpg deleted file mode 100644 index aa2a53d2284545de54b54a93063bb34167ce1bb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 117744 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�c|nRGduUy-ZCGY;*k<&K%_ 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

? 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 diff --git a/dist/public/images/social-icons/tumblr.png b/dist/public/images/social-icons/tumblr.png deleted file mode 100644 index a3ca944739ea272518a0c39c6395df4b6ef4ea43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2468 zcmaJ@c|25m8=p3BiK0S8rXv~KY+0Hyb1gF%G6-dB8|D~;S(+I}%APGtMkTH!QFpqw zREkEHaIH}iveYeHOR^@V8+TN??;mgP`J8i}=lA=3zu)KiJ&arkDa#mmAcHMtLm)WgKsLqG7vw=bKpLHi2PQ?80F+L}1J3$nB$-VB zz3HSN4(J$U>*N{a>xrQP#=k&ufmpEs1LRSlfeb$;7aNENzUpGd{_-{gfPRJWeDT1y zq+H1MPy&ksLiOQ$bv=pHm;%FSI z7uJDj@jaG!g$KNOJT?}A;Pd%#{$4nXLqni27|gN;8m%iv=yFdod6Yn1CRc4mfe3Ov zIdnFU&SFBB6)7Gpe;ytXXZr034E7IMCii=p#05hHQrHL-9Jzd?6(E`X|Dg=V4>XtO z0REfr{}kpron(Uu2awD1=Xi=6=cTqBij5_3Knjn=abmIjR;p<4&Em1R-Yhnh;AjAa zIn$X`7N4v66;CE(t(aUMh3N@e5%GXn0Zyk=u|z{Ng1)%S1Pcrig)&E*?jvAK4b6~9 zG!mmnMC+|^i7Zcl2FT>CaH;=t4S&jA9t8$l9GM7m=m8+rg2Q4!zaAM&|9LKYKh^ur zrT#n@{hx9X;$#rZjs34iuWX5@XW9KRw&KN)!3UY*Y3GQ?nj7~=4+J8y-HK@H6xcJK z8EVr3D%Ts&4~2BE;)lT!R6WM4&PZ*eY2_vgRl4<>)AbXN-#aLb5AEq`Dw(tMZ9SBs zyQj2l(Z_Ak(P9V6z4Wn><-O zTsMo$8lJ_?<7;Yb*OE0V^U;<#uePL22$q7lh%PrP1^N^X6^+%?-UQtVop4bUwn zyNRp6dBCb4UbqCR>F;JsbIte7WlCtJ$?kW6~k z`E_DbHeIZbgozqD28nLx%OoX0h0(qb`^Fn9{zfV$zHe_WdpIn-etoDglt!cFSi%iN znY}PnbrKVHr(vJF)WLV5oBpCId|Gsuqbi`oYXR-~)Tie&x@vxH0kZha-)e>sRcZOI zc^*jnp?D+VSQQf;J8WVm7}eAseONPeSCge{(+Er9>mThO$US0boXtFFzMAjr*lny` zBcJ9)bW^=8jB6=O0eUV}%GU_qLkgo>Dm2_$7riqs zTh3(nlS$=95Lq~}J!eno^`l+7CC3Y4k}o`RH0gDmg@r*&%CT2tu!x4JNAF(u2Aq06 zoOuM#4@ThCH}r2JXs?v9d2?blc*_K8lD#?2$~xiP$GKgc?C6a{ORH+U^|E^@-cclo z03t5C+3v8fUUkY=3~nr%gh$G*H_6?(eXcK@glE^kjU?g!3^)aK*jqDzqw1VH7fC9R zNwa*EQqIB1DKIa0y;YFUSBrlkB@mEY$}5U*g;q>-A82aJ#K|FpYZgML9tYcU*@{iCX24)(suC$cK0NxyD{sHkm%|1D*4*O$;fkdVo$u{sJ`Q#$J~;8L ze;>=%92Re-RmBWfA=YnpEMDEhDmo@s-v|lYIKM0b)NBht>p55AN zTVm+pohb9pFlgjvaLhi2+^SaQ| znUKm&iEChd<3WWS7V!+8*e0ZP_1L{ zJNn)A_Ysb(DqrjULKwsKp2*37f9bb=e5uG`_F~@Pd|RQ(W`XP(zWKgYiaU0=Pjz*s zkVXwt%XU3$Z-;65&_k1Q;kN73YEP$KxngUPBMX4_eg=*f77}%}IxR6Gmx4oN25WT8 zE-j|(!i8;0ii+746~D}U0z`-HCm(@#4jevwc_Ai8orjS>Q8aiwn?NAU{vLn3d}L(g zrmv6xdDpJ<*1~Db9e+{(;B;VznGCLkavN;!NDfyQsIZG9 zt;}z)S^iF>6_9ipNfA?j=8|0#l+^8;tA3%WVSv+^VPg|*zUPr9;JB7KStMPW+9Rus@r`tRvu$Yu62fbm5>D%>ColguS()1s3(by4`~y8J B9C`o% diff --git a/dist/public/images/social-icons/twitter.png b/dist/public/images/social-icons/twitter.png deleted file mode 100644 index 1561f844008b4ef8428b9387a397a32aae82587d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3691 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 QYrDUH7_<$l+RP{RUwf{KDgXcg diff --git a/dist/public/images/social-icons/vimeo.png b/dist/public/images/social-icons/vimeo.png deleted file mode 100644 index db8be67b931a4494a2da20d82366a17ba1c921a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3900 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 ZmbnydeztAK!v6oPnX#2om4W-U{{W2x`3V33 diff --git a/dist/public/images/social-icons/youtube.png b/dist/public/images/social-icons/youtube.png deleted file mode 100644 index 14424cb348feb94deee8bf04a0754c3fc40ce7c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4492 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 diff --git a/dist/public/index.html b/dist/public/index.html deleted file mode 100644 index 86f54b8..0000000 --- a/dist/public/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - -

- - - - - - - - - - - - \ No newline at end of file diff --git a/dist/public/js/angular.js b/dist/public/js/angular.js deleted file mode 100644 index e3b322a..0000000 --- a/dist/public/js/angular.js +++ /dev/null @@ -1,29859 +0,0 @@ -/** - * @license AngularJS v1.5.0-rc.0 - * (c) 2010-2015 Google, Inc. http://angularjs.org - * License: MIT - */ -(function(window, document, undefined) {'use strict'; - -/** - * @description - * - * This object provides a utility for producing rich Error messages within - * Angular. It can be called as follows: - * - * var exampleMinErr = minErr('example'); - * throw exampleMinErr('one', 'This {0} is {1}', foo, bar); - * - * The above creates an instance of minErr in the example namespace. The - * resulting error will have a namespaced error code of example.one. The - * resulting error will replace {0} with the value of foo, and {1} with the - * value of bar. The object is not restricted in the number of arguments it can - * take. - * - * If fewer arguments are specified than necessary for interpolation, the extra - * interpolation markers will be preserved in the final string. - * - * Since data will be parsed statically during a build step, some restrictions - * are applied with respect to how minErr instances are created and called. - * Instances should have names of the form namespaceMinErr for a minErr created - * using minErr('namespace') . Error codes, namespaces and template strings - * should all be static strings, not variables or general expressions. - * - * @param {string} module The namespace to use for the new minErr instance. - * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning - * error from returned function, for cases when a particular type of error is useful. - * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance - */ - -function minErr(module, ErrorConstructor) { - ErrorConstructor = ErrorConstructor || Error; - return function() { - var SKIP_INDEXES = 2; - - var templateArgs = arguments, - code = templateArgs[0], - message = '[' + (module ? module + ':' : '') + code + '] ', - template = templateArgs[1], - paramPrefix, i; - - message += template.replace(/\{\d+\}/g, function(match) { - var index = +match.slice(1, -1), - shiftedIndex = index + SKIP_INDEXES; - - if (shiftedIndex < templateArgs.length) { - return toDebugString(templateArgs[shiftedIndex]); - } - - return match; - }); - - message += '\nhttp://errors.angularjs.org/1.5.0-rc.0/' + - (module ? module + '/' : '') + code; - - for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') { - message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' + - encodeURIComponent(toDebugString(templateArgs[i])); - } - - return new ErrorConstructor(message); - }; -} - -/* We need to tell jshint what variables are being exported */ -/* global angular: true, - msie: true, - jqLite: true, - jQuery: true, - slice: true, - splice: true, - push: true, - toString: true, - ngMinErr: true, - angularModule: true, - uid: true, - REGEX_STRING_REGEXP: true, - VALIDITY_STATE_PROPERTY: true, - - lowercase: true, - uppercase: true, - manualLowercase: true, - manualUppercase: true, - nodeName_: true, - isArrayLike: true, - forEach: true, - forEachSorted: true, - reverseParams: true, - nextUid: true, - setHashKey: true, - extend: true, - toInt: true, - inherit: true, - merge: true, - noop: true, - identity: true, - valueFn: true, - isUndefined: true, - isDefined: true, - isObject: true, - isBlankObject: true, - isString: true, - isNumber: true, - isDate: true, - isArray: true, - isFunction: true, - isRegExp: true, - isWindow: true, - isScope: true, - isFile: true, - isFormData: true, - isBlob: true, - isBoolean: true, - isPromiseLike: true, - trim: true, - escapeForRegexp: true, - isElement: true, - makeMap: true, - includes: true, - arrayRemove: true, - copy: true, - shallowCopy: true, - equals: true, - csp: true, - jq: true, - concat: true, - sliceArgs: true, - bind: true, - toJsonReplacer: true, - toJson: true, - fromJson: true, - convertTimezoneToLocal: true, - timezoneToOffset: true, - startingTag: true, - tryDecodeURIComponent: true, - parseKeyValue: true, - toKeyValue: true, - encodeUriSegment: true, - encodeUriQuery: true, - angularInit: true, - bootstrap: true, - getTestability: true, - snake_case: true, - bindJQuery: true, - assertArg: true, - assertArgFn: true, - assertNotHasOwnProperty: true, - getter: true, - getBlockNodes: true, - hasOwnProperty: true, - createMap: true, - - NODE_TYPE_ELEMENT: true, - NODE_TYPE_ATTRIBUTE: true, - NODE_TYPE_TEXT: true, - NODE_TYPE_COMMENT: true, - NODE_TYPE_DOCUMENT: true, - NODE_TYPE_DOCUMENT_FRAGMENT: true, -*/ - -//////////////////////////////////// - -/** - * @ngdoc module - * @name ng - * @module ng - * @description - * - * # ng (core module) - * The ng module is loaded by default when an AngularJS application is started. The module itself - * contains the essential components for an AngularJS application to function. The table below - * lists a high level breakdown of each of the services/factories, filters, directives and testing - * components available within this core module. - * - *
- */ - -var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/; - -// The name of a form control's ValidityState property. -// This is used so that it's possible for internal tests to create mock ValidityStates. -var VALIDITY_STATE_PROPERTY = 'validity'; - -/** - * @ngdoc function - * @name angular.lowercase - * @module ng - * @kind function - * - * @description Converts the specified string to lowercase. - * @param {string} string String to be converted to lowercase. - * @returns {string} Lowercased string. - */ -var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;}; -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * @ngdoc function - * @name angular.uppercase - * @module ng - * @kind function - * - * @description Converts the specified string to uppercase. - * @param {string} string String to be converted to uppercase. - * @returns {string} Uppercased string. - */ -var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;}; - - -var manualLowercase = function(s) { - /* jshint bitwise: false */ - return isString(s) - ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);}) - : s; -}; -var manualUppercase = function(s) { - /* jshint bitwise: false */ - return isString(s) - ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);}) - : s; -}; - - -// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish -// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods -// with correct but slower alternatives. -if ('i' !== 'I'.toLowerCase()) { - lowercase = manualLowercase; - uppercase = manualUppercase; -} - - -var - msie, // holds major version number for IE, or NaN if UA is not IE. - jqLite, // delay binding since jQuery could be loaded after us. - jQuery, // delay binding - slice = [].slice, - splice = [].splice, - push = [].push, - toString = Object.prototype.toString, - getPrototypeOf = Object.getPrototypeOf, - ngMinErr = minErr('ng'), - - /** @name angular */ - angular = window.angular || (window.angular = {}), - angularModule, - uid = 0; - -/** - * documentMode is an IE-only property - * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx - */ -msie = document.documentMode; - - -/** - * @private - * @param {*} obj - * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, - * String ...) - */ -function isArrayLike(obj) { - - // `null`, `undefined` and `window` are not array-like - if (obj == null || isWindow(obj)) return false; - - // arrays, strings and jQuery/jqLite objects are array like - // * jqLite is either the jQuery or jqLite constructor function - // * we have to check the existance of jqLite first as this method is called - // via the forEach method when constructing the jqLite object in the first place - if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true; - - // Support: iOS 8.2 (not reproducible in simulator) - // "length" in obj used to prevent JIT error (gh-11508) - var length = "length" in Object(obj) && obj.length; - - // NodeList objects (with `item` method) and - // other objects with suitable length characteristics are array-like - return isNumber(length) && - (length >= 0 && (length - 1) in obj || typeof obj.item == 'function'); -} - -/** - * @ngdoc function - * @name angular.forEach - * @module ng - * @kind function - * - * @description - * Invokes the `iterator` function once for each item in `obj` collection, which can be either an - * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value` - * is the value of an object property or an array element, `key` is the object property key or - * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional. - * - * It is worth noting that `.forEach` does not iterate over inherited properties because it filters - * using the `hasOwnProperty` method. - * - * Unlike ES262's - * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18), - * Providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just - * return the value provided. - * - ```js - var values = {name: 'misko', gender: 'male'}; - var log = []; - angular.forEach(values, function(value, key) { - this.push(key + ': ' + value); - }, log); - expect(log).toEqual(['name: misko', 'gender: male']); - ``` - * - * @param {Object|Array} obj Object to iterate over. - * @param {Function} iterator Iterator function. - * @param {Object=} context Object to become context (`this`) for the iterator function. - * @returns {Object|Array} Reference to `obj`. - */ - -function forEach(obj, iterator, context) { - var key, length; - if (obj) { - if (isFunction(obj)) { - for (key in obj) { - // Need to check if hasOwnProperty exists, - // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function - if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) { - iterator.call(context, obj[key], key, obj); - } - } - } else if (isArray(obj) || isArrayLike(obj)) { - var isPrimitive = typeof obj !== 'object'; - for (key = 0, length = obj.length; key < length; key++) { - if (isPrimitive || key in obj) { - iterator.call(context, obj[key], key, obj); - } - } - } else if (obj.forEach && obj.forEach !== forEach) { - obj.forEach(iterator, context, obj); - } else if (isBlankObject(obj)) { - // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty - for (key in obj) { - iterator.call(context, obj[key], key, obj); - } - } else if (typeof obj.hasOwnProperty === 'function') { - // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed - for (key in obj) { - if (obj.hasOwnProperty(key)) { - iterator.call(context, obj[key], key, obj); - } - } - } else { - // Slow path for objects which do not have a method `hasOwnProperty` - for (key in obj) { - if (hasOwnProperty.call(obj, key)) { - iterator.call(context, obj[key], key, obj); - } - } - } - } - return obj; -} - -function forEachSorted(obj, iterator, context) { - var keys = Object.keys(obj).sort(); - for (var i = 0; i < keys.length; i++) { - iterator.call(context, obj[keys[i]], keys[i]); - } - return keys; -} - - -/** - * when using forEach the params are value, key, but it is often useful to have key, value. - * @param {function(string, *)} iteratorFn - * @returns {function(*, string)} - */ -function reverseParams(iteratorFn) { - return function(value, key) { iteratorFn(key, value); }; -} - -/** - * A consistent way of creating unique IDs in angular. - * - * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before - * we hit number precision issues in JavaScript. - * - * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M - * - * @returns {number} an unique alpha-numeric string - */ -function nextUid() { - return ++uid; -} - - -/** - * Set or clear the hashkey for an object. - * @param obj object - * @param h the hashkey (!truthy to delete the hashkey) - */ -function setHashKey(obj, h) { - if (h) { - obj.$$hashKey = h; - } else { - delete obj.$$hashKey; - } -} - - -function baseExtend(dst, objs, deep) { - var h = dst.$$hashKey; - - for (var i = 0, ii = objs.length; i < ii; ++i) { - var obj = objs[i]; - if (!isObject(obj) && !isFunction(obj)) continue; - var keys = Object.keys(obj); - for (var j = 0, jj = keys.length; j < jj; j++) { - var key = keys[j]; - var src = obj[key]; - - if (deep && isObject(src)) { - if (isDate(src)) { - dst[key] = new Date(src.valueOf()); - } else if (isRegExp(src)) { - dst[key] = new RegExp(src); - } else if (src.nodeName) { - dst[key] = src.cloneNode(true); - } else if (isElement(src)) { - dst[key] = src.clone(); - } else { - if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {}; - baseExtend(dst[key], [src], true); - } - } else { - dst[key] = src; - } - } - } - - setHashKey(dst, h); - return dst; -} - -/** - * @ngdoc function - * @name angular.extend - * @module ng - * @kind function - * - * @description - * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s) - * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so - * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`. - * - * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use - * {@link angular.merge} for this. - * - * @param {Object} dst Destination object. - * @param {...Object} src Source object(s). - * @returns {Object} Reference to `dst`. - */ -function extend(dst) { - return baseExtend(dst, slice.call(arguments, 1), false); -} - - -/** -* @ngdoc function -* @name angular.merge -* @module ng -* @kind function -* -* @description -* Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s) -* to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so -* by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`. -* -* Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source -* objects, performing a deep copy. -* -* @param {Object} dst Destination object. -* @param {...Object} src Source object(s). -* @returns {Object} Reference to `dst`. -*/ -function merge(dst) { - return baseExtend(dst, slice.call(arguments, 1), true); -} - - - -function toInt(str) { - return parseInt(str, 10); -} - - -function inherit(parent, extra) { - return extend(Object.create(parent), extra); -} - -/** - * @ngdoc function - * @name angular.noop - * @module ng - * @kind function - * - * @description - * A function that performs no operations. This function can be useful when writing code in the - * functional style. - ```js - function foo(callback) { - var result = calculateResult(); - (callback || angular.noop)(result); - } - ``` - */ -function noop() {} -noop.$inject = []; - - -/** - * @ngdoc function - * @name angular.identity - * @module ng - * @kind function - * - * @description - * A function that returns its first argument. This function is useful when writing code in the - * functional style. - * - ```js - function transformer(transformationFn, value) { - return (transformationFn || angular.identity)(value); - }; - ``` - * @param {*} value to be returned. - * @returns {*} the value passed in. - */ -function identity($) {return $;} -identity.$inject = []; - - -function valueFn(value) {return function() {return value;};} - -function hasCustomToString(obj) { - return isFunction(obj.toString) && obj.toString !== toString; -} - - -/** - * @ngdoc function - * @name angular.isUndefined - * @module ng - * @kind function - * - * @description - * Determines if a reference is undefined. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is undefined. - */ -function isUndefined(value) {return typeof value === 'undefined';} - - -/** - * @ngdoc function - * @name angular.isDefined - * @module ng - * @kind function - * - * @description - * Determines if a reference is defined. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is defined. - */ -function isDefined(value) {return typeof value !== 'undefined';} - - -/** - * @ngdoc function - * @name angular.isObject - * @module ng - * @kind function - * - * @description - * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not - * considered to be objects. Note that JavaScript arrays are objects. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is an `Object` but not `null`. - */ -function isObject(value) { - // http://jsperf.com/isobject4 - return value !== null && typeof value === 'object'; -} - - -/** - * Determine if a value is an object with a null prototype - * - * @returns {boolean} True if `value` is an `Object` with a null prototype - */ -function isBlankObject(value) { - return value !== null && typeof value === 'object' && !getPrototypeOf(value); -} - - -/** - * @ngdoc function - * @name angular.isString - * @module ng - * @kind function - * - * @description - * Determines if a reference is a `String`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `String`. - */ -function isString(value) {return typeof value === 'string';} - - -/** - * @ngdoc function - * @name angular.isNumber - * @module ng - * @kind function - * - * @description - * Determines if a reference is a `Number`. - * - * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`. - * - * If you wish to exclude these then you can use the native - * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite) - * method. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `Number`. - */ -function isNumber(value) {return typeof value === 'number';} - - -/** - * @ngdoc function - * @name angular.isDate - * @module ng - * @kind function - * - * @description - * Determines if a value is a date. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `Date`. - */ -function isDate(value) { - return toString.call(value) === '[object Date]'; -} - - -/** - * @ngdoc function - * @name angular.isArray - * @module ng - * @kind function - * - * @description - * Determines if a reference is an `Array`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is an `Array`. - */ -var isArray = Array.isArray; - -/** - * @ngdoc function - * @name angular.isFunction - * @module ng - * @kind function - * - * @description - * Determines if a reference is a `Function`. - * - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `Function`. - */ -function isFunction(value) {return typeof value === 'function';} - - -/** - * Determines if a value is a regular expression object. - * - * @private - * @param {*} value Reference to check. - * @returns {boolean} True if `value` is a `RegExp`. - */ -function isRegExp(value) { - return toString.call(value) === '[object RegExp]'; -} - - -/** - * Checks if `obj` is a window object. - * - * @private - * @param {*} obj Object to check - * @returns {boolean} True if `obj` is a window obj. - */ -function isWindow(obj) { - return obj && obj.window === obj; -} - - -function isScope(obj) { - return obj && obj.$evalAsync && obj.$watch; -} - - -function isFile(obj) { - return toString.call(obj) === '[object File]'; -} - - -function isFormData(obj) { - return toString.call(obj) === '[object FormData]'; -} - - -function isBlob(obj) { - return toString.call(obj) === '[object Blob]'; -} - - -function isBoolean(value) { - return typeof value === 'boolean'; -} - - -function isPromiseLike(obj) { - return obj && isFunction(obj.then); -} - - -var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array\]$/; -function isTypedArray(value) { - return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value)); -} - - -var trim = function(value) { - return isString(value) ? value.trim() : value; -}; - -// Copied from: -// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021 -// Prereq: s is a string. -var escapeForRegexp = function(s) { - return s.replace(/([-()\[\]{}+?*.$\^|,:#= 0) { - array.splice(index, 1); - } - return index; -} - -/** - * @ngdoc function - * @name angular.copy - * @module ng - * @kind function - * - * @description - * Creates a deep copy of `source`, which should be an object or an array. - * - * * If no destination is supplied, a copy of the object or array is created. - * * If a destination is provided, all of its elements (for arrays) or properties (for objects) - * are deleted and then all elements/properties from the source are copied to it. - * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned. - * * If `source` is identical to 'destination' an exception will be thrown. - * - * @param {*} source The source that will be used to make a copy. - * Can be any type, including primitives, `null`, and `undefined`. - * @param {(Object|Array)=} destination Destination into which the source is copied. If - * provided, must be of the same type as `source`. - * @returns {*} The copy or updated `destination`, if `destination` was specified. - * - * @example - - -
-
- Name:
- E-mail:
- Gender: male - female
- - -
-
form = {{user | json}}
-
master = {{master | json}}
-
- - -
-
- */ -function copy(source, destination) { - var stackSource = []; - var stackDest = []; - - if (destination) { - if (isTypedArray(destination)) { - throw ngMinErr('cpta', "Can't copy! TypedArray destination cannot be mutated."); - } - if (source === destination) { - throw ngMinErr('cpi', "Can't copy! Source and destination are identical."); - } - - // Empty the destination object - if (isArray(destination)) { - destination.length = 0; - } else { - forEach(destination, function(value, key) { - if (key !== '$$hashKey') { - delete destination[key]; - } - }); - } - - stackSource.push(source); - stackDest.push(destination); - return copyRecurse(source, destination); - } - - return copyElement(source); - - function copyRecurse(source, destination) { - var h = destination.$$hashKey; - var result, key; - if (isArray(source)) { - for (var i = 0, ii = source.length; i < ii; i++) { - destination.push(copyElement(source[i])); - } - } else if (isBlankObject(source)) { - // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty - for (key in source) { - destination[key] = copyElement(source[key]); - } - } else if (source && typeof source.hasOwnProperty === 'function') { - // Slow path, which must rely on hasOwnProperty - for (key in source) { - if (source.hasOwnProperty(key)) { - destination[key] = copyElement(source[key]); - } - } - } else { - // Slowest path --- hasOwnProperty can't be called as a method - for (key in source) { - if (hasOwnProperty.call(source, key)) { - destination[key] = copyElement(source[key]); - } - } - } - setHashKey(destination, h); - return destination; - } - - function copyElement(source) { - // Simple values - if (!isObject(source)) { - return source; - } - - // Already copied values - var index = stackSource.indexOf(source); - if (index !== -1) { - return stackDest[index]; - } - - if (isWindow(source) || isScope(source)) { - throw ngMinErr('cpws', - "Can't copy! Making copies of Window or Scope instances is not supported."); - } - - var needsRecurse = false; - var destination; - - if (isArray(source)) { - destination = []; - needsRecurse = true; - } else if (isTypedArray(source)) { - destination = new source.constructor(source); - } else if (isDate(source)) { - destination = new Date(source.getTime()); - } else if (isRegExp(source)) { - destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]); - destination.lastIndex = source.lastIndex; - } else if (isFunction(source.cloneNode)) { - destination = source.cloneNode(true); - } else { - destination = Object.create(getPrototypeOf(source)); - needsRecurse = true; - } - - stackSource.push(source); - stackDest.push(destination); - - return needsRecurse - ? copyRecurse(source, destination) - : destination; - } -} - -/** - * 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; -} - - -/** - * @ngdoc function - * @name angular.equals - * @module ng - * @kind function - * - * @description - * Determines if two objects or two values are equivalent. Supports value types, regular - * expressions, arrays and objects. - * - * Two objects or values are considered equivalent if at least one of the following is true: - * - * * Both objects or values pass `===` comparison. - * * Both objects or values are of the same type and all of their properties are equal by - * comparing them with `angular.equals`. - * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal) - * * Both values represent the same regular expression (In JavaScript, - * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual - * representation matches). - * - * During a property comparison, properties of `function` type and properties with names - * that begin with `$` are ignored. - * - * Scope and DOMWindow objects are being compared only by identify (`===`). - * - * @param {*} o1 Object or value to compare. - * @param {*} o2 Object or value to compare. - * @returns {boolean} True if arguments are equal. - */ -function equals(o1, o2) { - if (o1 === o2) return true; - if (o1 === null || o2 === null) return false; - if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN - var t1 = typeof o1, t2 = typeof o2, length, key, keySet; - if (t1 == t2) { - if (t1 == 'object') { - if (isArray(o1)) { - if (!isArray(o2)) return false; - if ((length = o1.length) == o2.length) { - for (key = 0; key < length; key++) { - if (!equals(o1[key], o2[key])) return false; - } - return true; - } - } else if (isDate(o1)) { - if (!isDate(o2)) return false; - return equals(o1.getTime(), o2.getTime()); - } else if (isRegExp(o1)) { - return isRegExp(o2) ? o1.toString() == o2.toString() : false; - } else { - if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || - isArray(o2) || isDate(o2) || isRegExp(o2)) return false; - keySet = createMap(); - for (key in o1) { - if (key.charAt(0) === '$' || isFunction(o1[key])) continue; - if (!equals(o1[key], o2[key])) return false; - keySet[key] = true; - } - for (key in o2) { - if (!(key in keySet) && - key.charAt(0) !== '$' && - isDefined(o2[key]) && - !isFunction(o2[key])) return false; - } - return true; - } - } - } - return false; -} - -var csp = function() { - if (!isDefined(csp.rules)) { - - - var ngCspElement = (document.querySelector('[ng-csp]') || - document.querySelector('[data-ng-csp]')); - - if (ngCspElement) { - var ngCspAttribute = ngCspElement.getAttribute('ng-csp') || - ngCspElement.getAttribute('data-ng-csp'); - csp.rules = { - noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1), - noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1) - }; - } else { - csp.rules = { - noUnsafeEval: noUnsafeEval(), - noInlineStyle: false - }; - } - } - - return csp.rules; - - function noUnsafeEval() { - try { - /* jshint -W031, -W054 */ - new Function(''); - /* jshint +W031, +W054 */ - return false; - } catch (e) { - return true; - } - } -}; - -/** - * @ngdoc directive - * @module ng - * @name ngJq - * - * @element ANY - * @param {string=} ngJq the name of the library available under `window` - * to be used for angular.element - * @description - * Use this directive to force the angular.element library. This should be - * used to force either jqLite by leaving ng-jq blank or setting the name of - * the jquery variable under window (eg. jQuery). - * - * Since angular looks for this directive when it is loaded (doesn't wait for the - * DOMContentLoaded event), it must be placed on an element that comes before the script - * which loads angular. Also, only the first instance of `ng-jq` will be used and all - * others ignored. - * - * @example - * This example shows how to force jqLite using the `ngJq` directive to the `html` tag. - ```html - - - ... - ... - - ``` - * @example - * This example shows how to use a jQuery based library of a different name. - * The library name must be available at the top most 'window'. - ```html - - - ... - ... - - ``` - */ -var jq = function() { - if (isDefined(jq.name_)) return jq.name_; - var el; - var i, ii = ngAttrPrefixes.length, prefix, name; - for (i = 0; i < ii; ++i) { - prefix = ngAttrPrefixes[i]; - if (el = document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]')) { - name = el.getAttribute(prefix + 'jq'); - break; - } - } - - return (jq.name_ = name); -}; - -function concat(array1, array2, index) { - return array1.concat(slice.call(array2, index)); -} - -function sliceArgs(args, startIndex) { - return slice.call(args, startIndex || 0); -} - - -/* jshint -W101 */ -/** - * @ngdoc function - * @name angular.bind - * @module ng - * @kind function - * - * @description - * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for - * `fn`). You can supply optional `args` that are prebound to the function. This feature is also - * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as - * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application). - * - * @param {Object} self Context which `fn` should be evaluated in. - * @param {function()} fn Function to be bound. - * @param {...*} args Optional arguments to be prebound to the `fn` function call. - * @returns {function()} Function that wraps the `fn` with all the specified bindings. - */ -/* jshint +W101 */ -function bind(self, fn) { - var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : []; - if (isFunction(fn) && !(fn instanceof RegExp)) { - return curryArgs.length - ? function() { - return arguments.length - ? fn.apply(self, concat(curryArgs, arguments, 0)) - : fn.apply(self, curryArgs); - } - : function() { - return arguments.length - ? fn.apply(self, arguments) - : fn.call(self); - }; - } else { - // in IE, native methods are not functions so they cannot be bound (note: they don't need to be) - return fn; - } -} - - -function toJsonReplacer(key, value) { - var val = value; - - if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') { - val = undefined; - } else if (isWindow(value)) { - val = '$WINDOW'; - } else if (value && document === value) { - val = '$DOCUMENT'; - } else if (isScope(value)) { - val = '$SCOPE'; - } - - return val; -} - - -/** - * @ngdoc function - * @name angular.toJson - * @module ng - * @kind function - * - * @description - * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be - * stripped since angular uses this notation internally. - * - * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON. - * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace. - * If set to an integer, the JSON output will contain that many spaces per indentation. - * @returns {string|undefined} JSON-ified string representing `obj`. - */ -function toJson(obj, pretty) { - if (typeof obj === 'undefined') return undefined; - if (!isNumber(pretty)) { - pretty = pretty ? 2 : null; - } - return JSON.stringify(obj, toJsonReplacer, pretty); -} - - -/** - * @ngdoc function - * @name angular.fromJson - * @module ng - * @kind function - * - * @description - * Deserializes a JSON string. - * - * @param {string} json JSON string to deserialize. - * @returns {Object|Array|string|number} Deserialized JSON string. - */ -function fromJson(json) { - return isString(json) - ? JSON.parse(json) - : json; -} - - -function timezoneToOffset(timezone, fallback) { - var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000; - return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset; -} - - -function addDateMinutes(date, minutes) { - date = new Date(date.getTime()); - date.setMinutes(date.getMinutes() + minutes); - return date; -} - - -function convertTimezoneToLocal(date, timezone, reverse) { - reverse = reverse ? -1 : 1; - var timezoneOffset = timezoneToOffset(timezone, date.getTimezoneOffset()); - return addDateMinutes(date, reverse * (timezoneOffset - date.getTimezoneOffset())); -} - - -/** - * @returns {string} Returns the string representation of the element. - */ -function startingTag(element) { - element = jqLite(element).clone(); - try { - // turns out IE does not let you set .html() on elements which - // are not allowed to have children. So we just ignore it. - element.empty(); - } catch (e) {} - var elemHtml = jqLite('
').append(element).html(); - try { - return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) : - elemHtml. - match(/^(<[^>]+>)/)[1]. - replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); }); - } catch (e) { - return lowercase(elemHtml); - } - -} - - -///////////////////////////////////////////////// - -/** - * Tries to decode the URI component without throwing an exception. - * - * @private - * @param str value potential URI component to check. - * @returns {boolean} True if `value` can be decoded - * with the decodeURIComponent function. - */ -function tryDecodeURIComponent(value) { - try { - return decodeURIComponent(value); - } catch (e) { - // Ignore any invalid uri component - } -} - - -/** - * Parses an escaped url query string into key-value pairs. - * @returns {Object.} - */ -function parseKeyValue(/**string*/keyValue) { - var obj = {}; - forEach((keyValue || "").split('&'), function(keyValue) { - var splitPoint, key, val; - if (keyValue) { - key = keyValue = keyValue.replace(/\+/g,'%20'); - splitPoint = keyValue.indexOf('='); - if (splitPoint !== -1) { - key = keyValue.substring(0, splitPoint); - val = keyValue.substring(splitPoint + 1); - } - key = tryDecodeURIComponent(key); - if (isDefined(key)) { - val = isDefined(val) ? tryDecodeURIComponent(val) : true; - if (!hasOwnProperty.call(obj, key)) { - obj[key] = val; - } else if (isArray(obj[key])) { - obj[key].push(val); - } else { - obj[key] = [obj[key],val]; - } - } - } - }); - return obj; -} - -function toKeyValue(obj) { - var parts = []; - forEach(obj, function(value, key) { - if (isArray(value)) { - forEach(value, function(arrayValue) { - parts.push(encodeUriQuery(key, true) + - (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true))); - }); - } else { - parts.push(encodeUriQuery(key, true) + - (value === true ? '' : '=' + encodeUriQuery(value, true))); - } - }); - return parts.length ? parts.join('&') : ''; -} - - -/** - * We need our custom method because encodeURIComponent is too aggressive and doesn't follow - * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path - * segments: - * segment = *pchar - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * pct-encoded = "%" HEXDIG HEXDIG - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - * / "*" / "+" / "," / ";" / "=" - */ -function encodeUriSegment(val) { - return encodeUriQuery(val, true). - replace(/%26/gi, '&'). - replace(/%3D/gi, '='). - replace(/%2B/gi, '+'); -} - - -/** - * This method is intended for encoding *key* or *value* parts of query component. We need a custom - * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be - * encoded per http://tools.ietf.org/html/rfc3986: - * query = *( pchar / "/" / "?" ) - * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" - * pct-encoded = "%" HEXDIG HEXDIG - * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - * / "*" / "+" / "," / ";" / "=" - */ -function encodeUriQuery(val, pctEncodeSpaces) { - return encodeURIComponent(val). - replace(/%40/gi, '@'). - replace(/%3A/gi, ':'). - replace(/%24/g, '$'). - replace(/%2C/gi, ','). - replace(/%3B/gi, ';'). - replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); -} - -var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-']; - -function getNgAttribute(element, ngAttr) { - var attr, i, ii = ngAttrPrefixes.length; - for (i = 0; i < ii; ++i) { - attr = ngAttrPrefixes[i] + ngAttr; - if (isString(attr = element.getAttribute(attr))) { - return attr; - } - } - return null; -} - -/** - * @ngdoc directive - * @name ngApp - * @module ng - * - * @element ANY - * @param {angular.Module} ngApp an optional application - * {@link angular.module module} name to load. - * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be - * created in "strict-di" mode. This means that the application will fail to invoke functions which - * do not use explicit function annotation (and are thus unsuitable for minification), as described - * in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in - * tracking down the root of these bugs. - * - * @description - * - * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive - * designates the **root element** of the application and is typically placed near the root element - * of the page - e.g. on the `` or `` tags. - * - * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp` - * found in the document will be used to define the root element to auto-bootstrap as an - * application. To run multiple applications in an HTML document you must manually bootstrap them using - * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other. - * - * You can specify an **AngularJS module** to be used as the root module for the application. This - * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It - * should contain the application code needed or have dependencies on other modules that will - * contain the code. See {@link angular.module} for more information. - * - * In the example below if the `ngApp` directive were not placed on the `html` element then the - * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}` - * would not be resolved to `3`. - * - * `ngApp` is the easiest, and most common way to bootstrap an application. - * - - -
- I can add: {{a}} + {{b}} = {{ a+b }} -
-
- - angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) { - $scope.a = 1; - $scope.b = 2; - }); - -
- * - * Using `ngStrictDi`, you would see something like this: - * - - -
-
- I can add: {{a}} + {{b}} = {{ a+b }} - -

This renders because the controller does not fail to - instantiate, by using explicit annotation style (see - script.js for details) -

-
- -
- Name:
- Hello, {{name}}! - -

This renders because the controller does not fail to - instantiate, by using explicit annotation style - (see script.js for details) -

-
- -
- I can add: {{a}} + {{b}} = {{ a+b }} - -

The controller could not be instantiated, due to relying - on automatic function annotations (which are disabled in - strict mode). As such, the content of this section is not - interpolated, and there should be an error in your web console. -

-
-
-
- - angular.module('ngAppStrictDemo', []) - // BadController will fail to instantiate, due to relying on automatic function annotation, - // rather than an explicit annotation - .controller('BadController', function($scope) { - $scope.a = 1; - $scope.b = 2; - }) - // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated, - // due to using explicit annotations using the array style and $inject property, respectively. - .controller('GoodController1', ['$scope', function($scope) { - $scope.a = 1; - $scope.b = 2; - }]) - .controller('GoodController2', GoodController2); - function GoodController2($scope) { - $scope.name = "World"; - } - GoodController2.$inject = ['$scope']; - - - div[ng-controller] { - margin-bottom: 1em; - -webkit-border-radius: 4px; - border-radius: 4px; - border: 1px solid; - padding: .5em; - } - div[ng-controller^=Good] { - border-color: #d6e9c6; - background-color: #dff0d8; - color: #3c763d; - } - div[ng-controller^=Bad] { - border-color: #ebccd1; - background-color: #f2dede; - color: #a94442; - margin-bottom: 0; - } - -
- */ -function angularInit(element, bootstrap) { - var appElement, - module, - config = {}; - - // The element `element` has priority over any other element - forEach(ngAttrPrefixes, function(prefix) { - var name = prefix + 'app'; - - if (!appElement && element.hasAttribute && element.hasAttribute(name)) { - appElement = element; - module = element.getAttribute(name); - } - }); - forEach(ngAttrPrefixes, function(prefix) { - var name = prefix + 'app'; - var candidate; - - if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) { - appElement = candidate; - module = candidate.getAttribute(name); - } - }); - if (appElement) { - config.strictDi = getNgAttribute(appElement, "strict-di") !== null; - bootstrap(appElement, module ? [module] : [], config); - } -} - -/** - * @ngdoc function - * @name angular.bootstrap - * @module ng - * @description - * Use this function to manually start up angular application. - * - * See: {@link guide/bootstrap Bootstrap} - * - * Note that Protractor based end-to-end tests cannot use this function to bootstrap manually. - * They must use {@link ng.directive:ngApp ngApp}. - * - * Angular will detect if it has been loaded into the browser more than once and only allow the - * first loaded script to be bootstrapped and will report a warning to the browser console for - * each of the subsequent scripts. This prevents strange results in applications, where otherwise - * multiple instances of Angular try to work on the DOM. - * - * ```html - * - * - * - *
- * {{greeting}} - *
- * - * - * - * - * - * ``` - * - * @param {DOMElement} element DOM element which is the root of angular application. - * @param {Array=} modules an array of modules to load into the application. - * Each item in the array should be the name of a predefined module or a (DI annotated) - * function that will be invoked by the injector as a `config` block. - * See: {@link angular.module modules} - * @param {Object=} config an object for defining configuration options for the application. The - * following keys are supported: - * - * * `strictDi` - disable automatic function annotation for the application. This is meant to - * assist in finding bugs which break minified code. Defaults to `false`. - * - * @returns {auto.$injector} Returns the newly created injector for this app. - */ -function bootstrap(element, modules, config) { - if (!isObject(config)) config = {}; - var defaultConfig = { - strictDi: false - }; - config = extend(defaultConfig, config); - var doBootstrap = function() { - element = jqLite(element); - - if (element.injector()) { - var tag = (element[0] === document) ? 'document' : startingTag(element); - //Encode angle brackets to prevent input from being sanitized to empty string #8683 - throw ngMinErr( - 'btstrpd', - "App Already Bootstrapped with this Element '{0}'", - tag.replace(//,'>')); - } - - modules = modules || []; - modules.unshift(['$provide', function($provide) { - $provide.value('$rootElement', element); - }]); - - if (config.debugInfoEnabled) { - // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`. - modules.push(['$compileProvider', function($compileProvider) { - $compileProvider.debugInfoEnabled(true); - }]); - } - - modules.unshift('ng'); - var injector = createInjector(modules, config.strictDi); - injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector', - function bootstrapApply(scope, element, compile, injector) { - scope.$apply(function() { - element.data('$injector', injector); - compile(element)(scope); - }); - }] - ); - return injector; - }; - - var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/; - var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/; - - if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) { - config.debugInfoEnabled = true; - window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, ''); - } - - if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) { - return doBootstrap(); - } - - window.name = window.name.replace(NG_DEFER_BOOTSTRAP, ''); - angular.resumeBootstrap = function(extraModules) { - forEach(extraModules, function(module) { - modules.push(module); - }); - return doBootstrap(); - }; - - if (isFunction(angular.resumeDeferredBootstrap)) { - angular.resumeDeferredBootstrap(); - } -} - -/** - * @ngdoc function - * @name angular.reloadWithDebugInfo - * @module ng - * @description - * Use this function to reload the current application with debug information turned on. - * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`. - * - * See {@link ng.$compileProvider#debugInfoEnabled} for more. - */ -function reloadWithDebugInfo() { - window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name; - window.location.reload(); -} - -/** - * @name angular.getTestability - * @module ng - * @description - * Get the testability service for the instance of Angular on the given - * element. - * @param {DOMElement} element DOM element which is the root of angular application. - */ -function getTestability(rootElement) { - var injector = angular.element(rootElement).injector(); - if (!injector) { - throw ngMinErr('test', - 'no injector found for element argument to getTestability'); - } - return injector.get('$$testability'); -} - -var SNAKE_CASE_REGEXP = /[A-Z]/g; -function snake_case(name, separator) { - separator = separator || '_'; - return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) { - return (pos ? separator : '') + letter.toLowerCase(); - }); -} - -var bindJQueryFired = false; -function bindJQuery() { - var originalCleanData; - - if (bindJQueryFired) { - return; - } - - // bind to jQuery if present; - var jqName = jq(); - jQuery = isUndefined(jqName) ? window.jQuery : // use jQuery (if present) - !jqName ? undefined : // use jqLite - window[jqName]; // use jQuery specified by `ngJq` - - // Use jQuery if it exists with proper functionality, otherwise default to us. - // Angular 1.2+ requires jQuery 1.7+ for on()/off() support. - // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older - // versions. It will not work for sure with jQuery <1.7, though. - if (jQuery && jQuery.fn.on) { - jqLite = jQuery; - extend(jQuery.fn, { - scope: JQLitePrototype.scope, - isolateScope: JQLitePrototype.isolateScope, - controller: JQLitePrototype.controller, - injector: JQLitePrototype.injector, - inheritedData: JQLitePrototype.inheritedData - }); - - // All nodes removed from the DOM via various jQuery APIs like .remove() - // are passed through jQuery.cleanData. Monkey-patch this method to fire - // the $destroy event on all removed nodes. - originalCleanData = jQuery.cleanData; - jQuery.cleanData = function(elems) { - var events; - for (var i = 0, elem; (elem = elems[i]) != null; i++) { - events = jQuery._data(elem, "events"); - if (events && events.$destroy) { - jQuery(elem).triggerHandler('$destroy'); - } - } - originalCleanData(elems); - }; - } else { - jqLite = JQLite; - } - - angular.element = jqLite; - - // Prevent double-proxying. - bindJQueryFired = true; -} - -/** - * throw error if the argument is falsy. - */ -function assertArg(arg, name, reason) { - if (!arg) { - throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required")); - } - return arg; -} - -function assertArgFn(arg, name, acceptArrayAnnotation) { - if (acceptArrayAnnotation && isArray(arg)) { - arg = arg[arg.length - 1]; - } - - assertArg(isFunction(arg), name, 'not a function, got ' + - (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg)); - return arg; -} - -/** - * throw error if the name given is hasOwnProperty - * @param {String} name the name to test - * @param {String} context the context in which the name is used, such as module or directive - */ -function assertNotHasOwnProperty(name, context) { - if (name === 'hasOwnProperty') { - throw ngMinErr('badname', "hasOwnProperty is not a valid {0} name", context); - } -} - -/** - * Return the value accessible from the object by path. Any undefined traversals are ignored - * @param {Object} obj starting object - * @param {String} path path to traverse - * @param {boolean} [bindFnToScope=true] - * @returns {Object} value as accessible by path - */ -//TODO(misko): this function needs to be removed -function getter(obj, path, bindFnToScope) { - if (!path) return obj; - var keys = path.split('.'); - var key; - var lastInstance = obj; - var len = keys.length; - - for (var i = 0; i < len; i++) { - key = keys[i]; - if (obj) { - obj = (lastInstance = obj)[key]; - } - } - if (!bindFnToScope && isFunction(obj)) { - return bind(lastInstance, obj); - } - return obj; -} - -/** - * Return the DOM siblings between the first and last node in the given array. - * @param {Array} array like object - * @returns {Array} the inputted object or a jqLite collection containing the nodes - */ -function getBlockNodes(nodes) { - // TODO(perf): update `nodes` instead of creating a new object? - var node = nodes[0]; - var endNode = nodes[nodes.length - 1]; - var blockNodes; - - for (var i = 1; node !== endNode && (node = node.nextSibling); i++) { - if (blockNodes || nodes[i] !== node) { - if (!blockNodes) { - blockNodes = jqLite(slice.call(nodes, 0, i)); - } - blockNodes.push(node); - } - } - - return blockNodes || nodes; -} - - -/** - * Creates a new object without a prototype. This object is useful for lookup without having to - * guard against prototypically inherited properties via hasOwnProperty. - * - * Related micro-benchmarks: - * - http://jsperf.com/object-create2 - * - http://jsperf.com/proto-map-lookup/2 - * - http://jsperf.com/for-in-vs-object-keys2 - * - * @returns {Object} - */ -function createMap() { - return Object.create(null); -} - -var NODE_TYPE_ELEMENT = 1; -var NODE_TYPE_ATTRIBUTE = 2; -var NODE_TYPE_TEXT = 3; -var NODE_TYPE_COMMENT = 8; -var NODE_TYPE_DOCUMENT = 9; -var NODE_TYPE_DOCUMENT_FRAGMENT = 11; - -/** - * @ngdoc type - * @name angular.Module - * @module ng - * @description - * - * Interface for configuring angular {@link angular.module modules}. - */ - -function setupModuleLoader(window) { - - var $injectorMinErr = minErr('$injector'); - var ngMinErr = minErr('ng'); - - function ensure(obj, name, factory) { - return obj[name] || (obj[name] = factory()); - } - - var angular = ensure(window, 'angular', Object); - - // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap - angular.$$minErr = angular.$$minErr || minErr; - - return ensure(angular, 'module', function() { - /** @type {Object.} */ - var modules = {}; - - /** - * @ngdoc function - * @name angular.module - * @module ng - * @description - * - * The `angular.module` is a global place for creating, registering and retrieving Angular - * modules. - * All modules (angular core or 3rd party) that should be available to an application must be - * registered using this mechanism. - * - * Passing one argument retrieves an existing {@link angular.Module}, - * whereas passing more than one argument creates a new {@link angular.Module} - * - * - * # Module - * - * A module is a collection of services, directives, controllers, filters, and configuration information. - * `angular.module` is used to configure the {@link auto.$injector $injector}. - * - * ```js - * // Create a new module - * var myModule = angular.module('myModule', []); - * - * // register a new service - * myModule.value('appName', 'MyCoolApp'); - * - * // configure existing services inside initialization blocks. - * myModule.config(['$locationProvider', function($locationProvider) { - * // Configure existing providers - * $locationProvider.hashPrefix('!'); - * }]); - * ``` - * - * Then you can create an injector and load your modules like this: - * - * ```js - * var injector = angular.injector(['ng', 'myModule']) - * ``` - * - * However it's more likely that you'll just use - * {@link ng.directive:ngApp ngApp} or - * {@link angular.bootstrap} to simplify this process for you. - * - * @param {!string} name The name of the module to create or retrieve. - * @param {!Array.=} requires If specified then new module is being created. If - * unspecified then the module is being retrieved for further configuration. - * @param {Function=} configFn Optional configuration function for the module. Same as - * {@link angular.Module#config Module#config()}. - * @returns {module} new module with the {@link angular.Module} api. - */ - return function module(name, requires, configFn) { - var assertNotHasOwnProperty = function(name, context) { - if (name === 'hasOwnProperty') { - throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); - } - }; - - assertNotHasOwnProperty(name, 'module'); - if (requires && modules.hasOwnProperty(name)) { - modules[name] = null; - } - return ensure(modules, name, function() { - if (!requires) { - throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " + - "the module name or forgot to load it. If registering a module ensure that you " + - "specify the dependencies as the second argument.", name); - } - - /** @type {!Array.>} */ - var invokeQueue = []; - - /** @type {!Array.} */ - var configBlocks = []; - - /** @type {!Array.} */ - var runBlocks = []; - - var config = invokeLater('$injector', 'invoke', 'push', configBlocks); - - /** @type {angular.Module} */ - var moduleInstance = { - // Private state - _invokeQueue: invokeQueue, - _configBlocks: configBlocks, - _runBlocks: runBlocks, - - /** - * @ngdoc property - * @name angular.Module#requires - * @module ng - * - * @description - * Holds the list of modules which the injector will load before the current module is - * loaded. - */ - requires: requires, - - /** - * @ngdoc property - * @name angular.Module#name - * @module ng - * - * @description - * Name of the module. - */ - name: name, - - - /** - * @ngdoc method - * @name angular.Module#provider - * @module ng - * @param {string} name service name - * @param {Function} providerType Construction function for creating new instance of the - * service. - * @description - * See {@link auto.$provide#provider $provide.provider()}. - */ - provider: invokeLaterAndSetModuleName('$provide', 'provider'), - - /** - * @ngdoc method - * @name angular.Module#factory - * @module ng - * @param {string} name service name - * @param {Function} providerFunction Function for creating new instance of the service. - * @description - * See {@link auto.$provide#factory $provide.factory()}. - */ - factory: invokeLaterAndSetModuleName('$provide', 'factory'), - - /** - * @ngdoc method - * @name angular.Module#service - * @module ng - * @param {string} name service name - * @param {Function} constructor A constructor function that will be instantiated. - * @description - * See {@link auto.$provide#service $provide.service()}. - */ - service: invokeLaterAndSetModuleName('$provide', 'service'), - - /** - * @ngdoc method - * @name angular.Module#value - * @module ng - * @param {string} name service name - * @param {*} object Service instance object. - * @description - * See {@link auto.$provide#value $provide.value()}. - */ - value: invokeLater('$provide', 'value'), - - /** - * @ngdoc method - * @name angular.Module#constant - * @module ng - * @param {string} name constant name - * @param {*} object Constant value. - * @description - * Because the constants are fixed, they get applied before other provide methods. - * See {@link auto.$provide#constant $provide.constant()}. - */ - constant: invokeLater('$provide', 'constant', 'unshift'), - - /** - * @ngdoc method - * @name angular.Module#decorator - * @module ng - * @param {string} The name of the service to decorate. - * @param {Function} This function will be invoked when the service needs to be - * instantiated and should return the decorated service instance. - * @description - * See {@link auto.$provide#decorator $provide.decorator()}. - */ - decorator: invokeLaterAndSetModuleName('$provide', 'decorator'), - - /** - * @ngdoc method - * @name angular.Module#animation - * @module ng - * @param {string} name animation name - * @param {Function} animationFactory Factory function for creating new instance of an - * animation. - * @description - * - * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. - * - * - * Defines an animation hook that can be later used with - * {@link $animate $animate} service and directives that use this service. - * - * ```js - * module.animation('.animation-name', function($inject1, $inject2) { - * return { - * eventName : function(element, done) { - * //code to run the animation - * //once complete, then run done() - * return function cancellationFunction(element) { - * //code to cancel the animation - * } - * } - * } - * }) - * ``` - * - * See {@link ng.$animateProvider#register $animateProvider.register()} and - * {@link ngAnimate ngAnimate module} for more information. - */ - animation: invokeLaterAndSetModuleName('$animateProvider', 'register'), - - /** - * @ngdoc method - * @name angular.Module#filter - * @module ng - * @param {string} name Filter name - this must be a valid angular expression identifier - * @param {Function} filterFactory Factory function for creating new instance of filter. - * @description - * See {@link ng.$filterProvider#register $filterProvider.register()}. - * - *
- * **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`). - *
- */ - filter: invokeLaterAndSetModuleName('$filterProvider', 'register'), - - /** - * @ngdoc method - * @name angular.Module#controller - * @module ng - * @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} constructor Controller constructor function. - * @description - * See {@link ng.$controllerProvider#register $controllerProvider.register()}. - */ - controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'), - - /** - * @ngdoc method - * @name angular.Module#directive - * @module ng - * @param {string|Object} name Directive name, or an object map of directives where the - * keys are the names and the values are the factories. - * @param {Function} directiveFactory Factory function for creating new instance of - * directives. - * @description - * See {@link ng.$compileProvider#directive $compileProvider.directive()}. - */ - directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'), - - /** - * @ngdoc method - * @name angular.Module#component - * @module ng - * @param {string} name Name of the component in camel-case (i.e. myComp which will match as my-comp) - * @param {Object} options Component definition object (a simplified - * {@link ng.$compile#directive-definition-object directive definition object}), - * has 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. Empty function by default. - * - `controllerAs` – `{string=}` – An identifier name for a reference to the controller. - * If present, the controller will be published to scope under the `controllerAs` name. - * If not present, this will default to be the same as the component name. - * - `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=}` – Define DOM attribute binding to component properties. - * Component properties are always bound to the component controller and not to the scope. - * - `transclude` – `{boolean=}` – Whether {@link $compile#transclusion transclusion} is enabled. - * Enabled by default. - * - `isolate` – `{boolean=}` – Whether the new scope is isolated. Isolated by default. - * - `restrict` - `{string=}` - String of subset of {@link ng.$compile#-restrict- EACM} which - * restricts the component to specific directive declaration style. If omitted, this defaults to 'E'. - * - `$canActivate` – `{function()=}` – TBD. - * - `$routeConfig` – `{object=}` – TBD. - * - * @description - * Register a component definition with the compiler. This is short for registering a specific - * subset of directives which represents actual UI components in your application. Component - * definitions are very simple and do not require the complexity behind defining directives. - * Component definitions usually consist only of the template and the controller backing it. - * In order to make the definition easier, components enforce best practices like controllerAs - * and default behaviors like scope isolation, restrict to elements and allow transclusion. - * - * Here are a few examples of how you would usually define components: - * - * ```js - * var myMod = angular.module(...); - * myMod.component('myComp', { - * template: '
My name is {{myComp.name}}
', - * controller: function() { - * this.name = 'shahar'; - * } - * }); - * - * myMod.component('myComp', { - * template: '
My name is {{myComp.name}}
', - * bindings: {name: '@'} - * }); - * - * myMod.component('myComp', { - * templateUrl: 'views/my-comp.html', - * controller: 'MyCtrl as ctrl', - * bindings: {name: '@'} - * }); - * - * ``` - * - * See {@link ng.$compileProvider#directive $compileProvider.directive()}. - */ - component: function(name, options) { - function factory($injector) { - function makeInjectable(fn) { - if (angular.isFunction(fn)) { - return function(tElement, tAttrs) { - return $injector.invoke(fn, this, {$element: tElement, $attrs: tAttrs}); - }; - } else { - return fn; - } - } - - var template = (!options.template && !options.templateUrl ? '' : options.template); - return { - controller: options.controller || function() {}, - controllerAs: identifierForController(options.controller) || options.controllerAs || name, - template: makeInjectable(template), - templateUrl: makeInjectable(options.templateUrl), - transclude: options.transclude === undefined ? true : options.transclude, - scope: options.isolate === false ? true : {}, - bindToController: options.bindings || {}, - restrict: options.restrict || 'E' - }; - } - - if (options.$canActivate) { - factory.$canActivate = options.$canActivate; - } - if (options.$routeConfig) { - factory.$routeConfig = options.$routeConfig; - } - factory.$inject = ['$injector']; - - return moduleInstance.directive(name, factory); - }, - - /** - * @ngdoc method - * @name angular.Module#config - * @module ng - * @param {Function} configFn Execute this function on module load. Useful for service - * configuration. - * @description - * Use this method to register work which needs to be performed on module loading. - * For more about how to configure services, see - * {@link providers#provider-recipe Provider Recipe}. - */ - config: config, - - /** - * @ngdoc method - * @name angular.Module#run - * @module ng - * @param {Function} initializationFn Execute this function after injector creation. - * Useful for application initialization. - * @description - * Use this method to register work which should be performed when the injector is done - * loading all modules. - */ - run: function(block) { - runBlocks.push(block); - return this; - } - }; - - if (configFn) { - config(configFn); - } - - return moduleInstance; - - /** - * @param {string} provider - * @param {string} method - * @param {String=} insertMethod - * @returns {angular.Module} - */ - function invokeLater(provider, method, insertMethod, queue) { - if (!queue) queue = invokeQueue; - return function() { - queue[insertMethod || 'push']([provider, method, arguments]); - return moduleInstance; - }; - } - - /** - * @param {string} provider - * @param {string} method - * @returns {angular.Module} - */ - function invokeLaterAndSetModuleName(provider, method) { - return function(recipeName, factoryFunction) { - if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name; - invokeQueue.push([provider, method, arguments]); - return moduleInstance; - }; - } - }); - }; - }); - -} - -/* global: toDebugString: true */ - -function serializeObject(obj) { - var seen = []; - - return JSON.stringify(obj, function(key, val) { - val = toJsonReplacer(key, val); - if (isObject(val)) { - - if (seen.indexOf(val) >= 0) return '...'; - - seen.push(val); - } - return val; - }); -} - -function toDebugString(obj) { - if (typeof obj === 'function') { - return obj.toString().replace(/ \{[\s\S]*$/, ''); - } else if (isUndefined(obj)) { - return 'undefined'; - } else if (typeof obj !== 'string') { - return serializeObject(obj); - } - return obj; -} - -/* global angularModule: true, - version: true, - - $CompileProvider, - - htmlAnchorDirective, - inputDirective, - inputDirective, - formDirective, - scriptDirective, - selectDirective, - styleDirective, - optionDirective, - ngBindDirective, - ngBindHtmlDirective, - ngBindTemplateDirective, - ngClassDirective, - ngClassEvenDirective, - ngClassOddDirective, - ngCloakDirective, - ngControllerDirective, - ngFormDirective, - ngHideDirective, - ngIfDirective, - ngIncludeDirective, - ngIncludeFillContentDirective, - ngInitDirective, - ngNonBindableDirective, - ngPluralizeDirective, - ngRepeatDirective, - ngShowDirective, - ngStyleDirective, - ngSwitchDirective, - ngSwitchWhenDirective, - ngSwitchDefaultDirective, - ngOptionsDirective, - ngTranscludeDirective, - ngModelDirective, - ngListDirective, - ngChangeDirective, - patternDirective, - patternDirective, - requiredDirective, - requiredDirective, - minlengthDirective, - minlengthDirective, - maxlengthDirective, - maxlengthDirective, - ngValueDirective, - ngModelOptionsDirective, - ngAttributeAliasDirectives, - ngEventDirectives, - - $AnchorScrollProvider, - $AnimateProvider, - $CoreAnimateCssProvider, - $$CoreAnimateQueueProvider, - $$AnimateRunnerFactoryProvider, - $$AnimateAsyncRunFactoryProvider, - $BrowserProvider, - $CacheFactoryProvider, - $ControllerProvider, - $DateProvider, - $DocumentProvider, - $ExceptionHandlerProvider, - $FilterProvider, - $$ForceReflowProvider, - $InterpolateProvider, - $IntervalProvider, - $$HashMapProvider, - $HttpProvider, - $HttpParamSerializerProvider, - $HttpParamSerializerJQLikeProvider, - $HttpBackendProvider, - $xhrFactoryProvider, - $LocationProvider, - $LogProvider, - $ParseProvider, - $RootScopeProvider, - $QProvider, - $$QProvider, - $$SanitizeUriProvider, - $SceProvider, - $SceDelegateProvider, - $SnifferProvider, - $TemplateCacheProvider, - $TemplateRequestProvider, - $$TestabilityProvider, - $TimeoutProvider, - $$RAFProvider, - $WindowProvider, - $$jqLiteProvider, - $$CookieReaderProvider -*/ - - -/** - * @ngdoc object - * @name angular.version - * @module ng - * @description - * An object that contains information about the current AngularJS version. - * - * This object has the following properties: - * - * - `full` – `{string}` – Full version string, such as "0.9.18". - * - `major` – `{number}` – Major version number, such as "0". - * - `minor` – `{number}` – Minor version number, such as "9". - * - `dot` – `{number}` – Dot version number, such as "18". - * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". - */ -var version = { - full: '1.5.0-rc.0', // all of these placeholder strings will be replaced by grunt's - major: 1, // package task - minor: 5, - dot: 0, - codeName: 'oblong-panoptikum' -}; - - -function publishExternalAPI(angular) { - extend(angular, { - 'bootstrap': bootstrap, - 'copy': copy, - 'extend': extend, - 'merge': merge, - 'equals': equals, - 'element': jqLite, - 'forEach': forEach, - 'injector': createInjector, - 'noop': noop, - 'bind': bind, - 'toJson': toJson, - 'fromJson': fromJson, - 'identity': identity, - 'isUndefined': isUndefined, - 'isDefined': isDefined, - 'isString': isString, - 'isFunction': isFunction, - 'isObject': isObject, - 'isNumber': isNumber, - 'isElement': isElement, - 'isArray': isArray, - 'version': version, - 'isDate': isDate, - 'lowercase': lowercase, - 'uppercase': uppercase, - 'callbacks': {counter: 0}, - 'getTestability': getTestability, - '$$minErr': minErr, - '$$csp': csp, - 'reloadWithDebugInfo': reloadWithDebugInfo - }); - - angularModule = setupModuleLoader(window); - - angularModule('ng', ['ngLocale'], ['$provide', - function ngModule($provide) { - // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it. - $provide.provider({ - $$sanitizeUri: $$SanitizeUriProvider - }); - $provide.provider('$compile', $CompileProvider). - directive({ - a: htmlAnchorDirective, - input: inputDirective, - textarea: inputDirective, - form: formDirective, - script: scriptDirective, - select: selectDirective, - style: styleDirective, - option: optionDirective, - ngBind: ngBindDirective, - ngBindHtml: ngBindHtmlDirective, - ngBindTemplate: ngBindTemplateDirective, - ngClass: ngClassDirective, - ngClassEven: ngClassEvenDirective, - ngClassOdd: ngClassOddDirective, - ngCloak: ngCloakDirective, - ngController: ngControllerDirective, - ngForm: ngFormDirective, - ngHide: ngHideDirective, - ngIf: ngIfDirective, - ngInclude: ngIncludeDirective, - ngInit: ngInitDirective, - ngNonBindable: ngNonBindableDirective, - ngPluralize: ngPluralizeDirective, - ngRepeat: ngRepeatDirective, - ngShow: ngShowDirective, - ngStyle: ngStyleDirective, - ngSwitch: ngSwitchDirective, - ngSwitchWhen: ngSwitchWhenDirective, - ngSwitchDefault: ngSwitchDefaultDirective, - ngOptions: ngOptionsDirective, - ngTransclude: ngTranscludeDirective, - ngModel: ngModelDirective, - ngList: ngListDirective, - ngChange: ngChangeDirective, - pattern: patternDirective, - ngPattern: patternDirective, - required: requiredDirective, - ngRequired: requiredDirective, - minlength: minlengthDirective, - ngMinlength: minlengthDirective, - maxlength: maxlengthDirective, - ngMaxlength: maxlengthDirective, - ngValue: ngValueDirective, - ngModelOptions: ngModelOptionsDirective - }). - directive({ - ngInclude: ngIncludeFillContentDirective - }). - directive(ngAttributeAliasDirectives). - directive(ngEventDirectives); - $provide.provider({ - $anchorScroll: $AnchorScrollProvider, - $animate: $AnimateProvider, - $animateCss: $CoreAnimateCssProvider, - $$animateQueue: $$CoreAnimateQueueProvider, - $$AnimateRunner: $$AnimateRunnerFactoryProvider, - $$animateAsyncRun: $$AnimateAsyncRunFactoryProvider, - $browser: $BrowserProvider, - $cacheFactory: $CacheFactoryProvider, - $controller: $ControllerProvider, - $document: $DocumentProvider, - $exceptionHandler: $ExceptionHandlerProvider, - $filter: $FilterProvider, - $$forceReflow: $$ForceReflowProvider, - $interpolate: $InterpolateProvider, - $interval: $IntervalProvider, - $http: $HttpProvider, - $httpParamSerializer: $HttpParamSerializerProvider, - $httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider, - $httpBackend: $HttpBackendProvider, - $xhrFactory: $xhrFactoryProvider, - $location: $LocationProvider, - $log: $LogProvider, - $parse: $ParseProvider, - $rootScope: $RootScopeProvider, - $q: $QProvider, - $$q: $$QProvider, - $sce: $SceProvider, - $sceDelegate: $SceDelegateProvider, - $sniffer: $SnifferProvider, - $templateCache: $TemplateCacheProvider, - $templateRequest: $TemplateRequestProvider, - $$testability: $$TestabilityProvider, - $timeout: $TimeoutProvider, - $window: $WindowProvider, - $$rAF: $$RAFProvider, - $$jqLite: $$jqLiteProvider, - $$HashMap: $$HashMapProvider, - $$cookieReader: $$CookieReaderProvider - }); - } - ]); -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * 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? * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* global JQLitePrototype: true, - addEventListenerFn: true, - removeEventListenerFn: true, - BOOLEAN_ATTR: true, - ALIASED_ATTR: true, -*/ - -////////////////////////////////// -//JQLite -////////////////////////////////// - -/** - * @ngdoc function - * @name angular.element - * @module ng - * @kind function - * - * @description - * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element. - * - * If jQuery is available, `angular.element` is an alias for the - * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element` - * delegates to Angular's built-in subset of jQuery, called "jQuery lite" or **jqLite**. - * - * jqLite is a tiny, API-compatible subset of jQuery that allows - * Angular to manipulate the DOM in a cross-browser compatible way. jqLite implements only the most - * commonly needed functionality with the goal of having a very small footprint. - * - * To use `jQuery`, simply ensure it is loaded before the `angular.js` file. You can also use the - * {@link ngJq `ngJq`} directive to specify that jqlite should be used over jQuery, or to use a - * specific version of jQuery if multiple versions exist on the page. - * - *
**Note:** All element references in Angular are always wrapped with jQuery or - * jqLite (such as the element argument in a directive's compile / link function). They are never raw DOM references.
- * - *
**Note:** Keep in mind that this function will not find elements - * by tag name / CSS selector. For lookups by tag name, try instead `angular.element(document).find(...)` - * or `$document.find()`, or use the standard DOM APIs, e.g. `document.querySelectorAll()`.
- * - * ## Angular's jqLite - * jqLite provides only the following jQuery methods: - * - * - [`addClass()`](http://api.jquery.com/addClass/) - * - [`after()`](http://api.jquery.com/after/) - * - [`append()`](http://api.jquery.com/append/) - * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters - * - [`bind()`](http://api.jquery.com/bind/) - Does not support namespaces, selectors or eventData - * - [`children()`](http://api.jquery.com/children/) - Does not support selectors - * - [`clone()`](http://api.jquery.com/clone/) - * - [`contents()`](http://api.jquery.com/contents/) - * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`. - * As a setter, does not convert numbers to strings or append 'px', and also does not have automatic property prefixing. - * - [`data()`](http://api.jquery.com/data/) - * - [`detach()`](http://api.jquery.com/detach/) - * - [`empty()`](http://api.jquery.com/empty/) - * - [`eq()`](http://api.jquery.com/eq/) - * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name - * - [`hasClass()`](http://api.jquery.com/hasClass/) - * - [`html()`](http://api.jquery.com/html/) - * - [`next()`](http://api.jquery.com/next/) - Does not support selectors - * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData - * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces, selectors or event object as parameter - * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors - * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors - * - [`prepend()`](http://api.jquery.com/prepend/) - * - [`prop()`](http://api.jquery.com/prop/) - * - [`ready()`](http://api.jquery.com/ready/) - * - [`remove()`](http://api.jquery.com/remove/) - * - [`removeAttr()`](http://api.jquery.com/removeAttr/) - * - [`removeClass()`](http://api.jquery.com/removeClass/) - * - [`removeData()`](http://api.jquery.com/removeData/) - * - [`replaceWith()`](http://api.jquery.com/replaceWith/) - * - [`text()`](http://api.jquery.com/text/) - * - [`toggleClass()`](http://api.jquery.com/toggleClass/) - * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers. - * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces or event object as parameter - * - [`val()`](http://api.jquery.com/val/) - * - [`wrap()`](http://api.jquery.com/wrap/) - * - * ## jQuery/jqLite Extras - * Angular also provides the following additional methods and events to both jQuery and jqLite: - * - * ### Events - * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event - * on all DOM nodes being removed. This can be used to clean up any 3rd party bindings to the DOM - * element before it is removed. - * - * ### Methods - * - `controller(name)` - retrieves the controller of the current element or its parent. By default - * retrieves controller associated with the `ngController` directive. If `name` is provided as - * camelCase directive name, then the controller for this directive will be retrieved (e.g. - * `'ngModel'`). - * - `injector()` - retrieves the injector of the current element or its parent. - * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current - * element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to - * be enabled. - * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the - * current element. This getter should be used only on elements that contain a directive which starts a new isolate - * scope. Calling `scope()` on this element always returns the original non-isolate scope. - * Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled. - * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top - * parent element is reached. - * - * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery. - * @returns {Object} jQuery object. - */ - -JQLite.expando = 'ng339'; - -var jqCache = JQLite.cache = {}, - jqId = 1, - addEventListenerFn = function(element, type, fn) { - element.addEventListener(type, fn, false); - }, - removeEventListenerFn = function(element, type, fn) { - element.removeEventListener(type, fn, false); - }; - -/* - * !!! This is an undocumented "private" function !!! - */ -JQLite._data = function(node) { - //jQuery always returns an object on cache miss - return this.cache[node[this.expando]] || {}; -}; - -function jqNextId() { return ++jqId; } - - -var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g; -var MOZ_HACK_REGEXP = /^moz([A-Z])/; -var MOUSE_EVENT_MAP= { mouseleave: "mouseout", mouseenter: "mouseover"}; -var jqLiteMinErr = minErr('jqLite'); - -/** - * Converts snake_case to camelCase. - * Also there is special case for Moz prefix starting with upper case letter. - * @param name Name to normalize - */ -function camelCase(name) { - return name. - replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) { - return offset ? letter.toUpperCase() : letter; - }). - replace(MOZ_HACK_REGEXP, 'Moz$1'); -} - -var SINGLE_TAG_REGEXP = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/; -var HTML_REGEXP = /<|&#?\w+;/; -var TAG_NAME_REGEXP = /<([\w:-]+)/; -var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi; - -var wrapMap = { - 'option': [1, ''], - - 'thead': [1, '', '
'], - 'col': [2, '', '
'], - 'tr': [2, '', '
'], - 'td': [3, '', '
'], - '_default': [0, "", ""] -}; - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - - -function jqLiteIsTextNode(html) { - return !HTML_REGEXP.test(html); -} - -function jqLiteAcceptsData(node) { - // The window object can accept data but has no nodeType - // Otherwise we are only interested in elements (1) and documents (9) - var nodeType = node.nodeType; - return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT; -} - -function jqLiteHasData(node) { - for (var key in jqCache[node.ng339]) { - return true; - } - return false; -} - -function jqLiteCleanData(nodes) { - for (var i = 0, ii = nodes.length; i < ii; i++) { - jqLiteRemoveData(nodes[i]); - } -} - -function jqLiteBuildFragment(html, context) { - var tmp, tag, wrap, - fragment = context.createDocumentFragment(), - nodes = [], i; - - if (jqLiteIsTextNode(html)) { - // Convert non-html into a text node - nodes.push(context.createTextNode(html)); - } else { - // Convert html into DOM nodes - tmp = tmp || fragment.appendChild(context.createElement("div")); - tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase(); - wrap = wrapMap[tag] || wrapMap._default; - tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, "<$1>") + wrap[2]; - - // Descend through wrappers to the right content - i = wrap[0]; - while (i--) { - tmp = tmp.lastChild; - } - - nodes = concat(nodes, tmp.childNodes); - - tmp = fragment.firstChild; - tmp.textContent = ""; - } - - // Remove wrapper from fragment - fragment.textContent = ""; - fragment.innerHTML = ""; // Clear inner HTML - forEach(nodes, function(node) { - fragment.appendChild(node); - }); - - return fragment; -} - -function jqLiteParseHTML(html, context) { - context = context || document; - var parsed; - - if ((parsed = SINGLE_TAG_REGEXP.exec(html))) { - return [context.createElement(parsed[1])]; - } - - if ((parsed = jqLiteBuildFragment(html, context))) { - return parsed.childNodes; - } - - return []; -} - - -// IE9-11 has no method "contains" in SVG element and in Node.prototype. Bug #10259. -var jqLiteContains = Node.prototype.contains || function(arg) { - // jshint bitwise: false - return !!(this.compareDocumentPosition(arg) & 16); - // jshint bitwise: true -}; - -///////////////////////////////////////////// -function JQLite(element) { - if (element instanceof JQLite) { - return element; - } - - var argIsString; - - if (isString(element)) { - element = trim(element); - argIsString = true; - } - if (!(this instanceof JQLite)) { - if (argIsString && element.charAt(0) != '<') { - throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element'); - } - return new JQLite(element); - } - - if (argIsString) { - jqLiteAddNodes(this, jqLiteParseHTML(element)); - } else { - jqLiteAddNodes(this, element); - } -} - -function jqLiteClone(element) { - return element.cloneNode(true); -} - -function jqLiteDealoc(element, onlyDescendants) { - if (!onlyDescendants) jqLiteRemoveData(element); - - if (element.querySelectorAll) { - var descendants = element.querySelectorAll('*'); - for (var i = 0, l = descendants.length; i < l; i++) { - jqLiteRemoveData(descendants[i]); - } - } -} - -function jqLiteOff(element, type, fn, unsupported) { - if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument'); - - var expandoStore = jqLiteExpandoStore(element); - var events = expandoStore && expandoStore.events; - var handle = expandoStore && expandoStore.handle; - - if (!handle) return; //no listeners registered - - if (!type) { - for (type in events) { - if (type !== '$destroy') { - removeEventListenerFn(element, type, handle); - } - delete events[type]; - } - } else { - - var removeHandler = function(type) { - var listenerFns = events[type]; - if (isDefined(fn)) { - arrayRemove(listenerFns || [], fn); - } - if (!(isDefined(fn) && listenerFns && listenerFns.length > 0)) { - removeEventListenerFn(element, type, handle); - delete events[type]; - } - }; - - forEach(type.split(' '), function(type) { - removeHandler(type); - if (MOUSE_EVENT_MAP[type]) { - removeHandler(MOUSE_EVENT_MAP[type]); - } - }); - } -} - -function jqLiteRemoveData(element, name) { - var expandoId = element.ng339; - var expandoStore = expandoId && jqCache[expandoId]; - - if (expandoStore) { - if (name) { - delete expandoStore.data[name]; - return; - } - - if (expandoStore.handle) { - if (expandoStore.events.$destroy) { - expandoStore.handle({}, '$destroy'); - } - jqLiteOff(element); - } - delete jqCache[expandoId]; - element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it - } -} - - -function jqLiteExpandoStore(element, createIfNecessary) { - var expandoId = element.ng339, - expandoStore = expandoId && jqCache[expandoId]; - - if (createIfNecessary && !expandoStore) { - element.ng339 = expandoId = jqNextId(); - expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined}; - } - - return expandoStore; -} - - -function jqLiteData(element, key, value) { - if (jqLiteAcceptsData(element)) { - - var isSimpleSetter = isDefined(value); - var isSimpleGetter = !isSimpleSetter && key && !isObject(key); - var massGetter = !key; - var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter); - var data = expandoStore && expandoStore.data; - - if (isSimpleSetter) { // data('key', value) - data[key] = value; - } else { - if (massGetter) { // data() - return data; - } else { - if (isSimpleGetter) { // data('key') - // don't force creation of expandoStore if it doesn't exist yet - return data && data[key]; - } else { // mass-setter: data({key1: val1, key2: val2}) - extend(data, key); - } - } - } - } -} - -function jqLiteHasClass(element, selector) { - if (!element.getAttribute) return false; - return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " "). - indexOf(" " + selector + " ") > -1); -} - -function jqLiteRemoveClass(element, cssClasses) { - if (cssClasses && element.setAttribute) { - forEach(cssClasses.split(' '), function(cssClass) { - element.setAttribute('class', trim( - (" " + (element.getAttribute('class') || '') + " ") - .replace(/[\n\t]/g, " ") - .replace(" " + trim(cssClass) + " ", " ")) - ); - }); - } -} - -function jqLiteAddClass(element, cssClasses) { - if (cssClasses && element.setAttribute) { - var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ') - .replace(/[\n\t]/g, " "); - - forEach(cssClasses.split(' '), function(cssClass) { - cssClass = trim(cssClass); - if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) { - existingClasses += cssClass + ' '; - } - }); - - element.setAttribute('class', trim(existingClasses)); - } -} - - -function jqLiteAddNodes(root, elements) { - // THIS CODE IS VERY HOT. Don't make changes without benchmarking. - - if (elements) { - - // if a Node (the most common case) - if (elements.nodeType) { - root[root.length++] = elements; - } else { - var length = elements.length; - - // if an Array or NodeList and not a Window - if (typeof length === 'number' && elements.window !== elements) { - if (length) { - for (var i = 0; i < length; i++) { - root[root.length++] = elements[i]; - } - } - } else { - root[root.length++] = elements; - } - } - } -} - - -function jqLiteController(element, name) { - return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller'); -} - -function jqLiteInheritedData(element, name, value) { - // if element is the document object work with the html element instead - // this makes $(document).scope() possible - if (element.nodeType == NODE_TYPE_DOCUMENT) { - element = element.documentElement; - } - var names = isArray(name) ? name : [name]; - - while (element) { - for (var i = 0, ii = names.length; i < ii; i++) { - if (isDefined(value = jqLite.data(element, names[i]))) return value; - } - - // If dealing with a document fragment node with a host element, and no parent, use the host - // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM - // to lookup parent controllers. - element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host); - } -} - -function jqLiteEmpty(element) { - jqLiteDealoc(element, true); - while (element.firstChild) { - element.removeChild(element.firstChild); - } -} - -function jqLiteRemove(element, keepData) { - if (!keepData) jqLiteDealoc(element); - var parent = element.parentNode; - if (parent) parent.removeChild(element); -} - - -function jqLiteDocumentLoaded(action, win) { - win = win || window; - if (win.document.readyState === 'complete') { - // Force the action to be run async for consistent behaviour - // from the action's point of view - // i.e. it will definitely not be in a $apply - win.setTimeout(action); - } else { - // No need to unbind this handler as load is only ever called once - jqLite(win).on('load', action); - } -} - -////////////////////////////////////////// -// Functions which are declared directly. -////////////////////////////////////////// -var JQLitePrototype = JQLite.prototype = { - ready: function(fn) { - var fired = false; - - function trigger() { - if (fired) return; - fired = true; - fn(); - } - - // check if document is already loaded - if (document.readyState === 'complete') { - setTimeout(trigger); - } else { - this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9 - // we can not use jqLite since we are not done loading and jQuery could be loaded later. - // jshint -W064 - JQLite(window).on('load', trigger); // fallback to window.onload for others - // jshint +W064 - } - }, - toString: function() { - var value = []; - forEach(this, function(e) { value.push('' + e);}); - return '[' + value.join(', ') + ']'; - }, - - eq: function(index) { - return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]); - }, - - length: 0, - push: push, - sort: [].sort, - splice: [].splice -}; - -////////////////////////////////////////// -// Functions iterating getter/setters. -// these functions return self on setter and -// value on get. -////////////////////////////////////////// -var BOOLEAN_ATTR = {}; -forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) { - BOOLEAN_ATTR[lowercase(value)] = value; -}); -var BOOLEAN_ELEMENTS = {}; -forEach('input,select,option,textarea,button,form,details'.split(','), function(value) { - BOOLEAN_ELEMENTS[value] = true; -}); -var ALIASED_ATTR = { - 'ngMinlength': 'minlength', - 'ngMaxlength': 'maxlength', - 'ngMin': 'min', - 'ngMax': 'max', - 'ngPattern': 'pattern' -}; - -function getBooleanAttrName(element, name) { - // check dom last since we will most likely fail on name - var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()]; - - // booleanAttr is here twice to minimize DOM access - return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr; -} - -function getAliasedAttrName(name) { - return ALIASED_ATTR[name]; -} - -forEach({ - data: jqLiteData, - removeData: jqLiteRemoveData, - hasData: jqLiteHasData, - cleanData: jqLiteCleanData -}, function(fn, name) { - JQLite[name] = fn; -}); - -forEach({ - data: jqLiteData, - inheritedData: jqLiteInheritedData, - - scope: function(element) { - // Can't use jqLiteData here directly so we stay compatible with jQuery! - return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']); - }, - - isolateScope: function(element) { - // Can't use jqLiteData here directly so we stay compatible with jQuery! - return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate'); - }, - - controller: jqLiteController, - - injector: function(element) { - return jqLiteInheritedData(element, '$injector'); - }, - - removeAttr: function(element, name) { - element.removeAttribute(name); - }, - - hasClass: jqLiteHasClass, - - css: function(element, name, value) { - name = camelCase(name); - - if (isDefined(value)) { - element.style[name] = value; - } else { - return element.style[name]; - } - }, - - attr: function(element, name, value) { - var nodeType = element.nodeType; - if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT) { - return; - } - var lowercasedName = lowercase(name); - if (BOOLEAN_ATTR[lowercasedName]) { - if (isDefined(value)) { - if (!!value) { - element[name] = true; - element.setAttribute(name, lowercasedName); - } else { - element[name] = false; - element.removeAttribute(lowercasedName); - } - } else { - return (element[name] || - (element.attributes.getNamedItem(name) || noop).specified) - ? lowercasedName - : undefined; - } - } else if (isDefined(value)) { - element.setAttribute(name, value); - } else if (element.getAttribute) { - // the extra argument "2" is to get the right thing for a.href in IE, see jQuery code - // some elements (e.g. Document) don't have get attribute, so return undefined - var ret = element.getAttribute(name, 2); - // normalize non-existing attributes to undefined (as jQuery) - return ret === null ? undefined : ret; - } - }, - - prop: function(element, name, value) { - if (isDefined(value)) { - element[name] = value; - } else { - return element[name]; - } - }, - - text: (function() { - getText.$dv = ''; - return getText; - - function getText(element, value) { - if (isUndefined(value)) { - var nodeType = element.nodeType; - return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : ''; - } - element.textContent = value; - } - })(), - - val: function(element, value) { - if (isUndefined(value)) { - if (element.multiple && nodeName_(element) === 'select') { - var result = []; - forEach(element.options, function(option) { - if (option.selected) { - result.push(option.value || option.text); - } - }); - return result.length === 0 ? null : result; - } - return element.value; - } - element.value = value; - }, - - html: function(element, value) { - if (isUndefined(value)) { - return element.innerHTML; - } - jqLiteDealoc(element, true); - element.innerHTML = value; - }, - - empty: jqLiteEmpty -}, function(fn, name) { - /** - * Properties: writes return selection, reads return first value - */ - JQLite.prototype[name] = function(arg1, arg2) { - var i, key; - var nodeCount = this.length; - - // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it - // in a way that survives minification. - // jqLiteEmpty takes no arguments but is a setter. - if (fn !== jqLiteEmpty && - (isUndefined((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2))) { - if (isObject(arg1)) { - - // we are a write, but the object properties are the key/values - for (i = 0; i < nodeCount; i++) { - if (fn === jqLiteData) { - // data() takes the whole object in jQuery - fn(this[i], arg1); - } else { - for (key in arg1) { - fn(this[i], key, arg1[key]); - } - } - } - // return self for chaining - return this; - } else { - // we are a read, so read the first child. - // TODO: do we still need this? - var value = fn.$dv; - // Only if we have $dv do we iterate over all, otherwise it is just the first element. - var jj = (isUndefined(value)) ? Math.min(nodeCount, 1) : nodeCount; - for (var j = 0; j < jj; j++) { - var nodeValue = fn(this[j], arg1, arg2); - value = value ? value + nodeValue : nodeValue; - } - return value; - } - } else { - // we are a write, so apply to all children - for (i = 0; i < nodeCount; i++) { - fn(this[i], arg1, arg2); - } - // return self for chaining - return this; - } - }; -}); - -function createEventHandler(element, events) { - var eventHandler = function(event, type) { - // jQuery specific api - event.isDefaultPrevented = function() { - return event.defaultPrevented; - }; - - var eventFns = events[type || event.type]; - var eventFnsLength = eventFns ? eventFns.length : 0; - - if (!eventFnsLength) return; - - if (isUndefined(event.immediatePropagationStopped)) { - var originalStopImmediatePropagation = event.stopImmediatePropagation; - event.stopImmediatePropagation = function() { - event.immediatePropagationStopped = true; - - if (event.stopPropagation) { - event.stopPropagation(); - } - - if (originalStopImmediatePropagation) { - originalStopImmediatePropagation.call(event); - } - }; - } - - event.isImmediatePropagationStopped = function() { - return event.immediatePropagationStopped === true; - }; - - // Some events have special handlers that wrap the real handler - var handlerWrapper = eventFns.specialHandlerWrapper || defaultHandlerWrapper; - - // Copy event handlers in case event handlers array is modified during execution. - if ((eventFnsLength > 1)) { - eventFns = shallowCopy(eventFns); - } - - for (var i = 0; i < eventFnsLength; i++) { - if (!event.isImmediatePropagationStopped()) { - handlerWrapper(element, event, eventFns[i]); - } - } - }; - - // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all - // events on `element` - eventHandler.elem = element; - return eventHandler; -} - -function defaultHandlerWrapper(element, event, handler) { - handler.call(element, event); -} - -function specialMouseHandlerWrapper(target, event, handler) { - // Refer to jQuery's implementation of mouseenter & mouseleave - // Read about mouseenter and mouseleave: - // http://www.quirksmode.org/js/events_mouse.html#link8 - var related = event.relatedTarget; - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if (!related || (related !== target && !jqLiteContains.call(target, related))) { - handler.call(target, event); - } -} - -////////////////////////////////////////// -// Functions iterating traversal. -// These functions chain results into a single -// selector. -////////////////////////////////////////// -forEach({ - removeData: jqLiteRemoveData, - - on: function jqLiteOn(element, type, fn, unsupported) { - if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters'); - - // Do not add event handlers to non-elements because they will not be cleaned up. - if (!jqLiteAcceptsData(element)) { - return; - } - - var expandoStore = jqLiteExpandoStore(element, true); - var events = expandoStore.events; - var handle = expandoStore.handle; - - if (!handle) { - handle = expandoStore.handle = createEventHandler(element, events); - } - - // http://jsperf.com/string-indexof-vs-split - var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type]; - var i = types.length; - - var addHandler = function(type, specialHandlerWrapper, noEventListener) { - var eventFns = events[type]; - - if (!eventFns) { - eventFns = events[type] = []; - eventFns.specialHandlerWrapper = specialHandlerWrapper; - if (type !== '$destroy' && !noEventListener) { - addEventListenerFn(element, type, handle); - } - } - - eventFns.push(fn); - }; - - while (i--) { - type = types[i]; - if (MOUSE_EVENT_MAP[type]) { - addHandler(MOUSE_EVENT_MAP[type], specialMouseHandlerWrapper); - addHandler(type, undefined, true); - } else { - addHandler(type); - } - } - }, - - off: jqLiteOff, - - one: function(element, type, fn) { - element = jqLite(element); - - //add the listener twice so that when it is called - //you can remove the original function and still be - //able to call element.off(ev, fn) normally - element.on(type, function onFn() { - element.off(type, fn); - element.off(type, onFn); - }); - element.on(type, fn); - }, - - replaceWith: function(element, replaceNode) { - var index, parent = element.parentNode; - jqLiteDealoc(element); - forEach(new JQLite(replaceNode), function(node) { - if (index) { - parent.insertBefore(node, index.nextSibling); - } else { - parent.replaceChild(node, element); - } - index = node; - }); - }, - - children: function(element) { - var children = []; - forEach(element.childNodes, function(element) { - if (element.nodeType === NODE_TYPE_ELEMENT) { - children.push(element); - } - }); - return children; - }, - - contents: function(element) { - return element.contentDocument || element.childNodes || []; - }, - - append: function(element, node) { - var nodeType = element.nodeType; - if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return; - - node = new JQLite(node); - - for (var i = 0, ii = node.length; i < ii; i++) { - var child = node[i]; - element.appendChild(child); - } - }, - - prepend: function(element, node) { - if (element.nodeType === NODE_TYPE_ELEMENT) { - var index = element.firstChild; - forEach(new JQLite(node), function(child) { - element.insertBefore(child, index); - }); - } - }, - - wrap: function(element, wrapNode) { - wrapNode = jqLite(wrapNode).eq(0).clone()[0]; - var parent = element.parentNode; - if (parent) { - parent.replaceChild(wrapNode, element); - } - wrapNode.appendChild(element); - }, - - remove: jqLiteRemove, - - detach: function(element) { - jqLiteRemove(element, true); - }, - - after: function(element, newElement) { - var index = element, parent = element.parentNode; - newElement = new JQLite(newElement); - - for (var i = 0, ii = newElement.length; i < ii; i++) { - var node = newElement[i]; - parent.insertBefore(node, index.nextSibling); - index = node; - } - }, - - addClass: jqLiteAddClass, - removeClass: jqLiteRemoveClass, - - toggleClass: function(element, selector, condition) { - if (selector) { - forEach(selector.split(' '), function(className) { - var classCondition = condition; - if (isUndefined(classCondition)) { - classCondition = !jqLiteHasClass(element, className); - } - (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className); - }); - } - }, - - parent: function(element) { - var parent = element.parentNode; - return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null; - }, - - next: function(element) { - return element.nextElementSibling; - }, - - find: function(element, selector) { - if (element.getElementsByTagName) { - return element.getElementsByTagName(selector); - } else { - return []; - } - }, - - clone: jqLiteClone, - - triggerHandler: function(element, event, extraParameters) { - - var dummyEvent, eventFnsCopy, handlerArgs; - var eventName = event.type || event; - var expandoStore = jqLiteExpandoStore(element); - var events = expandoStore && expandoStore.events; - var eventFns = events && events[eventName]; - - if (eventFns) { - // Create a dummy event to pass to the handlers - dummyEvent = { - preventDefault: function() { this.defaultPrevented = true; }, - isDefaultPrevented: function() { return this.defaultPrevented === true; }, - stopImmediatePropagation: function() { this.immediatePropagationStopped = true; }, - isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; }, - stopPropagation: noop, - type: eventName, - target: element - }; - - // If a custom event was provided then extend our dummy event with it - if (event.type) { - dummyEvent = extend(dummyEvent, event); - } - - // Copy event handlers in case event handlers array is modified during execution. - eventFnsCopy = shallowCopy(eventFns); - handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent]; - - forEach(eventFnsCopy, function(fn) { - if (!dummyEvent.isImmediatePropagationStopped()) { - fn.apply(element, handlerArgs); - } - }); - } - } -}, function(fn, name) { - /** - * chaining functions - */ - JQLite.prototype[name] = function(arg1, arg2, arg3) { - var value; - - for (var i = 0, ii = this.length; i < ii; i++) { - if (isUndefined(value)) { - value = fn(this[i], arg1, arg2, arg3); - if (isDefined(value)) { - // any function which returns a value needs to be wrapped - value = jqLite(value); - } - } else { - jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3)); - } - } - return isDefined(value) ? value : this; - }; - - // bind legacy bind/unbind to on/off - JQLite.prototype.bind = JQLite.prototype.on; - JQLite.prototype.unbind = JQLite.prototype.off; -}); - - -// Provider for private $$jqLite service -function $$jqLiteProvider() { - this.$get = function $$jqLite() { - return extend(JQLite, { - hasClass: function(node, classes) { - if (node.attr) node = node[0]; - return jqLiteHasClass(node, classes); - }, - addClass: function(node, classes) { - if (node.attr) node = node[0]; - return jqLiteAddClass(node, classes); - }, - removeClass: function(node, classes) { - if (node.attr) node = node[0]; - return jqLiteRemoveClass(node, classes); - } - }); - }; -} - -/** - * Computes a hash of an 'obj'. - * Hash of a: - * string is string - * number is number as string - * object is either result of calling $$hashKey function on the object or uniquely generated id, - * that is also assigned to the $$hashKey property of the object. - * - * @param obj - * @returns {string} hash string such that the same input will have the same hash string. - * The resulting string key is in 'type:hashKey' format. - */ -function hashKey(obj, nextUidFn) { - var key = obj && obj.$$hashKey; - - if (key) { - if (typeof key === 'function') { - key = obj.$$hashKey(); - } - return key; - } - - var objType = typeof obj; - if (objType == 'function' || (objType == 'object' && obj !== null)) { - key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)(); - } else { - key = objType + ':' + obj; - } - - return key; -} - -/** - * HashMap which can use objects as keys - */ -function HashMap(array, isolatedUid) { - if (isolatedUid) { - var uid = 0; - this.nextUid = function() { - return ++uid; - }; - } - forEach(array, this.put, this); -} -HashMap.prototype = { - /** - * Store key value pair - * @param key key to store can be any type - * @param value value to store can be any type - */ - put: function(key, value) { - this[hashKey(key, this.nextUid)] = value; - }, - - /** - * @param key - * @returns {Object} the value for the key - */ - get: function(key) { - return this[hashKey(key, this.nextUid)]; - }, - - /** - * Remove the key/value pair - * @param key - */ - remove: function(key) { - var value = this[key = hashKey(key, this.nextUid)]; - delete this[key]; - return value; - } -}; - -var $$HashMapProvider = [function() { - this.$get = [function() { - return HashMap; - }]; -}]; - -/** - * @ngdoc function - * @module ng - * @name angular.injector - * @kind function - * - * @description - * Creates an injector object that can be used for retrieving services as well as for - * dependency injection (see {@link guide/di dependency injection}). - * - * @param {Array.} modules A list of module functions or their aliases. See - * {@link angular.module}. The `ng` module must be explicitly added. - * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which - * disallows argument name annotation inference. - * @returns {injector} Injector object. See {@link auto.$injector $injector}. - * - * @example - * Typical usage - * ```js - * // create an injector - * var $injector = angular.injector(['ng']); - * - * // use the injector to kick off your application - * // use the type inference to auto inject arguments, or use implicit injection - * $injector.invoke(function($rootScope, $compile, $document) { - * $compile($document)($rootScope); - * $rootScope.$digest(); - * }); - * ``` - * - * Sometimes you want to get access to the injector of a currently running Angular app - * from outside Angular. Perhaps, you want to inject and compile some markup after the - * application has been bootstrapped. You can do this using the extra `injector()` added - * to JQuery/jqLite elements. See {@link angular.element}. - * - * *This is fairly rare but could be the case if a third party library is injecting the - * markup.* - * - * In the following example a new block of HTML containing a `ng-controller` - * directive is added to the end of the document body by JQuery. We then compile and link - * it into the current AngularJS scope. - * - * ```js - * var $div = $('
{{content.label}}
'); - * $(document.body).append($div); - * - * angular.element(document).injector().invoke(function($compile) { - * var scope = angular.element($div).scope(); - * $compile($div)(scope); - * }); - * ``` - */ - - -/** - * @ngdoc module - * @name auto - * @description - * - * Implicit module which gets automatically added to each {@link auto.$injector $injector}. - */ - -var ARROW_ARG = /^([^\(]+?)=>/; -var FN_ARGS = /^[^\(]*\(\s*([^\)]*)\)/m; -var FN_ARG_SPLIT = /,/; -var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/; -var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; -var $injectorMinErr = minErr('$injector'); - -function extractArgs(fn) { - var fnText = fn.toString().replace(STRIP_COMMENTS, ''), - args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS); - return args; -} - -function anonFn(fn) { - // For anonymous functions, showing at the very least the function signature can help in - // debugging. - var args = extractArgs(fn); - if (args) { - return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')'; - } - return 'fn'; -} - -function annotate(fn, strictDi, name) { - var $inject, - argDecl, - last; - - if (typeof fn === 'function') { - if (!($inject = fn.$inject)) { - $inject = []; - if (fn.length) { - if (strictDi) { - if (!isString(name) || !name) { - name = fn.name || anonFn(fn); - } - throw $injectorMinErr('strictdi', - '{0} is not using explicit annotation and cannot be invoked in strict mode', name); - } - argDecl = extractArgs(fn); - forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) { - arg.replace(FN_ARG, function(all, underscore, name) { - $inject.push(name); - }); - }); - } - fn.$inject = $inject; - } - } else if (isArray(fn)) { - last = fn.length - 1; - assertArgFn(fn[last], 'fn'); - $inject = fn.slice(0, last); - } else { - assertArgFn(fn, 'fn', true); - } - return $inject; -} - -/////////////////////////////////////// - -/** - * @ngdoc service - * @name $injector - * - * @description - * - * `$injector` is used to retrieve object instances as defined by - * {@link auto.$provide provider}, instantiate types, invoke methods, - * and load modules. - * - * The following always holds true: - * - * ```js - * var $injector = angular.injector(); - * expect($injector.get('$injector')).toBe($injector); - * expect($injector.invoke(function($injector) { - * return $injector; - * })).toBe($injector); - * ``` - * - * # Injection Function Annotation - * - * JavaScript does not have annotations, and annotations are needed for dependency injection. The - * following are all valid ways of annotating function with injection arguments and are equivalent. - * - * ```js - * // inferred (only works if code not minified/obfuscated) - * $injector.invoke(function(serviceA){}); - * - * // annotated - * function explicit(serviceA) {}; - * explicit.$inject = ['serviceA']; - * $injector.invoke(explicit); - * - * // inline - * $injector.invoke(['serviceA', function(serviceA){}]); - * ``` - * - * ## Inference - * - * In JavaScript calling `toString()` on a function returns the function definition. The definition - * can then be parsed and the function arguments can be extracted. This method of discovering - * annotations is disallowed when the injector is in strict mode. - * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the - * argument names. - * - * ## `$inject` Annotation - * By adding an `$inject` property onto a function the injection parameters can be specified. - * - * ## Inline - * As an array of injection names, where the last item in the array is the function to call. - */ - -/** - * @ngdoc method - * @name $injector#get - * - * @description - * Return an instance of the service. - * - * @param {string} name The name of the instance to retrieve. - * @param {string=} caller An optional string to provide the origin of the function call for error messages. - * @return {*} The instance. - */ - -/** - * @ngdoc method - * @name $injector#invoke - * - * @description - * Invoke the method and supply the method arguments from the `$injector`. - * - * @param {Function|Array.} fn The injectable function to invoke. Function parameters are - * injected according to the {@link guide/di $inject Annotation} rules. - * @param {Object=} self The `this` for the invoked method. - * @param {Object=} locals Optional object. If preset then any argument names are read from this - * object first, before the `$injector` is consulted. - * @returns {*} the value returned by the invoked `fn` function. - */ - -/** - * @ngdoc method - * @name $injector#has - * - * @description - * Allows the user to query if the particular service exists. - * - * @param {string} name Name of the service to query. - * @returns {boolean} `true` if injector has given service. - */ - -/** - * @ngdoc method - * @name $injector#instantiate - * @description - * Create a new instance of JS type. The method takes a constructor function, invokes the new - * operator, and supplies all of the arguments to the constructor function as specified by the - * constructor annotation. - * - * @param {Function} Type Annotated constructor function. - * @param {Object=} locals Optional object. If preset then any argument names are read from this - * object first, before the `$injector` is consulted. - * @returns {Object} new instance of `Type`. - */ - -/** - * @ngdoc method - * @name $injector#annotate - * - * @description - * Returns an array of service names which the function is requesting for injection. This API is - * used by the injector to determine which services need to be injected into the function when the - * function is invoked. There are three ways in which the function can be annotated with the needed - * dependencies. - * - * # Argument names - * - * The simplest form is to extract the dependencies from the arguments of the function. This is done - * by converting the function into a string using `toString()` method and extracting the argument - * names. - * ```js - * // Given - * function MyController($scope, $route) { - * // ... - * } - * - * // Then - * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']); - * ``` - * - * You can disallow this method by using strict injection mode. - * - * This method does not work with code minification / obfuscation. For this reason the following - * annotation strategies are supported. - * - * # The `$inject` property - * - * If a function has an `$inject` property and its value is an array of strings, then the strings - * represent names of services to be injected into the function. - * ```js - * // Given - * var MyController = function(obfuscatedScope, obfuscatedRoute) { - * // ... - * } - * // Define function dependencies - * MyController['$inject'] = ['$scope', '$route']; - * - * // Then - * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']); - * ``` - * - * # The array notation - * - * It is often desirable to inline Injected functions and that's when setting the `$inject` property - * is very inconvenient. In these situations using the array notation to specify the dependencies in - * a way that survives minification is a better choice: - * - * ```js - * // We wish to write this (not minification / obfuscation safe) - * injector.invoke(function($compile, $rootScope) { - * // ... - * }); - * - * // We are forced to write break inlining - * var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) { - * // ... - * }; - * tmpFn.$inject = ['$compile', '$rootScope']; - * injector.invoke(tmpFn); - * - * // To better support inline function the inline annotation is supported - * injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) { - * // ... - * }]); - * - * // Therefore - * expect(injector.annotate( - * ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}]) - * ).toEqual(['$compile', '$rootScope']); - * ``` - * - * @param {Function|Array.} fn Function for which dependent service names need to - * be retrieved as described above. - * - * @param {boolean=} [strictDi=false] Disallow argument name annotation inference. - * - * @returns {Array.} The names of the services which the function requires. - */ - - - - -/** - * @ngdoc service - * @name $provide - * - * @description - * - * The {@link auto.$provide $provide} service has a number of methods for registering components - * with the {@link auto.$injector $injector}. Many of these functions are also exposed on - * {@link angular.Module}. - * - * An Angular **service** is a singleton object created by a **service factory**. These **service - * factories** are functions which, in turn, are created by a **service provider**. - * The **service providers** are constructor functions. When instantiated they must contain a - * property called `$get`, which holds the **service factory** function. - * - * When you request a service, the {@link auto.$injector $injector} is responsible for finding the - * correct **service provider**, instantiating it and then calling its `$get` **service factory** - * function to get the instance of the **service**. - * - * Often services have no configuration options and there is no need to add methods to the service - * provider. The provider will be no more than a constructor function with a `$get` property. For - * these cases the {@link auto.$provide $provide} service has additional helper methods to register - * services without specifying a provider. - * - * * {@link auto.$provide#provider provider(provider)} - registers a **service provider** with the - * {@link auto.$injector $injector} - * * {@link auto.$provide#constant constant(obj)} - registers a value/object that can be accessed by - * providers and services. - * * {@link auto.$provide#value value(obj)} - registers a value/object that can only be accessed by - * services, not providers. - * * {@link auto.$provide#factory factory(fn)} - registers a service **factory function**, `fn`, - * that will be wrapped in a **service provider** object, whose `$get` property will contain the - * given factory function. - * * {@link auto.$provide#service service(class)} - registers a **constructor function**, `class` - * that will be wrapped in a **service provider** object, whose `$get` property will instantiate - * a new object using the given constructor function. - * - * See the individual methods for more information and examples. - */ - -/** - * @ngdoc method - * @name $provide#provider - * @description - * - * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions - * are constructor functions, whose instances are responsible for "providing" a factory for a - * service. - * - * Service provider names start with the name of the service they provide followed by `Provider`. - * For example, the {@link ng.$log $log} service has a provider called - * {@link ng.$logProvider $logProvider}. - * - * Service provider objects can have additional methods which allow configuration of the provider - * and its service. Importantly, you can configure what kind of service is created by the `$get` - * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a - * method {@link ng.$logProvider#debugEnabled debugEnabled} - * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the - * console or not. - * - * @param {string} name The name of the instance. NOTE: the provider will be available under `name + - 'Provider'` key. - * @param {(Object|function())} provider If the provider is: - * - * - `Object`: then it should have a `$get` method. The `$get` method will be invoked using - * {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created. - * - `Constructor`: a new instance of the provider will be created using - * {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`. - * - * @returns {Object} registered provider instance - - * @example - * - * The following example shows how to create a simple event tracking service and register it using - * {@link auto.$provide#provider $provide.provider()}. - * - * ```js - * // Define the eventTracker provider - * function EventTrackerProvider() { - * var trackingUrl = '/track'; - * - * // A provider method for configuring where the tracked events should been saved - * this.setTrackingUrl = function(url) { - * trackingUrl = url; - * }; - * - * // The service factory function - * this.$get = ['$http', function($http) { - * var trackedEvents = {}; - * return { - * // Call this to track an event - * event: function(event) { - * var count = trackedEvents[event] || 0; - * count += 1; - * trackedEvents[event] = count; - * return count; - * }, - * // Call this to save the tracked events to the trackingUrl - * save: function() { - * $http.post(trackingUrl, trackedEvents); - * } - * }; - * }]; - * } - * - * describe('eventTracker', function() { - * var postSpy; - * - * beforeEach(module(function($provide) { - * // Register the eventTracker provider - * $provide.provider('eventTracker', EventTrackerProvider); - * })); - * - * beforeEach(module(function(eventTrackerProvider) { - * // Configure eventTracker provider - * eventTrackerProvider.setTrackingUrl('/custom-track'); - * })); - * - * it('tracks events', inject(function(eventTracker) { - * expect(eventTracker.event('login')).toEqual(1); - * expect(eventTracker.event('login')).toEqual(2); - * })); - * - * it('saves to the tracking url', inject(function(eventTracker, $http) { - * postSpy = spyOn($http, 'post'); - * eventTracker.event('login'); - * eventTracker.save(); - * expect(postSpy).toHaveBeenCalled(); - * expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track'); - * expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track'); - * expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 }); - * })); - * }); - * ``` - */ - -/** - * @ngdoc method - * @name $provide#factory - * @description - * - * Register a **service factory**, which will be called to return the service instance. - * This is short for registering a service where its provider consists of only a `$get` property, - * which is the given service factory function. - * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to - * configure your service in a provider. - * - * @param {string} name The name of the instance. - * @param {Function|Array.} $getFn The injectable $getFn for the instance creation. - * Internally this is a short hand for `$provide.provider(name, {$get: $getFn})`. - * @returns {Object} registered provider instance - * - * @example - * Here is an example of registering a service - * ```js - * $provide.factory('ping', ['$http', function($http) { - * return function ping() { - * return $http.send('/ping'); - * }; - * }]); - * ``` - * You would then inject and use this service like this: - * ```js - * someModule.controller('Ctrl', ['ping', function(ping) { - * ping(); - * }]); - * ``` - */ - - -/** - * @ngdoc method - * @name $provide#service - * @description - * - * Register a **service constructor**, which will be invoked with `new` to create the service - * instance. - * This is short for registering a service where its provider's `$get` property is the service - * constructor function that will be used to instantiate the service instance. - * - * You should use {@link auto.$provide#service $provide.service(class)} if you define your service - * as a type/class. - * - * @param {string} name The name of the instance. - * @param {Function|Array.} constructor An injectable class (constructor function) - * that will be instantiated. - * @returns {Object} registered provider instance - * - * @example - * Here is an example of registering a service using - * {@link auto.$provide#service $provide.service(class)}. - * ```js - * var Ping = function($http) { - * this.$http = $http; - * }; - * - * Ping.$inject = ['$http']; - * - * Ping.prototype.send = function() { - * return this.$http.get('/ping'); - * }; - * $provide.service('ping', Ping); - * ``` - * You would then inject and use this service like this: - * ```js - * someModule.controller('Ctrl', ['ping', function(ping) { - * ping.send(); - * }]); - * ``` - */ - - -/** - * @ngdoc method - * @name $provide#value - * @description - * - * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a - * number, an array, an object or a function. This is short for registering a service where its - * provider's `$get` property is a factory function that takes no arguments and returns the **value - * service**. - * - * Value services are similar to constant services, except that they cannot be injected into a - * module configuration function (see {@link angular.Module#config}) but they can be overridden by - * an Angular - * {@link auto.$provide#decorator decorator}. - * - * @param {string} name The name of the instance. - * @param {*} value The value. - * @returns {Object} registered provider instance - * - * @example - * Here are some examples of creating value services. - * ```js - * $provide.value('ADMIN_USER', 'admin'); - * - * $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 }); - * - * $provide.value('halfOf', function(value) { - * return value / 2; - * }); - * ``` - */ - - -/** - * @ngdoc method - * @name $provide#constant - * @description - * - * Register a **constant service**, such as a string, a number, an array, an object or a function, - * with the {@link auto.$injector $injector}. Unlike {@link auto.$provide#value value} it can be - * injected into a module configuration function (see {@link angular.Module#config}) and it cannot - * be overridden by an Angular {@link auto.$provide#decorator decorator}. - * - * @param {string} name The name of the constant. - * @param {*} value The constant value. - * @returns {Object} registered instance - * - * @example - * Here a some examples of creating constants: - * ```js - * $provide.constant('SHARD_HEIGHT', 306); - * - * $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']); - * - * $provide.constant('double', function(value) { - * return value * 2; - * }); - * ``` - */ - - -/** - * @ngdoc method - * @name $provide#decorator - * @description - * - * Register a **service decorator** with the {@link auto.$injector $injector}. A service decorator - * intercepts the creation of a service, allowing it to override or modify the behaviour of the - * service. The object returned by the decorator may be the original service, or a new service - * object which replaces or wraps and delegates to the original service. - * - * @param {string} name The name of the service to decorate. - * @param {Function|Array.} decorator This function will be invoked when the service needs to be - * instantiated and should return the decorated service instance. The function is called using - * the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable. - * Local injection arguments: - * - * * `$delegate` - The original service instance, which can be monkey patched, configured, - * decorated or delegated to. - * - * @example - * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting - * calls to {@link ng.$log#error $log.warn()}. - * ```js - * $provide.decorator('$log', ['$delegate', function($delegate) { - * $delegate.warn = $delegate.error; - * return $delegate; - * }]); - * ``` - */ - - -function createInjector(modulesToLoad, strictDi) { - strictDi = (strictDi === true); - var INSTANTIATING = {}, - providerSuffix = 'Provider', - path = [], - loadedModules = new HashMap([], true), - providerCache = { - $provide: { - provider: supportObject(provider), - factory: supportObject(factory), - service: supportObject(service), - value: supportObject(value), - constant: supportObject(constant), - decorator: decorator - } - }, - providerInjector = (providerCache.$injector = - createInternalInjector(providerCache, function(serviceName, caller) { - if (angular.isString(caller)) { - path.push(caller); - } - throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- ')); - })), - instanceCache = {}, - protoInstanceInjector = - createInternalInjector(instanceCache, function(serviceName, caller) { - var provider = providerInjector.get(serviceName + providerSuffix, caller); - return instanceInjector.invoke( - provider.$get, provider, undefined, serviceName); - }), - instanceInjector = protoInstanceInjector; - - providerCache['$injector' + providerSuffix] = { $get: valueFn(protoInstanceInjector) }; - var runBlocks = loadModules(modulesToLoad); - instanceInjector = protoInstanceInjector.get('$injector'); - instanceInjector.strictDi = strictDi; - forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); }); - - return instanceInjector; - - //////////////////////////////////// - // $provider - //////////////////////////////////// - - function supportObject(delegate) { - return function(key, value) { - if (isObject(key)) { - forEach(key, reverseParams(delegate)); - } else { - return delegate(key, value); - } - }; - } - - function provider(name, provider_) { - assertNotHasOwnProperty(name, 'service'); - if (isFunction(provider_) || isArray(provider_)) { - provider_ = providerInjector.instantiate(provider_); - } - if (!provider_.$get) { - throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name); - } - return providerCache[name + providerSuffix] = provider_; - } - - function enforceReturnValue(name, factory) { - return function enforcedReturnValue() { - var result = instanceInjector.invoke(factory, this); - if (isUndefined(result)) { - throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name); - } - return result; - }; - } - - function factory(name, factoryFn, enforce) { - return provider(name, { - $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn - }); - } - - function service(name, constructor) { - return factory(name, ['$injector', function($injector) { - return $injector.instantiate(constructor); - }]); - } - - function value(name, val) { return factory(name, valueFn(val), false); } - - function constant(name, value) { - assertNotHasOwnProperty(name, 'constant'); - providerCache[name] = value; - instanceCache[name] = value; - } - - function decorator(serviceName, decorFn) { - var origProvider = providerInjector.get(serviceName + providerSuffix), - orig$get = origProvider.$get; - - origProvider.$get = function() { - var origInstance = instanceInjector.invoke(orig$get, origProvider); - return instanceInjector.invoke(decorFn, null, {$delegate: origInstance}); - }; - } - - //////////////////////////////////// - // Module Loading - //////////////////////////////////// - function loadModules(modulesToLoad) { - assertArg(isUndefined(modulesToLoad) || isArray(modulesToLoad), 'modulesToLoad', 'not an array'); - var runBlocks = [], moduleFn; - forEach(modulesToLoad, function(module) { - if (loadedModules.get(module)) return; - loadedModules.put(module, true); - - function runInvokeQueue(queue) { - var i, ii; - for (i = 0, ii = queue.length; i < ii; i++) { - var invokeArgs = queue[i], - provider = providerInjector.get(invokeArgs[0]); - - provider[invokeArgs[1]].apply(provider, invokeArgs[2]); - } - } - - try { - if (isString(module)) { - moduleFn = angularModule(module); - runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks); - runInvokeQueue(moduleFn._invokeQueue); - runInvokeQueue(moduleFn._configBlocks); - } else if (isFunction(module)) { - runBlocks.push(providerInjector.invoke(module)); - } else if (isArray(module)) { - runBlocks.push(providerInjector.invoke(module)); - } else { - assertArgFn(module, 'module'); - } - } catch (e) { - if (isArray(module)) { - module = module[module.length - 1]; - } - if (e.message && e.stack && e.stack.indexOf(e.message) == -1) { - // Safari & FF's stack traces don't contain error.message content - // unlike those of Chrome and IE - // So if stack doesn't contain message, we create a new string that contains both. - // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here. - /* jshint -W022 */ - e = e.message + '\n' + e.stack; - } - throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}", - module, e.stack || e.message || e); - } - }); - return runBlocks; - } - - //////////////////////////////////// - // internal Injector - //////////////////////////////////// - - function createInternalInjector(cache, factory) { - - function getService(serviceName, caller) { - if (cache.hasOwnProperty(serviceName)) { - if (cache[serviceName] === INSTANTIATING) { - throw $injectorMinErr('cdep', 'Circular dependency found: {0}', - serviceName + ' <- ' + path.join(' <- ')); - } - return cache[serviceName]; - } else { - try { - path.unshift(serviceName); - cache[serviceName] = INSTANTIATING; - return cache[serviceName] = factory(serviceName, caller); - } catch (err) { - if (cache[serviceName] === INSTANTIATING) { - delete cache[serviceName]; - } - throw err; - } finally { - path.shift(); - } - } - } - - function invoke(fn, self, locals, serviceName) { - if (typeof locals === 'string') { - serviceName = locals; - locals = null; - } - - var args = [], - $inject = createInjector.$$annotate(fn, strictDi, serviceName), - length, i, - key; - - for (i = 0, length = $inject.length; i < length; i++) { - key = $inject[i]; - if (typeof key !== 'string') { - throw $injectorMinErr('itkn', - 'Incorrect injection token! Expected service name as string, got {0}', key); - } - args.push( - locals && locals.hasOwnProperty(key) - ? locals[key] - : getService(key, serviceName) - ); - } - if (isArray(fn)) { - fn = fn[length]; - } - - // http://jsperf.com/angularjs-invoke-apply-vs-switch - // #5388 - return fn.apply(self, args); - } - - function instantiate(Type, locals, serviceName) { - // Check if Type is annotated and use just the given function at n-1 as parameter - // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]); - // Object creation: http://jsperf.com/create-constructor/2 - var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype || null); - var returnedValue = invoke(Type, instance, locals, serviceName); - - return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance; - } - - return { - invoke: invoke, - instantiate: instantiate, - get: getService, - annotate: createInjector.$$annotate, - has: function(name) { - return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name); - } - }; - } -} - -createInjector.$$annotate = annotate; - -/** - * @ngdoc provider - * @name $anchorScrollProvider - * - * @description - * Use `$anchorScrollProvider` to disable automatic scrolling whenever - * {@link ng.$location#hash $location.hash()} changes. - */ -function $AnchorScrollProvider() { - - var autoScrollingEnabled = true; - - /** - * @ngdoc method - * @name $anchorScrollProvider#disableAutoScrolling - * - * @description - * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to - * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.
- * Use this method to disable automatic scrolling. - * - * If automatic scrolling is disabled, one must explicitly call - * {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the - * current hash. - */ - this.disableAutoScrolling = function() { - autoScrollingEnabled = false; - }; - - /** - * @ngdoc service - * @name $anchorScroll - * @kind function - * @requires $window - * @requires $location - * @requires $rootScope - * - * @description - * When called, it scrolls to the element related to the specified `hash` or (if omitted) to the - * current value of {@link ng.$location#hash $location.hash()}, according to the rules specified - * in the - * [HTML5 spec](http://www.w3.org/html/wg/drafts/html/master/browsers.html#the-indicated-part-of-the-document). - * - * It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to - * match any anchor whenever it changes. This can be disabled by calling - * {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}. - * - * Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a - * vertical scroll-offset (either fixed or dynamic). - * - * @param {string=} hash The hash specifying the element to scroll to. If omitted, the value of - * {@link ng.$location#hash $location.hash()} will be used. - * - * @property {(number|function|jqLite)} yOffset - * If set, specifies a vertical scroll-offset. This is often useful when there are fixed - * positioned elements at the top of the page, such as navbars, headers etc. - * - * `yOffset` can be specified in various ways: - * - **number**: A fixed number of pixels to be used as offset.

- * - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return - * a number representing the offset (in pixels).

- * - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from - * the top of the page to the element's bottom will be used as offset.
- * **Note**: The element will be taken into account only as long as its `position` is set to - * `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust - * their height and/or positioning according to the viewport's size. - * - *
- *
- * In order for `yOffset` to work properly, scrolling should take place on the document's root and - * not some child element. - *
- * - * @example - - -
- Go to bottom - You're at the bottom! -
- - - angular.module('anchorScrollExample', []) - .controller('ScrollController', ['$scope', '$location', '$anchorScroll', - function ($scope, $location, $anchorScroll) { - $scope.gotoBottom = function() { - // set the location.hash to the id of - // the element you wish to scroll to. - $location.hash('bottom'); - - // call $anchorScroll() - $anchorScroll(); - }; - }]); - - - #scrollArea { - height: 280px; - overflow: auto; - } - - #bottom { - display: block; - margin-top: 2000px; - } - - - * - *
- * The example below illustrates the use of a vertical scroll-offset (specified as a fixed value). - * See {@link ng.$anchorScroll#yOffset $anchorScroll.yOffset} for more details. - * - * @example - - - -
- Anchor {{x}} of 5 -
-
- - angular.module('anchorScrollOffsetExample', []) - .run(['$anchorScroll', function($anchorScroll) { - $anchorScroll.yOffset = 50; // always scroll by 50 extra pixels - }]) - .controller('headerCtrl', ['$anchorScroll', '$location', '$scope', - function ($anchorScroll, $location, $scope) { - $scope.gotoAnchor = function(x) { - var newHash = 'anchor' + x; - if ($location.hash() !== newHash) { - // set the $location.hash to `newHash` and - // $anchorScroll will automatically scroll to it - $location.hash('anchor' + x); - } else { - // call $anchorScroll() explicitly, - // since $location.hash hasn't changed - $anchorScroll(); - } - }; - } - ]); - - - body { - padding-top: 50px; - } - - .anchor { - border: 2px dashed DarkOrchid; - padding: 10px 10px 200px 10px; - } - - .fixed-header { - background-color: rgba(0, 0, 0, 0.2); - height: 50px; - position: fixed; - top: 0; left: 0; right: 0; - } - - .fixed-header > a { - display: inline-block; - margin: 5px 15px; - } - -
- */ - this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) { - var document = $window.document; - - // Helper function to get first anchor from a NodeList - // (using `Array#some()` instead of `angular#forEach()` since it's more performant - // and working in all supported browsers.) - function getFirstAnchor(list) { - var result = null; - Array.prototype.some.call(list, function(element) { - if (nodeName_(element) === 'a') { - result = element; - return true; - } - }); - return result; - } - - function getYOffset() { - - var offset = scroll.yOffset; - - if (isFunction(offset)) { - offset = offset(); - } else if (isElement(offset)) { - var elem = offset[0]; - var style = $window.getComputedStyle(elem); - if (style.position !== 'fixed') { - offset = 0; - } else { - offset = elem.getBoundingClientRect().bottom; - } - } else if (!isNumber(offset)) { - offset = 0; - } - - return offset; - } - - function scrollTo(elem) { - if (elem) { - elem.scrollIntoView(); - - var offset = getYOffset(); - - if (offset) { - // `offset` is the number of pixels we should scroll UP in order to align `elem` properly. - // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the - // top of the viewport. - // - // IF the number of pixels from the top of `elem` to the end of the page's content is less - // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some - // way down the page. - // - // This is often the case for elements near the bottom of the page. - // - // In such cases we do not need to scroll the whole `offset` up, just the difference between - // the top of the element and the offset, which is enough to align the top of `elem` at the - // desired position. - var elemTop = elem.getBoundingClientRect().top; - $window.scrollBy(0, elemTop - offset); - } - } else { - $window.scrollTo(0, 0); - } - } - - function scroll(hash) { - hash = isString(hash) ? hash : $location.hash(); - var elm; - - // empty hash, scroll to the top of the page - if (!hash) scrollTo(null); - - // element with given id - else if ((elm = document.getElementById(hash))) scrollTo(elm); - - // first anchor with given name :-D - else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm); - - // no element and hash == 'top', scroll to the top of the page - else if (hash === 'top') scrollTo(null); - } - - // does not scroll when user clicks on anchor link that is currently on - // (no url change, no $location.hash() change), browser native does scroll - if (autoScrollingEnabled) { - $rootScope.$watch(function autoScrollWatch() {return $location.hash();}, - function autoScrollWatchAction(newVal, oldVal) { - // skip the initial scroll if $location.hash is empty - if (newVal === oldVal && newVal === '') return; - - jqLiteDocumentLoaded(function() { - $rootScope.$evalAsync(scroll); - }); - }); - } - - return scroll; - }]; -} - -var $animateMinErr = minErr('$animate'); -var ELEMENT_NODE = 1; -var NG_ANIMATE_CLASSNAME = 'ng-animate'; - -function mergeClasses(a,b) { - if (!a && !b) return ''; - if (!a) return b; - if (!b) return a; - if (isArray(a)) a = a.join(' '); - if (isArray(b)) b = b.join(' '); - return a + ' ' + b; -} - -function extractElementNode(element) { - for (var i = 0; i < element.length; i++) { - var elm = element[i]; - if (elm.nodeType === ELEMENT_NODE) { - return elm; - } - } -} - -function splitClasses(classes) { - if (isString(classes)) { - classes = classes.split(' '); - } - - // Use createMap() to prevent class assumptions involving property names in - // Object.prototype - var obj = createMap(); - forEach(classes, function(klass) { - // sometimes the split leaves empty string values - // incase extra spaces were applied to the options - if (klass.length) { - obj[klass] = true; - } - }); - return obj; -} - -// if any other type of options value besides an Object value is -// passed into the $animate.method() animation then this helper code -// will be run which will ignore it. While this patch is not the -// greatest solution to this, a lot of existing plugins depend on -// $animate to either call the callback (< 1.2) or return a promise -// that can be changed. This helper function ensures that the options -// are wiped clean incase a callback function is provided. -function prepareAnimateOptions(options) { - return isObject(options) - ? options - : {}; -} - -// this is prefixed with Core since it conflicts with -// the animateQueueProvider defined in ngAnimate/animateQueue.js -var $$CoreAnimateQueueProvider = function() { - var postDigestQueue = new HashMap(); - var postDigestElements = []; - - this.$get = ['$$AnimateRunner', '$rootScope', - function($$AnimateRunner, $rootScope) { - return { - enabled: noop, - on: noop, - off: noop, - pin: noop, - - push: function(element, event, options, domOperation) { - domOperation && domOperation(); - - options = options || {}; - options.from && element.css(options.from); - options.to && element.css(options.to); - - if (options.addClass || options.removeClass) { - addRemoveClassesPostDigest(element, options.addClass, options.removeClass); - } - - var runner = new $$AnimateRunner(); // jshint ignore:line - - // since there are no animations to run the runner needs to be - // notified that the animation call is complete. - runner.complete(); - return runner; - } - }; - - - function updateData(data, classes, value) { - var changed = false; - if (classes) { - classes = isString(classes) ? classes.split(' ') : - isArray(classes) ? classes : []; - forEach(classes, function(className) { - if (className) { - changed = true; - data[className] = value; - } - }); - } - return changed; - } - - function handleCSSClassChanges() { - forEach(postDigestElements, function(element) { - var data = postDigestQueue.get(element); - if (data) { - var existing = splitClasses(element.attr('class')); - var toAdd = ''; - var toRemove = ''; - forEach(data, function(status, className) { - var hasClass = !!existing[className]; - if (status !== hasClass) { - if (status) { - toAdd += (toAdd.length ? ' ' : '') + className; - } else { - toRemove += (toRemove.length ? ' ' : '') + className; - } - } - }); - - forEach(element, function(elm) { - toAdd && jqLiteAddClass(elm, toAdd); - toRemove && jqLiteRemoveClass(elm, toRemove); - }); - postDigestQueue.remove(element); - } - }); - postDigestElements.length = 0; - } - - - function addRemoveClassesPostDigest(element, add, remove) { - var data = postDigestQueue.get(element) || {}; - - var classesAdded = updateData(data, add, true); - var classesRemoved = updateData(data, remove, false); - - if (classesAdded || classesRemoved) { - - postDigestQueue.put(element, data); - postDigestElements.push(element); - - if (postDigestElements.length === 1) { - $rootScope.$$postDigest(handleCSSClassChanges); - } - } - } - }]; -}; - -/** - * @ngdoc provider - * @name $animateProvider - * - * @description - * Default implementation of $animate that doesn't perform any animations, instead just - * synchronously performs DOM updates and resolves the returned runner promise. - * - * In order to enable animations the `ngAnimate` module has to be loaded. - * - * To see the functional implementation check out `src/ngAnimate/animate.js`. - */ -var $AnimateProvider = ['$provide', function($provide) { - var provider = this; - - this.$$registeredAnimations = Object.create(null); - - /** - * @ngdoc method - * @name $animateProvider#register - * - * @description - * Registers a new injectable animation factory function. The factory function produces the - * animation object which contains callback functions for each event that is expected to be - * animated. - * - * * `eventFn`: `function(element, ... , doneFunction, options)` - * The element to animate, the `doneFunction` and the options fed into the animation. Depending - * on the type of animation additional arguments will be injected into the animation function. The - * list below explains the function signatures for the different animation methods: - * - * - setClass: function(element, addedClasses, removedClasses, doneFunction, options) - * - addClass: function(element, addedClasses, doneFunction, options) - * - removeClass: function(element, removedClasses, doneFunction, options) - * - enter, leave, move: function(element, doneFunction, options) - * - animate: function(element, fromStyles, toStyles, doneFunction, options) - * - * Make sure to trigger the `doneFunction` once the animation is fully complete. - * - * ```js - * return { - * //enter, leave, move signature - * eventFn : function(element, done, options) { - * //code to run the animation - * //once complete, then run done() - * return function endFunction(wasCancelled) { - * //code to cancel the animation - * } - * } - * } - * ``` - * - * @param {string} name The name of the animation (this is what the class-based CSS value will be compared to). - * @param {Function} factory The factory function that will be executed to return the animation - * object. - */ - this.register = function(name, factory) { - if (name && name.charAt(0) !== '.') { - throw $animateMinErr('notcsel', "Expecting class selector starting with '.' got '{0}'.", name); - } - - var key = name + '-animation'; - provider.$$registeredAnimations[name.substr(1)] = key; - $provide.factory(key, factory); - }; - - /** - * @ngdoc method - * @name $animateProvider#classNameFilter - * - * @description - * Sets and/or returns the CSS class regular expression that is checked when performing - * an animation. Upon bootstrap the classNameFilter value is not set at all and will - * therefore enable $animate to attempt to perform an animation on any element that is triggered. - * When setting the `classNameFilter` value, animations will only be performed on elements - * that successfully match the filter expression. This in turn can boost performance - * for low-powered devices as well as applications containing a lot of structural operations. - * @param {RegExp=} expression The className expression which will be checked against all animations - * @return {RegExp} The current CSS className expression value. If null then there is no expression value - */ - this.classNameFilter = function(expression) { - if (arguments.length === 1) { - this.$$classNameFilter = (expression instanceof RegExp) ? expression : null; - if (this.$$classNameFilter) { - var reservedRegex = new RegExp("(\\s+|\\/)" + NG_ANIMATE_CLASSNAME + "(\\s+|\\/)"); - if (reservedRegex.test(this.$$classNameFilter.toString())) { - throw $animateMinErr('nongcls','$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME); - - } - } - } - return this.$$classNameFilter; - }; - - this.$get = ['$$animateQueue', function($$animateQueue) { - function domInsert(element, parentElement, afterElement) { - // if for some reason the previous element was removed - // from the dom sometime before this code runs then let's - // just stick to using the parent element as the anchor - if (afterElement) { - var afterNode = extractElementNode(afterElement); - if (afterNode && !afterNode.parentNode && !afterNode.previousElementSibling) { - afterElement = null; - } - } - afterElement ? afterElement.after(element) : parentElement.prepend(element); - } - - /** - * @ngdoc service - * @name $animate - * @description The $animate service exposes a series of DOM utility methods that provide support - * for animation hooks. The default behavior is the application of DOM operations, however, - * when an animation is detected (and animations are enabled), $animate will do the heavy lifting - * to ensure that animation runs with the triggered DOM operation. - * - * By default $animate doesn't trigger any animations. This is because the `ngAnimate` module isn't - * included and only when it is active then the animation hooks that `$animate` triggers will be - * functional. Once active then all structural `ng-` directives will trigger animations as they perform - * their DOM-related operations (enter, leave and move). Other directives such as `ngClass`, - * `ngShow`, `ngHide` and `ngMessages` also provide support for animations. - * - * It is recommended that the`$animate` service is always used when executing DOM-related procedures within directives. - * - * To learn more about enabling animation support, click here to visit the - * {@link ngAnimate ngAnimate module page}. - */ - return { - // we don't call it directly since non-existant arguments may - // be interpreted as null within the sub enabled function - - /** - * - * @ngdoc method - * @name $animate#on - * @kind function - * @description Sets up an event listener to fire whenever the animation event (enter, leave, move, etc...) - * has fired on the given element or among any of its children. Once the listener is fired, the provided callback - * is fired with the following params: - * - * ```js - * $animate.on('enter', container, - * function callback(element, phase) { - * // cool we detected an enter animation within the container - * } - * ); - * ``` - * - * @param {string} event the animation event that will be captured (e.g. enter, leave, move, addClass, removeClass, etc...) - * @param {DOMElement} container the container element that will capture each of the animation events that are fired on itself - * as well as among its children - * @param {Function} callback the callback function that will be fired when the listener is triggered - * - * The arguments present in the callback function are: - * * `element` - The captured DOM element that the animation was fired on. - * * `phase` - The phase of the animation. The two possible phases are **start** (when the animation starts) and **close** (when it ends). - */ - on: $$animateQueue.on, - - /** - * - * @ngdoc method - * @name $animate#off - * @kind function - * @description Deregisters an event listener based on the event which has been associated with the provided element. This method - * can be used in three different ways depending on the arguments: - * - * ```js - * // remove all the animation event listeners listening for `enter` - * $animate.off('enter'); - * - * // remove all the animation event listeners listening for `enter` on the given element and its children - * $animate.off('enter', container); - * - * // remove the event listener function provided by `listenerFn` that is set - * // to listen for `enter` on the given `element` as well as its children - * $animate.off('enter', container, callback); - * ``` - * - * @param {string} event the animation event (e.g. enter, leave, move, addClass, removeClass, etc...) - * @param {DOMElement=} container the container element the event listener was placed on - * @param {Function=} callback the callback function that was registered as the listener - */ - off: $$animateQueue.off, - - /** - * @ngdoc method - * @name $animate#pin - * @kind function - * @description Associates the provided element with a host parent element to allow the element to be animated even if it exists - * outside of the DOM structure of the Angular application. By doing so, any animation triggered via `$animate` can be issued on the - * element despite being outside the realm of the application or within another application. Say for example if the application - * was bootstrapped on an element that is somewhere inside of the `` tag, but we wanted to allow for an element to be situated - * as a direct child of `document.body`, then this can be achieved by pinning the element via `$animate.pin(element)`. Keep in mind - * that calling `$animate.pin(element, parentElement)` will not actually insert into the DOM anywhere; it will just create the association. - * - * Note that this feature is only active when the `ngAnimate` module is used. - * - * @param {DOMElement} element the external element that will be pinned - * @param {DOMElement} parentElement the host parent element that will be associated with the external element - */ - pin: $$animateQueue.pin, - - /** - * - * @ngdoc method - * @name $animate#enabled - * @kind function - * @description Used to get and set whether animations are enabled or not on the entire application or on an element and its children. This - * function can be called in four ways: - * - * ```js - * // returns true or false - * $animate.enabled(); - * - * // changes the enabled state for all animations - * $animate.enabled(false); - * $animate.enabled(true); - * - * // returns true or false if animations are enabled for an element - * $animate.enabled(element); - * - * // changes the enabled state for an element and its children - * $animate.enabled(element, true); - * $animate.enabled(element, false); - * ``` - * - * @param {DOMElement=} element the element that will be considered for checking/setting the enabled state - * @param {boolean=} enabled whether or not the animations will be enabled for the element - * - * @return {boolean} whether or not animations are enabled - */ - enabled: $$animateQueue.enabled, - - /** - * @ngdoc method - * @name $animate#cancel - * @kind function - * @description Cancels the provided animation. - * - * @param {Promise} animationPromise The animation promise that is returned when an animation is started. - */ - cancel: function(runner) { - runner.end && runner.end(); - }, - - /** - * - * @ngdoc method - * @name $animate#enter - * @kind function - * @description Inserts the element into the DOM either after the `after` element (if provided) or - * as the first child within the `parent` element and then triggers an animation. - * A promise is returned that will be resolved during the next digest once the animation - * has completed. - * - * @param {DOMElement} element the element which will be inserted into the DOM - * @param {DOMElement} parent the parent element which will append the element as - * a child (so long as the after element is not present) - * @param {DOMElement=} after the sibling element after which the element will be appended - * @param {object=} options an optional collection of options/styles that will be applied to the element - * - * @return {Promise} the animation callback promise - */ - enter: function(element, parent, after, options) { - parent = parent && jqLite(parent); - after = after && jqLite(after); - parent = parent || after.parent(); - domInsert(element, parent, after); - return $$animateQueue.push(element, 'enter', prepareAnimateOptions(options)); - }, - - /** - * - * @ngdoc method - * @name $animate#move - * @kind function - * @description Inserts (moves) the element into its new position in the DOM either after - * the `after` element (if provided) or as the first child within the `parent` element - * and then triggers an animation. A promise is returned that will be resolved - * during the next digest once the animation has completed. - * - * @param {DOMElement} element the element which will be moved into the new DOM position - * @param {DOMElement} parent the parent element which will append the element as - * a child (so long as the after element is not present) - * @param {DOMElement=} after the sibling element after which the element will be appended - * @param {object=} options an optional collection of options/styles that will be applied to the element - * - * @return {Promise} the animation callback promise - */ - move: function(element, parent, after, options) { - parent = parent && jqLite(parent); - after = after && jqLite(after); - parent = parent || after.parent(); - domInsert(element, parent, after); - return $$animateQueue.push(element, 'move', prepareAnimateOptions(options)); - }, - - /** - * @ngdoc method - * @name $animate#leave - * @kind function - * @description Triggers an animation and then removes the element from the DOM. - * When the function is called a promise is returned that will be resolved during the next - * digest once the animation has completed. - * - * @param {DOMElement} element the element which will be removed from the DOM - * @param {object=} options an optional collection of options/styles that will be applied to the element - * - * @return {Promise} the animation callback promise - */ - leave: function(element, options) { - return $$animateQueue.push(element, 'leave', prepareAnimateOptions(options), function() { - element.remove(); - }); - }, - - /** - * @ngdoc method - * @name $animate#addClass - * @kind function - * - * @description Triggers an addClass animation surrounding the addition of the provided CSS class(es). Upon - * execution, the addClass operation will only be handled after the next digest and it will not trigger an - * animation if element already contains the CSS class or if the class is removed at a later step. - * Note that class-based animations are treated differently compared to structural animations - * (like enter, move and leave) since the CSS classes may be added/removed at different points - * depending if CSS or JavaScript animations are used. - * - * @param {DOMElement} element the element which the CSS classes will be applied to - * @param {string} className the CSS class(es) that will be added (multiple classes are separated via spaces) - * @param {object=} options an optional collection of options/styles that will be applied to the element - * - * @return {Promise} the animation callback promise - */ - addClass: function(element, className, options) { - options = prepareAnimateOptions(options); - options.addClass = mergeClasses(options.addclass, className); - return $$animateQueue.push(element, 'addClass', options); - }, - - /** - * @ngdoc method - * @name $animate#removeClass - * @kind function - * - * @description Triggers a removeClass animation surrounding the removal of the provided CSS class(es). Upon - * execution, the removeClass operation will only be handled after the next digest and it will not trigger an - * animation if element does not contain the CSS class or if the class is added at a later step. - * Note that class-based animations are treated differently compared to structural animations - * (like enter, move and leave) since the CSS classes may be added/removed at different points - * depending if CSS or JavaScript animations are used. - * - * @param {DOMElement} element the element which the CSS classes will be applied to - * @param {string} className the CSS class(es) that will be removed (multiple classes are separated via spaces) - * @param {object=} options an optional collection of options/styles that will be applied to the element - * - * @return {Promise} the animation callback promise - */ - removeClass: function(element, className, options) { - options = prepareAnimateOptions(options); - options.removeClass = mergeClasses(options.removeClass, className); - return $$animateQueue.push(element, 'removeClass', options); - }, - - /** - * @ngdoc method - * @name $animate#setClass - * @kind function - * - * @description Performs both the addition and removal of a CSS classes on an element and (during the process) - * triggers an animation surrounding the class addition/removal. Much like `$animate.addClass` and - * `$animate.removeClass`, `setClass` will only evaluate the classes being added/removed once a digest has - * passed. Note that class-based animations are treated differently compared to structural animations - * (like enter, move and leave) since the CSS classes may be added/removed at different points - * depending if CSS or JavaScript animations are used. - * - * @param {DOMElement} element the element which the CSS classes will be applied to - * @param {string} add the CSS class(es) that will be added (multiple classes are separated via spaces) - * @param {string} remove the CSS class(es) that will be removed (multiple classes are separated via spaces) - * @param {object=} options an optional collection of options/styles that will be applied to the element - * - * @return {Promise} the animation callback promise - */ - setClass: function(element, add, remove, options) { - options = prepareAnimateOptions(options); - options.addClass = mergeClasses(options.addClass, add); - options.removeClass = mergeClasses(options.removeClass, remove); - return $$animateQueue.push(element, 'setClass', options); - }, - - /** - * @ngdoc method - * @name $animate#animate - * @kind function - * - * @description Performs an inline animation on the element which applies the provided to and from CSS styles to the element. - * If any detected CSS transition, keyframe or JavaScript matches the provided className value then the animation will take - * on the provided styles. For example, if a transition animation is set for the given className then the provided from and - * to styles will be applied alongside the given transition. If a JavaScript animation is detected then the provided styles - * will be given in as function paramters into the `animate` method (or as apart of the `options` parameter). - * - * @param {DOMElement} element the element which the CSS styles will be applied to - * @param {object} from the from (starting) CSS styles that will be applied to the element and across the animation. - * @param {object} to the to (destination) CSS styles that will be applied to the element and across the animation. - * @param {string=} className an optional CSS class that will be applied to the element for the duration of the animation. If - * this value is left as empty then a CSS class of `ng-inline-animate` will be applied to the element. - * (Note that if no animation is detected then this value will not be appplied to the element.) - * @param {object=} options an optional collection of options/styles that will be applied to the element - * - * @return {Promise} the animation callback promise - */ - animate: function(element, from, to, className, options) { - options = prepareAnimateOptions(options); - options.from = options.from ? extend(options.from, from) : from; - options.to = options.to ? extend(options.to, to) : to; - - className = className || 'ng-inline-animate'; - options.tempClasses = mergeClasses(options.tempClasses, className); - return $$animateQueue.push(element, 'animate', options); - } - }; - }]; -}]; - -var $$AnimateAsyncRunFactoryProvider = function() { - this.$get = ['$$rAF', function($$rAF) { - var waitQueue = []; - - function waitForTick(fn) { - waitQueue.push(fn); - if (waitQueue.length > 1) return; - $$rAF(function() { - for (var i = 0; i < waitQueue.length; i++) { - waitQueue[i](); - } - waitQueue = []; - }); - } - - return function() { - var passed = false; - waitForTick(function() { - passed = true; - }); - return function(callback) { - passed ? callback() : waitForTick(callback); - }; - }; - }]; -}; - -var $$AnimateRunnerFactoryProvider = function() { - this.$get = ['$q', '$sniffer', '$$animateAsyncRun', - function($q, $sniffer, $$animateAsyncRun) { - - var INITIAL_STATE = 0; - var DONE_PENDING_STATE = 1; - var DONE_COMPLETE_STATE = 2; - - AnimateRunner.chain = function(chain, callback) { - var index = 0; - - next(); - function next() { - if (index === chain.length) { - callback(true); - return; - } - - chain[index](function(response) { - if (response === false) { - callback(false); - return; - } - index++; - next(); - }); - } - }; - - AnimateRunner.all = function(runners, callback) { - var count = 0; - var status = true; - forEach(runners, function(runner) { - runner.done(onProgress); - }); - - function onProgress(response) { - status = status && response; - if (++count === runners.length) { - callback(status); - } - } - }; - - function AnimateRunner(host) { - this.setHost(host); - - this._doneCallbacks = []; - this._runInAnimationFrame = $$animateAsyncRun(); - this._state = 0; - } - - AnimateRunner.prototype = { - setHost: function(host) { - this.host = host || {}; - }, - - done: function(fn) { - if (this._state === DONE_COMPLETE_STATE) { - fn(); - } else { - this._doneCallbacks.push(fn); - } - }, - - progress: noop, - - getPromise: function() { - if (!this.promise) { - var self = this; - this.promise = $q(function(resolve, reject) { - self.done(function(status) { - status === false ? reject() : resolve(); - }); - }); - } - return this.promise; - }, - - then: function(resolveHandler, rejectHandler) { - return this.getPromise().then(resolveHandler, rejectHandler); - }, - - 'catch': function(handler) { - return this.getPromise()['catch'](handler); - }, - - 'finally': function(handler) { - return this.getPromise()['finally'](handler); - }, - - pause: function() { - if (this.host.pause) { - this.host.pause(); - } - }, - - resume: function() { - if (this.host.resume) { - this.host.resume(); - } - }, - - end: function() { - if (this.host.end) { - this.host.end(); - } - this._resolve(true); - }, - - cancel: function() { - if (this.host.cancel) { - this.host.cancel(); - } - this._resolve(false); - }, - - complete: function(response) { - var self = this; - if (self._state === INITIAL_STATE) { - self._state = DONE_PENDING_STATE; - self._runInAnimationFrame(function() { - self._resolve(response); - }); - } - }, - - _resolve: function(response) { - if (this._state !== DONE_COMPLETE_STATE) { - forEach(this._doneCallbacks, function(fn) { - fn(response); - }); - this._doneCallbacks.length = 0; - this._state = DONE_COMPLETE_STATE; - } - } - }; - - return AnimateRunner; - }]; -}; - -/** - * @ngdoc service - * @name $animateCss - * @kind object - * - * @description - * This is the core version of `$animateCss`. By default, only when the `ngAnimate` is included, - * then the `$animateCss` service will actually perform animations. - * - * Click here {@link ngAnimate.$animateCss to read the documentation for $animateCss}. - */ -var $CoreAnimateCssProvider = function() { - this.$get = ['$$rAF', '$q', '$$AnimateRunner', function($$rAF, $q, $$AnimateRunner) { - - return function(element, initialOptions) { - // we always make a copy of the options since - // there should never be any side effects on - // the input data when running `$animateCss`. - var options = copy(initialOptions); - - // there is no point in applying the styles since - // there is no animation that goes on at all in - // this version of $animateCss. - if (options.cleanupStyles) { - options.from = options.to = null; - } - - if (options.from) { - element.css(options.from); - options.from = null; - } - - /* jshint newcap: false */ - var closed, runner = new $$AnimateRunner(); - return { - start: run, - end: run - }; - - function run() { - $$rAF(function() { - applyAnimationContents(); - if (!closed) { - runner.complete(); - } - closed = true; - }); - return runner; - } - - function applyAnimationContents() { - if (options.addClass) { - element.addClass(options.addClass); - options.addClass = null; - } - if (options.removeClass) { - element.removeClass(options.removeClass); - options.removeClass = null; - } - if (options.to) { - element.css(options.to); - options.to = null; - } - } - }; - }]; -}; - -/* global stripHash: true */ - -/** - * ! This is a private undocumented service ! - * - * @name $browser - * @requires $log - * @description - * This object has two goals: - * - * - hide all the global state in the browser caused by the window object - * - abstract away all the browser specific features and inconsistencies - * - * For tests we provide {@link ngMock.$browser mock implementation} of the `$browser` - * service, which can be used for convenient testing of the application without the interaction with - * the real browser apis. - */ -/** - * @param {object} window The global window object. - * @param {object} document jQuery wrapped document. - * @param {object} $log window.console or an object with the same interface. - * @param {object} $sniffer $sniffer service - */ -function Browser(window, document, $log, $sniffer) { - var self = this, - rawDocument = document[0], - location = window.location, - history = window.history, - setTimeout = window.setTimeout, - clearTimeout = window.clearTimeout, - pendingDeferIds = {}; - - self.isMock = false; - - var outstandingRequestCount = 0; - var outstandingRequestCallbacks = []; - - // TODO(vojta): remove this temporary api - self.$$completeOutstandingRequest = completeOutstandingRequest; - self.$$incOutstandingRequestCount = function() { outstandingRequestCount++; }; - - /** - * Executes the `fn` function(supports currying) and decrements the `outstandingRequestCallbacks` - * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed. - */ - function completeOutstandingRequest(fn) { - try { - fn.apply(null, sliceArgs(arguments, 1)); - } finally { - outstandingRequestCount--; - if (outstandingRequestCount === 0) { - while (outstandingRequestCallbacks.length) { - try { - outstandingRequestCallbacks.pop()(); - } catch (e) { - $log.error(e); - } - } - } - } - } - - function getHash(url) { - var index = url.indexOf('#'); - return index === -1 ? '' : url.substr(index); - } - - /** - * @private - * Note: this method is used only by scenario runner - * TODO(vojta): prefix this method with $$ ? - * @param {function()} callback Function that will be called when no outstanding request - */ - self.notifyWhenNoOutstandingRequests = function(callback) { - if (outstandingRequestCount === 0) { - callback(); - } else { - outstandingRequestCallbacks.push(callback); - } - }; - - ////////////////////////////////////////////////////////////// - // URL API - ////////////////////////////////////////////////////////////// - - var cachedState, lastHistoryState, - lastBrowserUrl = location.href, - baseElement = document.find('base'), - pendingLocation = null; - - cacheState(); - lastHistoryState = cachedState; - - /** - * @name $browser#url - * - * @description - * GETTER: - * Without any argument, this method just returns current value of location.href. - * - * SETTER: - * With at least one argument, this method sets url to new value. - * If html5 history api supported, pushState/replaceState is used, otherwise - * location.href/location.replace is used. - * Returns its own instance to allow chaining - * - * NOTE: this api is intended for use only by the $location service. Please use the - * {@link ng.$location $location service} to change url. - * - * @param {string} url New url (when used as setter) - * @param {boolean=} replace Should new url replace current history record? - * @param {object=} state object to use with pushState/replaceState - */ - self.url = function(url, replace, state) { - // In modern browsers `history.state` is `null` by default; treating it separately - // from `undefined` would cause `$browser.url('/foo')` to change `history.state` - // to undefined via `pushState`. Instead, let's change `undefined` to `null` here. - if (isUndefined(state)) { - state = null; - } - - // Android Browser BFCache causes location, history reference to become stale. - if (location !== window.location) location = window.location; - if (history !== window.history) history = window.history; - - // setter - if (url) { - var sameState = lastHistoryState === state; - - // Don't change anything if previous and current URLs and states match. This also prevents - // IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode. - // See https://github.com/angular/angular.js/commit/ffb2701 - if (lastBrowserUrl === url && (!$sniffer.history || sameState)) { - return self; - } - var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url); - lastBrowserUrl = url; - lastHistoryState = state; - // Don't use history API if only the hash changed - // due to a bug in IE10/IE11 which leads - // to not firing a `hashchange` nor `popstate` event - // in some cases (see #9143). - if ($sniffer.history && (!sameBase || !sameState)) { - history[replace ? 'replaceState' : 'pushState'](state, '', url); - cacheState(); - // Do the assignment again so that those two variables are referentially identical. - lastHistoryState = cachedState; - } else { - if (!sameBase || pendingLocation) { - pendingLocation = url; - } - if (replace) { - location.replace(url); - } else if (!sameBase) { - location.href = url; - } else { - location.hash = getHash(url); - } - if (location.href !== url) { - pendingLocation = url; - } - } - return self; - // getter - } else { - // - pendingLocation is needed as browsers don't allow to read out - // the new location.href if a reload happened or if there is a bug like in iOS 9 (see - // https://openradar.appspot.com/22186109). - // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172 - return pendingLocation || location.href.replace(/%27/g,"'"); - } - }; - - /** - * @name $browser#state - * - * @description - * This method is a getter. - * - * Return history.state or null if history.state is undefined. - * - * @returns {object} state - */ - self.state = function() { - return cachedState; - }; - - var urlChangeListeners = [], - urlChangeInit = false; - - function cacheStateAndFireUrlChange() { - pendingLocation = null; - cacheState(); - fireUrlChange(); - } - - function getCurrentState() { - try { - return history.state; - } catch (e) { - // MSIE can reportedly throw when there is no state (UNCONFIRMED). - } - } - - // This variable should be used *only* inside the cacheState function. - var lastCachedState = null; - function cacheState() { - // This should be the only place in $browser where `history.state` is read. - cachedState = getCurrentState(); - cachedState = isUndefined(cachedState) ? null : cachedState; - - // Prevent callbacks fo fire twice if both hashchange & popstate were fired. - if (equals(cachedState, lastCachedState)) { - cachedState = lastCachedState; - } - lastCachedState = cachedState; - } - - function fireUrlChange() { - if (lastBrowserUrl === self.url() && lastHistoryState === cachedState) { - return; - } - - lastBrowserUrl = self.url(); - lastHistoryState = cachedState; - forEach(urlChangeListeners, function(listener) { - listener(self.url(), cachedState); - }); - } - - /** - * @name $browser#onUrlChange - * - * @description - * Register callback function that will be called, when url changes. - * - * It's only called when the url is changed from outside of angular: - * - user types different url into address bar - * - user clicks on history (forward/back) button - * - user clicks on a link - * - * It's not called when url is changed by $browser.url() method - * - * The listener gets called with new url as parameter. - * - * NOTE: this api is intended for use only by the $location service. Please use the - * {@link ng.$location $location service} to monitor url changes in angular apps. - * - * @param {function(string)} listener Listener function to be called when url changes. - * @return {function(string)} Returns the registered listener fn - handy if the fn is anonymous. - */ - self.onUrlChange = function(callback) { - // TODO(vojta): refactor to use node's syntax for events - if (!urlChangeInit) { - // We listen on both (hashchange/popstate) when available, as some browsers (e.g. Opera) - // don't fire popstate when user change the address bar and don't fire hashchange when url - // changed by push/replaceState - - // html5 history api - popstate event - if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange); - // hashchange event - jqLite(window).on('hashchange', cacheStateAndFireUrlChange); - - urlChangeInit = true; - } - - urlChangeListeners.push(callback); - return callback; - }; - - /** - * @private - * Remove popstate and hashchange handler from window. - * - * NOTE: this api is intended for use only by $rootScope. - */ - self.$$applicationDestroyed = function() { - jqLite(window).off('hashchange popstate', cacheStateAndFireUrlChange); - }; - - /** - * Checks whether the url has changed outside of Angular. - * Needs to be exported to be able to check for changes that have been done in sync, - * as hashchange/popstate events fire in async. - */ - self.$$checkUrlChange = fireUrlChange; - - ////////////////////////////////////////////////////////////// - // Misc API - ////////////////////////////////////////////////////////////// - - /** - * @name $browser#baseHref - * - * @description - * Returns current - * (always relative - without domain) - * - * @returns {string} The current base href - */ - self.baseHref = function() { - var href = baseElement.attr('href'); - return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : ''; - }; - - /** - * @name $browser#defer - * @param {function()} fn A function, who's execution should be deferred. - * @param {number=} [delay=0] of milliseconds to defer the function execution. - * @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`. - * - * @description - * Executes a fn asynchronously via `setTimeout(fn, delay)`. - * - * Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using - * `setTimeout` in tests, the fns are queued in an array, which can be programmatically flushed - * via `$browser.defer.flush()`. - * - */ - self.defer = function(fn, delay) { - var timeoutId; - outstandingRequestCount++; - timeoutId = setTimeout(function() { - delete pendingDeferIds[timeoutId]; - completeOutstandingRequest(fn); - }, delay || 0); - pendingDeferIds[timeoutId] = true; - return timeoutId; - }; - - - /** - * @name $browser#defer.cancel - * - * @description - * Cancels a deferred task identified with `deferId`. - * - * @param {*} deferId Token returned by the `$browser.defer` function. - * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully - * canceled. - */ - self.defer.cancel = function(deferId) { - if (pendingDeferIds[deferId]) { - delete pendingDeferIds[deferId]; - clearTimeout(deferId); - completeOutstandingRequest(noop); - return true; - } - return false; - }; - -} - -function $BrowserProvider() { - this.$get = ['$window', '$log', '$sniffer', '$document', - function($window, $log, $sniffer, $document) { - return new Browser($window, $document, $log, $sniffer); - }]; -} - -/** - * @ngdoc service - * @name $cacheFactory - * - * @description - * Factory that constructs {@link $cacheFactory.Cache Cache} objects and gives access to - * them. - * - * ```js - * - * var cache = $cacheFactory('cacheId'); - * expect($cacheFactory.get('cacheId')).toBe(cache); - * expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined(); - * - * cache.put("key", "value"); - * cache.put("another key", "another value"); - * - * // We've specified no options on creation - * expect(cache.info()).toEqual({id: 'cacheId', size: 2}); - * - * ``` - * - * - * @param {string} cacheId Name or id of the newly created cache. - * @param {object=} options Options object that specifies the cache behavior. Properties: - * - * - `{number=}` `capacity` — turns the cache into LRU cache. - * - * @returns {object} Newly created cache object with the following set of methods: - * - * - `{object}` `info()` — Returns id, size, and options of cache. - * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns - * it. - * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss. - * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache. - * - `{void}` `removeAll()` — Removes all cached values. - * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory. - * - * @example - - -
- - - - -

Cached Values

-
- - : - -
- -

Cache Info

-
- - : - -
-
-
- - angular.module('cacheExampleApp', []). - controller('CacheController', ['$scope', '$cacheFactory', function($scope, $cacheFactory) { - $scope.keys = []; - $scope.cache = $cacheFactory('cacheId'); - $scope.put = function(key, value) { - if (angular.isUndefined($scope.cache.get(key))) { - $scope.keys.push(key); - } - $scope.cache.put(key, angular.isUndefined(value) ? null : value); - }; - }]); - - - p { - margin: 10px 0 3px; - } - -
- */ -function $CacheFactoryProvider() { - - this.$get = function() { - var caches = {}; - - function cacheFactory(cacheId, options) { - if (cacheId in caches) { - throw minErr('$cacheFactory')('iid', "CacheId '{0}' is already taken!", cacheId); - } - - var size = 0, - stats = extend({}, options, {id: cacheId}), - data = createMap(), - capacity = (options && options.capacity) || Number.MAX_VALUE, - lruHash = createMap(), - freshEnd = null, - staleEnd = null; - - /** - * @ngdoc type - * @name $cacheFactory.Cache - * - * @description - * A cache object used to store and retrieve data, primarily used by - * {@link $http $http} and the {@link ng.directive:script script} directive to cache - * templates and other data. - * - * ```js - * angular.module('superCache') - * .factory('superCache', ['$cacheFactory', function($cacheFactory) { - * return $cacheFactory('super-cache'); - * }]); - * ``` - * - * Example test: - * - * ```js - * it('should behave like a cache', inject(function(superCache) { - * superCache.put('key', 'value'); - * superCache.put('another key', 'another value'); - * - * expect(superCache.info()).toEqual({ - * id: 'super-cache', - * size: 2 - * }); - * - * superCache.remove('another key'); - * expect(superCache.get('another key')).toBeUndefined(); - * - * superCache.removeAll(); - * expect(superCache.info()).toEqual({ - * id: 'super-cache', - * size: 0 - * }); - * })); - * ``` - */ - return caches[cacheId] = { - - /** - * @ngdoc method - * @name $cacheFactory.Cache#put - * @kind function - * - * @description - * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be - * retrieved later, and incrementing the size of the cache if the key was not already - * present in the cache. If behaving like an LRU cache, it will also remove stale - * entries from the set. - * - * It will not insert undefined values into the cache. - * - * @param {string} key the key under which the cached data is stored. - * @param {*} value the value to store alongside the key. If it is undefined, the key - * will not be stored. - * @returns {*} the value stored. - */ - put: function(key, value) { - if (isUndefined(value)) return; - if (capacity < Number.MAX_VALUE) { - var lruEntry = lruHash[key] || (lruHash[key] = {key: key}); - - refresh(lruEntry); - } - - if (!(key in data)) size++; - data[key] = value; - - if (size > capacity) { - this.remove(staleEnd.key); - } - - return value; - }, - - /** - * @ngdoc method - * @name $cacheFactory.Cache#get - * @kind function - * - * @description - * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object. - * - * @param {string} key the key of the data to be retrieved - * @returns {*} the value stored. - */ - get: function(key) { - if (capacity < Number.MAX_VALUE) { - var lruEntry = lruHash[key]; - - if (!lruEntry) return; - - refresh(lruEntry); - } - - return data[key]; - }, - - - /** - * @ngdoc method - * @name $cacheFactory.Cache#remove - * @kind function - * - * @description - * Removes an entry from the {@link $cacheFactory.Cache Cache} object. - * - * @param {string} key the key of the entry to be removed - */ - remove: function(key) { - if (capacity < Number.MAX_VALUE) { - var lruEntry = lruHash[key]; - - if (!lruEntry) return; - - if (lruEntry == freshEnd) freshEnd = lruEntry.p; - if (lruEntry == staleEnd) staleEnd = lruEntry.n; - link(lruEntry.n,lruEntry.p); - - delete lruHash[key]; - } - - if (!(key in data)) return; - - delete data[key]; - size--; - }, - - - /** - * @ngdoc method - * @name $cacheFactory.Cache#removeAll - * @kind function - * - * @description - * Clears the cache object of any entries. - */ - removeAll: function() { - data = createMap(); - size = 0; - lruHash = createMap(); - freshEnd = staleEnd = null; - }, - - - /** - * @ngdoc method - * @name $cacheFactory.Cache#destroy - * @kind function - * - * @description - * Destroys the {@link $cacheFactory.Cache Cache} object entirely, - * removing it from the {@link $cacheFactory $cacheFactory} set. - */ - destroy: function() { - data = null; - stats = null; - lruHash = null; - delete caches[cacheId]; - }, - - - /** - * @ngdoc method - * @name $cacheFactory.Cache#info - * @kind function - * - * @description - * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}. - * - * @returns {object} an object with the following properties: - *
    - *
  • **id**: the id of the cache instance
  • - *
  • **size**: the number of entries kept in the cache instance
  • - *
  • **...**: any additional properties from the options object when creating the - * cache.
  • - *
- */ - info: function() { - return extend({}, stats, {size: size}); - } - }; - - - /** - * makes the `entry` the freshEnd of the LRU linked list - */ - function refresh(entry) { - if (entry != freshEnd) { - if (!staleEnd) { - staleEnd = entry; - } else if (staleEnd == entry) { - staleEnd = entry.n; - } - - link(entry.n, entry.p); - link(entry, freshEnd); - freshEnd = entry; - freshEnd.n = null; - } - } - - - /** - * bidirectionally links two entries of the LRU linked list - */ - function link(nextEntry, prevEntry) { - if (nextEntry != prevEntry) { - if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify - if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify - } - } - } - - - /** - * @ngdoc method - * @name $cacheFactory#info - * - * @description - * Get information about all the caches that have been created - * - * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info` - */ - cacheFactory.info = function() { - var info = {}; - forEach(caches, function(cache, cacheId) { - info[cacheId] = cache.info(); - }); - return info; - }; - - - /** - * @ngdoc method - * @name $cacheFactory#get - * - * @description - * Get access to a cache object by the `cacheId` used when it was created. - * - * @param {string} cacheId Name or id of a cache to access. - * @returns {object} Cache object identified by the cacheId or undefined if no such cache. - */ - cacheFactory.get = function(cacheId) { - return caches[cacheId]; - }; - - - return cacheFactory; - }; -} - -/** - * @ngdoc service - * @name $templateCache - * - * @description - * The first time a template is used, it is loaded in the template cache for quick retrieval. You - * can load templates directly into the cache in a `script` tag, or by consuming the - * `$templateCache` service directly. - * - * Adding via the `script` tag: - * - * ```html - * - * ``` - * - * **Note:** the `script` tag containing the template does not need to be included in the `head` of - * the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE, - * element with ng-app attribute), otherwise the template will be ignored. - * - * Adding via the `$templateCache` service: - * - * ```js - * var myApp = angular.module('myApp', []); - * myApp.run(function($templateCache) { - * $templateCache.put('templateId.html', 'This is the content of the template'); - * }); - * ``` - * - * To retrieve the template later, simply use it in your HTML: - * ```html - *
- * ``` - * - * or get it via Javascript: - * ```js - * $templateCache.get('templateId.html') - * ``` - * - * See {@link ng.$cacheFactory $cacheFactory}. - * - */ -function $TemplateCacheProvider() { - this.$get = ['$cacheFactory', function($cacheFactory) { - return $cacheFactory('templates'); - }]; -} - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * 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? * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE! - * - * DOM-related variables: - * - * - "node" - DOM Node - * - "element" - DOM Element or Node - * - "$node" or "$element" - jqLite-wrapped node or element - * - * - * Compiler related stuff: - * - * - "linkFn" - linking fn of a single directive - * - "nodeLinkFn" - function that aggregates all linking fns for a particular node - * - "childLinkFn" - function that aggregates all linking fns for child nodes of a particular node - * - "compositeLinkFn" - function that aggregates all linking fns for a compilation root (nodeList) - */ - - -/** - * @ngdoc service - * @name $compile - * @kind function - * - * @description - * Compiles an HTML string or DOM into a template and produces a template function, which - * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together. - * - * The compilation is a process of walking the DOM tree and matching DOM elements to - * {@link ng.$compileProvider#directive directives}. - * - *
- * **Note:** This document is an in-depth reference of all directive options. - * For a gentle introduction to directives with examples of common use cases, - * see the {@link guide/directive directive guide}. - *
- * - * ## Comprehensive Directive API - * - * There are many different options for a directive. - * - * The difference resides in the return value of the factory function. - * You can either return a "Directive Definition Object" (see below) that defines the directive properties, - * or just the `postLink` function (all other properties will have the default values). - * - *
- * **Best Practice:** It's recommended to use the "directive definition object" form. - *
- * - * Here's an example directive declared with a Directive Definition Object: - * - * ```js - * var myModule = angular.module(...); - * - * myModule.directive('directiveName', function factory(injectables) { - * var directiveDefinitionObject = { - * priority: 0, - * template: '
', // or // function(tElement, tAttrs) { ... }, - * // or - * // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... }, - * transclude: false, - * restrict: 'A', - * templateNamespace: 'html', - * scope: false, - * controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... }, - * controllerAs: 'stringIdentifier', - * bindToController: false, - * require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'], - * compile: function compile(tElement, tAttrs, transclude) { - * return { - * pre: function preLink(scope, iElement, iAttrs, controller) { ... }, - * post: function postLink(scope, iElement, iAttrs, controller) { ... } - * } - * // or - * // return function postLink( ... ) { ... } - * }, - * // or - * // link: { - * // pre: function preLink(scope, iElement, iAttrs, controller) { ... }, - * // post: function postLink(scope, iElement, iAttrs, controller) { ... } - * // } - * // or - * // link: function postLink( ... ) { ... } - * }; - * return directiveDefinitionObject; - * }); - * ``` - * - *
- * **Note:** Any unspecified options will use the default value. You can see the default values below. - *
- * - * Therefore the above can be simplified as: - * - * ```js - * var myModule = angular.module(...); - * - * myModule.directive('directiveName', function factory(injectables) { - * var directiveDefinitionObject = { - * link: function postLink(scope, iElement, iAttrs) { ... } - * }; - * return directiveDefinitionObject; - * // or - * // return function postLink(scope, iElement, iAttrs) { ... } - * }); - * ``` - * - * - * - * ### Directive Definition Object - * - * The directive definition object provides instructions to the {@link ng.$compile - * compiler}. The attributes are: - * - * #### `multiElement` - * When this property is set to true, the HTML compiler will collect DOM nodes between - * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them - * together as the directive elements. It is recommended that this feature be used on directives - * which are not strictly behavioural (such as {@link ngClick}), and which - * do not manipulate or replace child nodes (such as {@link ngInclude}). - * - * #### `priority` - * When there are multiple directives defined on a single DOM element, sometimes it - * is necessary to specify the order in which the directives are applied. The `priority` is used - * to sort the directives before their `compile` functions get called. Priority is defined as a - * number. Directives with greater numerical `priority` are compiled first. Pre-link functions - * are also run in priority order, but post-link functions are run in reverse order. The order - * of directives with the same priority is undefined. The default priority is `0`. - * - * #### `terminal` - * If set to true then the current `priority` will be the last set of directives - * which will execute (any directives at the current priority will still execute - * as the order of execution on same `priority` is undefined). Note that expressions - * and other directives used in the directive's template will also be excluded from execution. - * - * #### `scope` - * The scope property can be `true`, an object or a falsy value: - * - * * **falsy:** No scope will be created for the directive. The directive will use its parent's scope. - * - * * **`true`:** A new child scope that prototypically inherits from its parent will be created for - * the directive's element. If multiple directives on the same element request a new scope, - * only one new scope is created. The new scope rule does not apply for the root of the template - * since the root of the template always gets a new scope. - * - * * **`{...}` (an object hash):** A new "isolate" scope is created for the directive's element. The - * 'isolate' scope differs from normal scope in that it does not prototypically inherit from its parent - * scope. This is useful when creating reusable components, which should not accidentally read or modify - * data in the parent scope. - * - * The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the - * directive's element. These local properties are useful for aliasing values for templates. The keys in - * the object hash map to the name of the property on the isolate scope; the values define how the property - * is bound to the parent scope, via matching attributes on the directive's element: - * - * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is - * always a string since DOM attributes are strings. If no `attr` name is specified then the - * attribute name is assumed to be the same as the local name. - * Given `` and widget definition - * of `scope: { localName:'@myAttr' }`, then widget scope property `localName` will reflect - * the interpolated value of `hello {{name}}`. As the `name` attribute changes so will the - * `localName` property on the widget scope. The `name` is read from the parent scope (not - * component scope). - * - * * `=` or `=attr` - set up bi-directional binding between a local scope property and the - * parent scope property of name defined via the value of the `attr` attribute. If no `attr` - * name is specified then the attribute name is assumed to be the same as the local name. - * Given `` and widget definition of - * `scope: { localModel:'=myAttr' }`, then widget scope property `localModel` will reflect the - * value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected - * in `localModel` and any changes in `localModel` will reflect in `parentModel`. If the parent - * scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You - * can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional. If - * you want to shallow watch for changes (i.e. $watchCollection instead of $watch) you can use - * `=*` or `=*attr` (`=*?` or `=*?attr` if the property is optional). - * - * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope. - * If no `attr` name is specified then the attribute name is assumed to be the same as the - * local name. Given `` and widget definition of - * `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to - * a function wrapper for the `count = count + value` expression. Often it's desirable to - * pass data from the isolated scope via an expression to the parent scope, this can be - * done by passing a map of local variable names and values into the expression wrapper fn. - * For example, if the expression is `increment(amount)` then we can specify the amount value - * by calling the `localFn` as `localFn({amount: 22})`. - * - * In general it's possible to apply more than one directive to one element, but there might be limitations - * depending on the type of scope required by the directives. The following points will help explain these limitations. - * For simplicity only two directives are taken into account, but it is also applicable for several directives: - * - * * **no scope** + **no scope** => Two directives which don't require their own scope will use their parent's scope - * * **child scope** + **no scope** => Both directives will share one single child scope - * * **child scope** + **child scope** => Both directives will share one single child scope - * * **isolated scope** + **no scope** => The isolated directive will use it's own created isolated scope. The other directive will use - * its parent's scope - * * **isolated scope** + **child scope** => **Won't work!** Only one scope can be related to one element. Therefore these directives cannot - * be applied to the same element. - * * **isolated scope** + **isolated scope** => **Won't work!** Only one scope can be related to one element. Therefore these directives - * cannot be applied to the same element. - * - * - * #### `bindToController` - * When an isolate scope is used for a component (see above), and `controllerAs` is used, `bindToController: true` will - * allow a component to have its properties bound to the controller, rather than to scope. When the controller - * is instantiated, the initial values of the isolate scope bindings are already available. - * - * #### `controller` - * Controller constructor function. The controller is instantiated before the - * pre-linking phase and can be accessed by other directives (see - * `require` attribute). This allows the directives to communicate with each other and augment - * each other's behavior. The controller is injectable (and supports bracket notation) with the following locals: - * - * * `$scope` - Current scope associated with the element - * * `$element` - Current element - * * `$attrs` - Current attributes object for the element - * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope: - * `function([scope], cloneLinkingFn, futureParentElement, slotName)`: - * * `scope`: (optional) override the scope. - * * `cloneLinkingFn`: (optional) argument to create clones of the original transcluded content. - * * `futureParentElement` (optional): - * * defines the parent to which the `cloneLinkingFn` will add the cloned elements. - * * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`. - * * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements) - * and when the `cloneLinkinFn` is passed, - * as those elements need to created and cloned in a special way when they are defined outside their - * usual containers (e.g. like ``). - * * See also the `directive.templateNamespace` property. - * * `slotName`: (optional) the name of the slot to transclude. If falsy (e.g. `null`, `undefined` or `''`) - * then the default translusion is provided. - * The `$transclude` function also has a method on it, `$transclude.isSlotFilled(slotName)`, which returns - * `true` if the specified slot contains content (i.e. one or more DOM nodes). - * - * #### `require` - * Require another directive and inject its controller as the fourth argument to the linking function. The - * `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the - * injected argument will be an array in corresponding order. If no such directive can be - * found, or if the directive does not have a controller, then an error is raised (unless no link function - * is specified, in which case error checking is skipped). The name can be prefixed with: - * - * * (no prefix) - Locate the required controller on the current element. Throw an error if not found. - * * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found. - * * `^` - Locate the required controller by searching the element and its parents. Throw an error if not found. - * * `^^` - Locate the required controller by searching the element's parents. Throw an error if not found. - * * `?^` - Attempt to locate the required controller by searching the element and its parents or pass - * `null` to the `link` fn if not found. - * * `?^^` - Attempt to locate the required controller by searching the element's parents, or pass - * `null` to the `link` fn if not found. - * - * - * #### `controllerAs` - * Identifier name for a reference to the controller in the directive's scope. - * This allows the controller to be referenced from the directive template. This is especially - * useful when a directive is used as component, i.e. with an `isolate` scope. It's also possible - * to use it in a directive without an `isolate` / `new` scope, but you need to be aware that the - * `controllerAs` reference might overwrite a property that already exists on the parent scope. - * - * - * #### `restrict` - * String of subset of `EACM` which restricts the directive to a specific directive - * declaration style. If omitted, the defaults (elements and attributes) are used. - * - * * `E` - Element name (default): `` - * * `A` - Attribute (default): `
` - * * `C` - Class: `
` - * * `M` - Comment: `` - * - * - * #### `templateNamespace` - * String representing the document type used by the markup in the template. - * AngularJS needs this information as those elements need to be created and cloned - * in a special way when they are defined outside their usual containers like `` and ``. - * - * * `html` - All root nodes in the template are HTML. Root nodes may also be - * top-level elements such as `` or ``. - * * `svg` - The root nodes in the template are SVG elements (excluding ``). - * * `math` - The root nodes in the template are MathML elements (excluding ``). - * - * If no `templateNamespace` is specified, then the namespace is considered to be `html`. - * - * #### `template` - * HTML markup that may: - * * Replace the contents of the directive's element (default). - * * Replace the directive's element itself (if `replace` is true - DEPRECATED). - * * Wrap the contents of the directive's element (if `transclude` is true). - * - * Value may be: - * - * * A string. For example `
{{delete_str}}
`. - * * A function which takes two arguments `tElement` and `tAttrs` (described in the `compile` - * function api below) and returns a string value. - * - * - * #### `templateUrl` - * This is similar to `template` but the template is loaded from the specified URL, asynchronously. - * - * Because template loading is asynchronous the compiler will suspend compilation of directives on that element - * for later when the template has been resolved. In the meantime it will continue to compile and link - * sibling and parent elements as though this element had not contained any directives. - * - * The compiler does not suspend the entire compilation to wait for templates to be loaded because this - * would result in the whole app "stalling" until all templates are loaded asynchronously - even in the - * case when only one deeply nested directive has `templateUrl`. - * - * Template loading is asynchronous even if the template has been preloaded into the {@link $templateCache} - * - * You can specify `templateUrl` as a string representing the URL or as a function which takes two - * arguments `tElement` and `tAttrs` (described in the `compile` function api below) and returns - * a string value representing the url. In either case, the template URL is passed through {@link - * $sce#getTrustedResourceUrl $sce.getTrustedResourceUrl}. - * - * - * #### `replace` ([*DEPRECATED*!], will be removed in next major release - i.e. v2.0) - * specify what the template should replace. Defaults to `false`. - * - * * `true` - the template will replace the directive's element. - * * `false` - the template will replace the contents of the directive's element. - * - * The replacement process migrates all of the attributes / classes from the old element to the new - * one. See the {@link guide/directive#template-expanding-directive - * Directives Guide} for an example. - * - * There are very few scenarios where element replacement is required for the application function, - * the main one being reusable custom components that are used within SVG contexts - * (because SVG doesn't work with custom elements in the DOM tree). - * - * #### `transclude` - * Extract the contents of the element where the directive appears and make it available to the directive. - * The contents are compiled and provided to the directive as a **transclusion function**. See the - * {@link $compile#transclusion Transclusion} section below. - * - * - * #### `compile` - * - * ```js - * function compile(tElement, tAttrs, transclude) { ... } - * ``` - * - * The compile function deals with transforming the template DOM. Since most directives do not do - * template transformation, it is not used often. The compile function takes the following arguments: - * - * * `tElement` - template element - The element where the directive has been declared. It is - * safe to do template transformation on the element and child elements only. - * - * * `tAttrs` - template attributes - Normalized list of attributes declared on this element shared - * between all directive compile functions. - * - * * `transclude` - [*DEPRECATED*!] A transclude linking function: `function(scope, cloneLinkingFn)` - * - *
- * **Note:** The template instance and the link instance may be different objects if the template has - * been cloned. For this reason it is **not** safe to do anything other than DOM transformations that - * apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration - * should be done in a linking function rather than in a compile function. - *
- - *
- * **Note:** The compile function cannot handle directives that recursively use themselves in their - * own templates or compile functions. Compiling these directives results in an infinite loop and a - * stack overflow errors. - * - * This can be avoided by manually using $compile in the postLink function to imperatively compile - * a directive's template instead of relying on automatic template compilation via `template` or - * `templateUrl` declaration or manual compilation inside the compile function. - *
- * - *
- * **Note:** The `transclude` function that is passed to the compile function is deprecated, as it - * e.g. does not know about the right outer scope. Please use the transclude function that is passed - * to the link function instead. - *
- - * A compile function can have a return value which can be either a function or an object. - * - * * returning a (post-link) function - is equivalent to registering the linking function via the - * `link` property of the config object when the compile function is empty. - * - * * returning an object with function(s) registered via `pre` and `post` properties - allows you to - * control when a linking function should be called during the linking phase. See info about - * pre-linking and post-linking functions below. - * - * - * #### `link` - * This property is used only if the `compile` property is not defined. - * - * ```js - * function link(scope, iElement, iAttrs, controller, transcludeFn) { ... } - * ``` - * - * The link function is responsible for registering DOM listeners as well as updating the DOM. It is - * executed after the template has been cloned. This is where most of the directive logic will be - * put. - * - * * `scope` - {@link ng.$rootScope.Scope Scope} - The scope to be used by the - * directive for registering {@link ng.$rootScope.Scope#$watch watches}. - * - * * `iElement` - instance element - The element where the directive is to be used. It is safe to - * manipulate the children of the element only in `postLink` function since the children have - * already been linked. - * - * * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared - * between all directive linking functions. - * - * * `controller` - the directive's required controller instance(s) - Instances are shared - * among all directives, which allows the directives to use the controllers as a communication - * channel. The exact value depends on the directive's `require` property: - * * no controller(s) required: the directive's own controller, or `undefined` if it doesn't have one - * * `string`: the controller instance - * * `array`: array of controller instances - * - * If a required controller cannot be found, and it is optional, the instance is `null`, - * otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown. - * - * Note that you can also require the directive's own controller - it will be made available like - * any other controller. - * - * * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope. - * This is the same as the `$transclude` - * parameter of directive controllers, see there for details. - * `function([scope], cloneLinkingFn, futureParentElement)`. - * - * #### Pre-linking function - * - * Executed before the child elements are linked. Not safe to do DOM transformation since the - * compiler linking function will fail to locate the correct elements for linking. - * - * #### Post-linking function - * - * Executed after the child elements are linked. - * - * Note that child elements that contain `templateUrl` directives will not have been compiled - * and linked since they are waiting for their template to load asynchronously and their own - * compilation and linking has been suspended until that occurs. - * - * It is safe to do DOM transformation in the post-linking function on elements that are not waiting - * for their async templates to be resolved. - * - * - * ### Transclusion - * - * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and - * copying them to another part of the DOM, while maintaining their connection to the original AngularJS - * scope from where they were taken. - * - * Transclusion is used (often with {@link ngTransclude}) to insert the - * original contents of a directive's element into a specified place in the template of the directive. - * The benefit of transclusion, over simply moving the DOM elements manually, is that the transcluded - * content has access to the properties on the scope from which it was taken, even if the directive - * has isolated scope. - * See the {@link guide/directive#creating-a-directive-that-wraps-other-elements Directives Guide}. - * - * This makes it possible for the widget to have private state for its template, while the transcluded - * content has access to its originating scope. - * - *
- * **Note:** When testing an element transclude directive you must not place the directive at the root of the - * DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives - * Testing Transclusion Directives}. - *
- * - * There are three kinds of transclusion depending upon whether you want to transclude just the contents of the - * directive's element, the entire element or multiple parts of the element contents: - * - * * `true` - transclude the content (i.e. the child nodes) of the directive's element. - * * `'element'` - transclude the whole of the directive's element including any directives on this - * element that defined at a lower priority than this directive. When used, the `template` - * property is ignored. - * * **`{...}` (an object hash):** - map elements of the content onto transclusion "slots" in the template. - * - * **Mult-slot transclusion** is declared by providing an object for the `transclude` property. - * - * This object is a map where the keys are the name of the slot to fill and the value is an element selector - * used to match the HTML to the slot. The element selector should be in normalized form (e.g. `myElement`) - * and will match the standard element variants (e.g. `my-element`, `my:element`, `data-my-element`, etc). - * - * For further information check out the guide on {@link guide/directive#matching-directives Matching Directives} - * - * If the element selector is prefixed with a `?` then that slot is optional. - * - * For example, the transclude object `{ slotA: '?myCustomElement' }` maps `` elements to - * the `slotA` slot, which can be accessed via the `$transclude` function or via the {@link ngTransclude} directive. - * - * Slots that are not marked as optional (`?`) will trigger a compile time error if there are no matching elements - * in the transclude content. If you wish to know if an optional slot was filled with content, then you can call - * `$transclude.isSlotFilled(slotName)` on the transclude function passed to the directive's link function and - * injectable into the directive's controller. - * - * - * #### Transclusion Functions - * - * When a directive requests transclusion, the compiler extracts its contents and provides a **transclusion - * function** to the directive's `link` function and `controller`. This transclusion function is a special - * **linking function** that will return the compiled contents linked to a new transclusion scope. - * - *
- * If you are just using {@link ngTransclude} then you don't need to worry about this function, since - * ngTransclude will deal with it for us. - *
- * - * If you want to manually control the insertion and removal of the transcluded content in your directive - * then you must use this transclude function. When you call a transclude function it returns a a jqLite/JQuery - * object that contains the compiled DOM, which is linked to the correct transclusion scope. - * - * When you call a transclusion function you can pass in a **clone attach function**. This function accepts - * two parameters, `function(clone, scope) { ... }`, where the `clone` is a fresh compiled copy of your transcluded - * content and the `scope` is the newly created transclusion scope, to which the clone is bound. - * - *
- * **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a translude function - * since you then get a fresh clone of the original DOM and also have access to the new transclusion scope. - *
- * - * It is normal practice to attach your transcluded content (`clone`) to the DOM inside your **clone - * attach function**: - * - * ```js - * var transcludedContent, transclusionScope; - * - * $transclude(function(clone, scope) { - * element.append(clone); - * transcludedContent = clone; - * transclusionScope = scope; - * }); - * ``` - * - * Later, if you want to remove the transcluded content from your DOM then you should also destroy the - * associated transclusion scope: - * - * ```js - * transcludedContent.remove(); - * transclusionScope.$destroy(); - * ``` - * - *
- * **Best Practice**: if you intend to add and remove transcluded content manually in your directive - * (by calling the transclude function to get the DOM and calling `element.remove()` to remove it), - * then you are also responsible for calling `$destroy` on the transclusion scope. - *
- * - * The built-in DOM manipulation directives, such as {@link ngIf}, {@link ngSwitch} and {@link ngRepeat} - * automatically destroy their transluded clones as necessary so you do not need to worry about this if - * you are simply using {@link ngTransclude} to inject the transclusion into your directive. - * - * - * #### Transclusion Scopes - * - * When you call a transclude function it returns a DOM fragment that is pre-bound to a **transclusion - * scope**. This scope is special, in that it is a child of the directive's scope (and so gets destroyed - * when the directive's scope gets destroyed) but it inherits the properties of the scope from which it - * was taken. - * - * For example consider a directive that uses transclusion and isolated scope. The DOM hierarchy might look - * like this: - * - * ```html - *
- *
- *
- *
- *
- *
- * ``` - * - * The `$parent` scope hierarchy will look like this: - * - * ``` - * - $rootScope - * - isolate - * - transclusion - * ``` - * - * but the scopes will inherit prototypically from different scopes to their `$parent`. - * - * ``` - * - $rootScope - * - transclusion - * - isolate - * ``` - * - * - * ### Attributes - * - * The {@link ng.$compile.directive.Attributes Attributes} object - passed as a parameter in the - * `link()` or `compile()` functions. It has a variety of uses. - * - * accessing *Normalized attribute names:* - * Directives like 'ngBind' can be expressed in many ways: 'ng:bind', `data-ng-bind`, or 'x-ng-bind'. - * the attributes object allows for normalized access to - * the attributes. - * - * * *Directive inter-communication:* All directives share the same instance of the attributes - * object which allows the directives to use the attributes object as inter directive - * communication. - * - * * *Supports interpolation:* Interpolation attributes are assigned to the attribute object - * allowing other directives to read the interpolated value. - * - * * *Observing interpolated attributes:* Use `$observe` to observe the value changes of attributes - * that contain interpolation (e.g. `src="{{bar}}"`). Not only is this very efficient but it's also - * the only way to easily get the actual value because during the linking phase the interpolation - * hasn't been evaluated yet and so the value is at this time set to `undefined`. - * - * ```js - * function linkingFn(scope, elm, attrs, ctrl) { - * // get the attribute value - * console.log(attrs.ngModel); - * - * // change the attribute - * attrs.$set('ngModel', 'new value'); - * - * // observe changes to interpolated attribute - * attrs.$observe('ngModel', function(value) { - * console.log('ngModel has changed value to ' + value); - * }); - * } - * ``` - * - * ## Example - * - *
- * **Note**: Typically directives are registered with `module.directive`. The example below is - * to illustrate how `$compile` works. - *
- * - - - -
-
-
-
-
-
- - 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 controller instances; if given, it will make the controllers - * available to directives. - * * `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. - */ - -var $compileMinErr = minErr('$compile'); - -/** - * @ngdoc provider - * @name $compileProvider - * - * @description - */ -$CompileProvider.$inject = ['$provide', '$$sanitizeUriProvider']; -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)$/; - - function parseIsolateBindings(scope, directiveName, isController) { - var LOCAL_REGEXP = /^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/; - - var bindings = {}; - - forEach(scope, function(definition, scopeName) { - 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 - }; - }); - - 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 (isObject(bindings.bindToController)) { - var controller = directive.controller; - var controllerAs = directive.controllerAs; - if (!controller) { - // There is no controller, there may or may not be a controllerAs property - throw $compileMinErr('noctrl', - "Cannot bind to controller without directive '{0}'s controller.", - directiveName); - } else if (!identifierForController(controller, controllerAs)) { - // There is a controller, but no identifier or controllerAs property - throw $compileMinErr('noident', - "Cannot bind to controller without identifier for directive '{0}'.", - directiveName); - } - } - return bindings; - } - - function assertValidDirectiveName(name) { - var letter = name.charAt(0); - if (!letter || letter !== lowercase(letter)) { - throw $compileMinErr('baddir', "Directive name '{0}' is invalid. The first character must be a lowercase letter", name); - } - if (name !== name.trim()) { - throw $compileMinErr('baddir', - "Directive name '{0}' is invalid. The name should not contain leading or trailing whitespaces", - name); - } - } - - /** - * @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 - * {@link guide/directive} for more info. - * @returns {ng.$compileProvider} Self for chaining. - */ - this.directive = function registerDirective(name, directiveFactory) { - 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 = directive.require || (directive.controller && directive.name); - directive.restrict = directive.restrict || 'EA'; - var bindings = directive.$$bindings = - parseDirectiveBindings(directive, directive.name); - if (isObject(bindings.isolateScope)) { - directive.$$isolateBindings = bindings.isolateScope; - } - 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#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; - }; - - this.$get = [ - '$injector', '$interpolate', '$exceptionHandler', '$templateRequest', '$parse', - '$controller', '$rootScope', '$document', '$sce', '$animate', '$$sanitizeUri', - function($injector, $interpolate, $exceptionHandler, $templateRequest, $parse, - $controller, $rootScope, $document, $sce, $animate, $$sanitizeUri) { - - var SIMPLE_ATTR_NAME = /^\w/; - var specialAttrHolder = document.createElement('div'); - var Attributes = function(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') { - // 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; - $$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/directive#text-and-attribute-bindings Directives} 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; - - 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); - } - // We can not compile top level text elements since text nodes can be merged and we will - // not be able to attach scope data to them, so we will wrap them in - forEach($compileNodes, function(node, index) { - if (node.nodeType == NODE_TYPE_TEXT && node.nodeValue.match(/\S+/) /* non-empty */) { - $compileNodes[index] = jqLite(node).wrap('').parent()[0]; - } - }); - var compositeLinkFn = - compileNodes($compileNodes, transcludeFn, $compileNodes, - maxPriority, ignoreDirective, previousCompileContext); - compile.$$addScopeClass($compileNodes); - var namespace = null; - return function publicLinkFn(scope, cloneConnectFn, options) { - 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); - 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' && node.toString().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 = [], - attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound; - - for (var i = 0; i < nodeList.length; i++) { - attrs = new Attributes(); - - // we must always refer to nodeList[i] 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 createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) { - - var boundTranscludeFn = function(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, - className; - - switch (nodeType) { - case NODE_TYPE_ELEMENT: /* Element */ - // use the node name: - addDirective(directives, - directiveNormalize(nodeName_(node)), '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 = trim(attr.value); - - // support ngAttr attribute binding - ngAttrName = directiveNormalize(name); - if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) { - 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); - } - - // use class as directive - 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 */ - if (msie === 11) { - // Workaround for #11781 - while (node.parentNode && node.nextSibling && node.nextSibling.nodeType === NODE_TYPE_TEXT) { - node.nodeValue = node.nodeValue + node.nextSibling.nodeValue; - node.parentNode.removeChild(node.nextSibling); - } - } - addTextInterpolateDirective(directives, node.nodeValue); - break; - case NODE_TYPE_COMMENT: /* Comment */ - try { - match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue); - if (match) { - 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.) - } - break; - } - - directives.sort(byPriority); - return directives; - } - - /** - * Given a node with an 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(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) { - if (eager) { - return compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext); - } - - var compiled; - - return function() { - 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 - } - - if (directiveValue = directive.scope) { - - // 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) { - directiveValue = directive.controller; - controllerDirectives = controllerDirectives || createMap(); - assertNoDuplicate("'" + directiveName + "' controller", - controllerDirectives[directiveName], directive, $compileNode); - controllerDirectives[directiveName] = directive; - } - - if (directiveValue = directive.transclude) { - 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(document.createComment(' ' + directiveName + ': ' + - templateAttrs[directiveName] + ' ')); - compileNode = $compileNode[0]; - replaceWith(jqCollection, sliceArgs($template), compileNode); - - 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(); - - $template = jqLite(jqLiteClone(compileNode)).contents(); - - if (isObject(directiveValue)) { - - // 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; - } - - 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); - if (isFunction(linkFn)) { - addLinkFns(null, linkFn, attrStart, attrEnd); - } else if (linkFn) { - addLinkFns(linkFn.pre, 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 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); - } - } - - return value || null; - } - - function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope) { - 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, - // but jQuery .data doesn't support attaching data to comment nodes as it's hard to - // clean up (http://bugs.jquery.com/ticket/8335). - // 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; - if (!hasElementTranscludeDirective) { - $element.data('$' + directive.name + 'Controller', controllerInstance.instance); - } - } - return elementControllers; - } - - function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) { - var linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element, - attrs, removeScopeBindingWatches, removeControllerBindingWatches; - - 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); - } - - 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; - removeScopeBindingWatches = initializeDirectiveBindings(scope, attrs, isolateScope, - isolateScope.$$isolateBindings, - newIsolateScopeDirective); - if (removeScopeBindingWatches) { - isolateScope.$on('$destroy', removeScopeBindingWatches); - } - } - - // Initialize bindToController bindings - for (var name in elementControllers) { - var controllerDirective = controllerDirectives[name]; - var controller = elementControllers[name]; - var bindings = controllerDirective.$$bindings.bindToController; - - if (controller.identifier && bindings) { - removeControllerBindingWatches = - initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective); - } - - 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); - removeControllerBindingWatches && removeControllerBindingWatches(); - removeControllerBindingWatches = - initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective); - } - } - - // 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; - } - 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 - ); - } - - // 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); - } - } - } - } - - // 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++) { - try { - directive = directives[i]; - if ((isUndefined(maxPriority) || maxPriority > directive.priority) && - directive.restrict.indexOf(location) != -1) { - if (startAttrName) { - directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName}); - } - tDirectives.push(directive); - match = directive; - } - } catch (e) { $exceptionHandler(e); } - } - } - 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, - $element = dst.$$element; - - // reapply the old attributes to the new element - forEach(dst, function(value, key) { - if (key.charAt(0) != '$') { - if (src[key] && src[key] !== value) { - value += (key === 'style' ? ';' : ' ') + src[key]; - } - dst.$set(key, value, true, srcAttr[key]); - } - }); - - // copy the new attributes on the old attrs object - forEach(src, function(value, key) { - if (key == 'class') { - safeAddClass($element, value); - dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value; - } else if (key == 'style') { - $element.attr('style', $element.attr('style') + ';' + value); - dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value; - // `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. - } else if (key.charAt(0) != '$' && !dst.hasOwnProperty(key)) { - dst[key] = value; - 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; - }); - - 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 = 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); - // maction[xlink:href] can source SVG. It's not limited to . - if (attrNormalizedName == "xlinkHref" || - (tag == "form" && attrNormalizedName == "action") || - (tag != "img" && (attrNormalizedName == "src" || - attrNormalizedName == "ngSrc"))) { - return $sce.RESOURCE_URL; - } - } - - - function addAttrInterpolateDirective(node, directives, value, name, allOrNothing) { - var trustedContext = getTrustedContext(node, name); - allOrNothing = ALL_OR_NOTHING_ATTRS[name] || allOrNothing; - - var interpolateFn = $interpolate(value, true, 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)); - } - - directives.push({ - priority: 100, - compile: function() { - return { - pre: function attrInterpolatePreLinkFn(scope, element, attr) { - var $$observers = (attr.$$observers || (attr.$$observers = createMap())); - - 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."); - } - - // 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 = 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. This process - // only occurs for isolate scopes and new scopes with controllerAs. - function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) { - var removeWatchCollection = []; - forEach(bindings, function(definition, scopeName) { - var attrName = definition.attrName, - optional = definition.optional, - mode = definition.mode, // @, =, or & - lastValue, - parentGet, parentSet, compare; - - switch (mode) { - - case '@': - if (!optional && !hasOwnProperty.call(attrs, attrName)) { - destination[scopeName] = attrs[attrName] = void 0; - } - attrs.$observe(attrName, function(value) { - if (isString(value)) { - destination[scopeName] = value; - } - }); - attrs.$$observers[attrName].$$scope = scope; - if (isString(attrs[attrName])) { - // 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(attrs[attrName])(scope); - } - break; - - case '=': - if (!hasOwnProperty.call(attrs, attrName)) { - if (optional) break; - attrs[attrName] = void 0; - } - if (optional && !attrs[attrName]) break; - - parentGet = $parse(attrs[attrName]); - if (parentGet.literal) { - compare = equals; - } else { - compare = function(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}' used with directive '{1}' is non-assignable!", - attrs[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]); - } - } - return lastValue = parentValue; - }; - parentValueWatch.$stateful = true; - var removeWatch; - 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 '&': - // 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; - } - }); - - return removeWatchCollection.length && function removeWatches() { - for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) { - removeWatchCollection[i](); - } - }; - } - }]; -} - -var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i; -/** - * Converts all accepted directives format into proper directive name. - * @param name Name to normalize - */ -function directiveNormalize(name) { - return camelCase(name.replace(PREFIX_REGEXP, '')); -} - -/** - * @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) { - 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 - * @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#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` - */ - 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 (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(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); - - 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); - } - - var instantiate; - return instantiate = extend(function() { - 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 - * - * @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); - }]; -} - -/** - * @ngdoc service - * @name $exceptionHandler - * @requires ng.$log - * - * @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: - * - * ```js - * angular.module('exceptionOverride', []).factory('$exceptionHandler', function() { - * return function(exception, cause) { - * exception.message += ' (caused by "' + cause + '")'; - * throw exception; - * }; - * }); - * ``` - * - * This example will override the normal action of `$exceptionHandler`, to make angular - * exceptions fail hard when they happen, instead of just logging to the console. - * - *
- * 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 = 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'); -var $httpMinErrLegacyFn = function(method) { - return function() { - throw $httpMinErr('legacy', 'The method `{0}` on the promise returned from `$http` has been disabled.', method); - }; -}; - -function serializeValue(v) { - if (isObject(v)) { - return isDate(v) ? v.toISOString() : toJson(v); - } - return v; -} - - -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, k) { - parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(v))); - }); - } else { - parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value))); - } - }); - - return parts.join('&'); - }; - }; -} - -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 single 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 === void 0) { - 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 - * @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`** - {Object} - an object built with {@link ng.$cacheFactory `$cacheFactory`} - * that will provide the cache for all requests who set their `cache` property to `true`. - * If you set the `defaults.cache = false` then only requests that specify their own custom - * cache object will be cached. 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}. - * - **/ - 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' - }; - - 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; - }; - - var useLegacyPromise = true; - /** - * @ngdoc method - * @name $httpProvider#useLegacyPromiseExtensions - * @description - * - * Configure `$http` service to return promises without the shorthand methods `success` and `error`. - * This should be used to make sure that applications work without these methods. - * - * Defaults to true. If no value is specified, returns the current configured value. - * - * @param {boolean=} value If true, `$http` will return a promise with the deprecated legacy `success` and `error` methods. - * - * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining. - * otherwise, returns the current configured value. - **/ - this.useLegacyPromiseExtensions = function(value) { - if (isDefined(value)) { - useLegacyPromise = !!value; - return this; - } - return useLegacyPromise; - }; - - /** - * @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 = ['$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector', - function($httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector) { - - 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. Note that if the response is a redirect, - * XMLHttpRequest will transparently follow it, meaning that the error callback will not be - * called for such responses. - * - * - * ## 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(); - * ``` - * - * ## Deprecation Notice - *
- * The `$http` legacy promise methods `success` and `error` have been deprecated. - * Use the standard `then` method instead. - * If {@link $httpProvider#useLegacyPromiseExtensions `$httpProvider.useLegacyPromiseExtensions`} is set to - * `false` then these methods will throw {@link $http:legacy `$http/legacy`} error. - *
- * - * ## 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. - * - * ### 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 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 - * - * To enable caching, set the request configuration `cache` property to `true` (to use default - * cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}). - * When the cache is enabled, `$http` stores the response from the server in the specified - * cache. The next time the same request is made, the response is served from the cache without - * sending a request to the server. - * - * Note that even if the response is served from cache, delivery of the data is asynchronous in - * the same way that real requests are. - * - * If there are multiple GET requests for the same URL that should be cached using the same - * cache, but the cache is not populated yet, only one request to the server will be made and - * the remaining requests will be fulfilled using the response from the first request. - * - * You can change the default cache to a new object (built with - * {@link ng.$cacheFactory `$cacheFactory`}) by updating the - * {@link ng.$http#defaults `$http.defaults.cache`} property. All requests who set - * their `cache` property to `true` will now use this cache object. - * - * If you set the default cache to `false` then only requests that specify their own custom - * cache object will be 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 a technique by which - * an unauthorized site can gain your user's private data. 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}` – Absolute or relative URL of the resource that is being requested. - * - **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. - * - **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 TransformationjqLiks} - * - **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|Cache}` – If true, a default $http cache will be used to cache the - * GET request, otherwise if a cache instance built with - * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for - * caching. - * - **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', []) - .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 sampleJsonpBtn = element(by.id('samplejsonpbtn')); - 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() { -// 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(requestConfig.url)) { - throw minErr('$http')('badreq', 'Http request configuration url must be a string. Received: {0}', requestConfig.url); - } - - var config = extend({ - method: 'get', - transformRequest: defaults.transformRequest, - transformResponse: defaults.transformResponse, - paramSerializer: defaults.paramSerializer - }, requestConfig); - - config.headers = mergeHeaders(requestConfig); - config.method = uppercase(config.method); - config.paramSerializer = isString(config.paramSerializer) ? - $injector.get(config.paramSerializer) : config.paramSerializer; - - var serverRequest = function(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); - }; - - var chain = [serverRequest, undefined]; - var promise = $q.when(config); - - // apply interceptors - forEach(reversedInterceptors, function(interceptor) { - if (interceptor.request || interceptor.requestError) { - chain.unshift(interceptor.request, interceptor.requestError); - } - if (interceptor.response || interceptor.responseError) { - chain.push(interceptor.response, interceptor.responseError); - } - }); - - while (chain.length) { - var thenFn = chain.shift(); - var rejectFn = chain.shift(); - - promise = promise.then(thenFn, rejectFn); - } - - if (useLegacyPromise) { - promise.success = function(fn) { - assertArgFn(fn, 'fn'); - - promise.then(function(response) { - fn(response.data, response.status, response.headers, config); - }); - return promise; - }; - - promise.error = function(fn) { - assertArgFn(fn, 'fn'); - - promise.then(null, function(response) { - fn(response.data, response.status, response.headers, config); - }); - return promise; - }; - } else { - promise.success = $httpMinErrLegacyFn('success'); - promise.error = $httpMinErrLegacyFn('error'); - } - - return promise; - - 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); - } - - 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 unecessary 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)); - } - } - - $http.pendingRequests = []; - - /** - * @ngdoc method - * @name $http#get - * - * @description - * Shortcut method to perform `GET` request. - * - * @param {string} url Relative or absolute URL specifying the destination of the request - * @param {Object=} config Optional configuration object - * @returns {HttpPromise} Future object - */ - - /** - * @ngdoc method - * @name $http#delete - * - * @description - * Shortcut method to perform `DELETE` request. - * - * @param {string} url Relative or absolute URL specifying the destination of the request - * @param {Object=} config Optional configuration object - * @returns {HttpPromise} Future object - */ - - /** - * @ngdoc method - * @name $http#head - * - * @description - * Shortcut method to perform `HEAD` request. - * - * @param {string} url Relative or absolute URL specifying the destination of the request - * @param {Object=} config Optional configuration object - * @returns {HttpPromise} Future object - */ - - /** - * @ngdoc method - * @name $http#jsonp - * - * @description - * Shortcut method to perform `JSONP` request. - * - * @param {string} url Relative or absolute URL specifying the destination of the request. - * The name of the callback should be the string `JSON_CALLBACK`. - * @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, - url = buildUrl(config.url, config.paramSerializer(config.params)); - - $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); - } - - return promise; - - - /** - * 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; - } - }]; -} - -/** - * @ngdoc service - * @name $xhrFactory - * - * @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 $window - * @requires $document - * @requires $xhrFactory - * - * @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', '$window', '$document', '$xhrFactory', function($browser, $window, $document, $xhrFactory) { - return createHttpBackend($browser, $xhrFactory, $browser.defer, $window.angular.callbacks, $document[0]); - }]; -} - -function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) { - // TODO(vojta): fix the signature - return function(method, url, post, callback, headers, timeout, withCredentials, responseType) { - $browser.$$incOutstandingRequestCount(); - url = url || $browser.url(); - - if (lowercase(method) == 'jsonp') { - var callbackId = '_' + (callbacks.counter++).toString(36); - callbacks[callbackId] = function(data) { - callbacks[callbackId].data = data; - callbacks[callbackId].called = true; - }; - - var jsonpDone = jsonpReq(url.replace('JSON_CALLBACK', 'angular.callbacks.' + callbackId), - callbackId, function(status, text) { - completeRequest(callback, status, callbacks[callbackId].data, "", text); - callbacks[callbackId] = noop; - }); - } 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; - - 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() { - jsonpDone && jsonpDone(); - 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); - $browser.$$completeOutstandingRequest(noop); - } - }; - - function jsonpReq(url, callbackId, done) { - // 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) { - removeEventListenerFn(script, "load", callback); - removeEventListenerFn(script, "error", callback); - rawDocument.body.removeChild(script); - script = null; - var status = -1; - var text = "unknown"; - - if (event) { - if (event.type === "load" && !callbacks[callbackId].called) { - event = { type: "error" }; - } - text = event.type; - status = event.type === "error" ? 404 : 200; - } - - if (done) { - done(status, text); - } - }; - - addEventListenerFn(script, "load", callback); - addEventListenerFn(script, "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 - * - * @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); - } - - function stringify(value) { - if (value == null) { // null || undefined - return ''; - } - switch (typeof value) { - case 'string': - break; - case 'number': - value = '' + value; - break; - default: - value = toJson(value); - } - - return value; - } - - //TODO: this is the same as the constantWatchDelegate in parse.js - function constantWatchDelegate(scope, listener, objectEquality, constantInterp) { - var unwatch; - return unwatch = scope.$watch(function constantInterpolateWatch(scope) { - unwatch(); - return constantInterp(scope); - }, listener, objectEquality); - } - - /** - * @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.

- *
- *
- *
- * - * @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, 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; - }]; -} - -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. - * @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) { - intervals[promise.$$intervalId].reject('canceled'); - $window.clearInterval(promise.$$intervalId); - delete intervals[promise.$$intervalId]; - return true; - } - return false; - }; - - return interval; - }]; -} - -/** - * @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; -} - - -function parseAppUrl(relativeUrl, locationObj) { - var prefixed = (relativeUrl.charAt(0) !== '/'); - if (prefixed) { - relativeUrl = '/' + relativeUrl; - } - var match = urlResolve(relativeUrl); - 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; - } -} - - -/** - * - * @param {string} begin - * @param {string} whole - * @returns {string} returns text from whole after begin or undefined if it does not begin with - * expected string. - */ -function beginsWith(begin, whole) { - if (whole.indexOf(begin) === 0) { - return whole.substr(begin.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 an 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 = beginsWith(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 = beginsWith(appBase, url))) { - prevAppUrl = appUrl; - if (isDefined(appUrl = beginsWith(basePrefix, appUrl))) { - rewrittenUrl = appBaseNoFile + (beginsWith('/', appUrl) || appUrl); - } else { - rewrittenUrl = appBase + prevAppUrl; - } - } else if (isDefined(appUrl = beginsWith(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 = beginsWith(appBase, url) || beginsWith(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 = beginsWith(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 (url.indexOf(base) === 0) { - 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 = beginsWith(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 = { - - /** - * 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} path - */ - 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 function() { - return this[property]; - }; -} - - -function locationGetterSetter(property, preprocess) { - return 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 - * @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 - * @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}` - (default: `true`) When html5Mode is enabled, - * enables/disables url rewriting for relative links. - * - * @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)) { - 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) { - // TODO(vojta): rewrite link when opening in new tab/window (in legacy browser) - // currently we open nice url link and redirect then - - if (!html5Mode.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; - } - - 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 (isUndefined(beginsWith(appBaseNoFile, newUrl))) { - // 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 - * @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) {} - - 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'); - -// Sandboxing Angular Expressions -// ------------------------------ -// Angular expressions are generally considered safe because these expressions only have direct -// access to `$scope` and locals. However, one can obtain the ability to execute arbitrary JS code by -// obtaining a reference to native JS functions such as the Function constructor. -// -// As an example, consider the following Angular expression: -// -// {}.toString.constructor('alert("evil JS code")') -// -// This sandboxing technique is not perfect and doesn't aim to be. The goal is to prevent exploits -// against the expression language, but not to prevent exploits that were enabled by exposing -// sensitive JavaScript or browser APIs on Scope. Exposing such objects on a Scope is never a good -// practice and therefore we are not even trying to protect against interaction with an object -// explicitly exposed in this way. -// -// In general, it is not possible to access a Window object from an angular expression unless a -// window or some DOM object that has a reference to window is published onto a Scope. -// Similarly we prevent invocations of function known to be dangerous, as well as assignments to -// native objects. -// -// See https://docs.angularjs.org/guide/security - - -function ensureSafeMemberName(name, fullExpression) { - if (name === "__defineGetter__" || name === "__defineSetter__" - || name === "__lookupGetter__" || name === "__lookupSetter__" - || name === "__proto__") { - throw $parseMinErr('isecfld', - 'Attempting to access a disallowed field in Angular expressions! ' - + 'Expression: {0}', fullExpression); - } - return name; -} - -function getStringValue(name, fullExpression) { - // From the JavaScript docs: - // 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. - // - // So, to ensure that we are checking the same `name` that JavaScript would use, - // we cast it to a string, if possible. - // Doing `name + ''` can cause a repl error if the result to `toString` is not a string, - // this is, this will handle objects that misbehave. - name = name + ''; - if (!isString(name)) { - throw $parseMinErr('iseccst', - 'Cannot convert object to primitive value! ' - + 'Expression: {0}', fullExpression); - } - return name; -} - -function ensureSafeObject(obj, fullExpression) { - // nifty check if obj is Function that is fast and works across iframes and other contexts - if (obj) { - if (obj.constructor === obj) { - throw $parseMinErr('isecfn', - 'Referencing Function in Angular expressions is disallowed! Expression: {0}', - fullExpression); - } else if (// isWindow(obj) - obj.window === obj) { - throw $parseMinErr('isecwindow', - 'Referencing the Window in Angular expressions is disallowed! Expression: {0}', - fullExpression); - } else if (// isElement(obj) - obj.children && (obj.nodeName || (obj.prop && obj.attr && obj.find))) { - throw $parseMinErr('isecdom', - 'Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}', - fullExpression); - } else if (// block Object so that we can't get hold of dangerous Object.* methods - obj === Object) { - throw $parseMinErr('isecobj', - 'Referencing Object in Angular expressions is disallowed! Expression: {0}', - fullExpression); - } - } - return obj; -} - -var CALL = Function.prototype.call; -var APPLY = Function.prototype.apply; -var BIND = Function.prototype.bind; - -function ensureSafeFunction(obj, fullExpression) { - if (obj) { - if (obj.constructor === obj) { - throw $parseMinErr('isecfn', - 'Referencing Function in Angular expressions is disallowed! Expression: {0}', - fullExpression); - } else if (obj === CALL || obj === APPLY || obj === BIND) { - throw $parseMinErr('isecff', - 'Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}', - fullExpression); - } - } -} - -function ensureSafeAssignContext(obj, fullExpression) { - if (obj) { - if (obj === (0).constructor || obj === (false).constructor || obj === ''.constructor || - obj === {}.constructor || obj === [].constructor || obj === Function.constructor) { - throw $parseMinErr('isecaf', - 'Assigning to a constructor is disallowed! Expression: {0}', fullExpression); - } - } -} - -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(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.isIdent(ch)) { - 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'); - }, - - isIdent: function(ch) { - return ('a' <= ch && ch <= 'z' || - 'A' <= ch && ch <= 'Z' || - '_' === ch || 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; - while (this.index < this.text.length) { - var ch = this.text.charAt(this.index); - if (!(this.isIdent(ch) || this.isNumber(ch))) { - break; - } - this.index++; - } - 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(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(); - var token; - while ((token = this.expect('|'))) { - left = this.filter(left); - } - return left; - }, - - expression: function() { - return this.assignment(); - }, - - assignment: function() { - var result = this.ternary(); - if (this.expect('=')) { - 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.constants.hasOwnProperty(this.peek().text)) { - primary = copy(this.constants[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.expression()); - } 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(); - } else if (this.peek().identifier) { - property.key = this.identifier(); - } else { - this.throwError("invalid key", this.peek()); - } - this.consume(':'); - property.value = this.expression(); - 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; - }, - - - /* `undefined` is not a constant, it is an identifier, - * but using it as an identifier is not supported - */ - constants: { - 'true': { type: AST.Literal, value: true }, - 'false': { type: AST.Literal, value: false }, - 'null': { type: AST.Literal, value: null }, - 'undefined': {type: AST.Literal, value: undefined }, - '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; - 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: - allConstants = ast.filter ? isStateless($filter, ast.callee.name) : false; - 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 = ast.filter && isStateless($filter, ast.callee.name) ? 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; - 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, expensiveChecks) { - var self = this; - var ast = this.astBuilder.ast(expression); - this.state = { - nextId: 0, - filters: {}, - expensiveChecks: expensiveChecks, - 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;'; - - /* jshint -W054 */ - var fn = (new Function('$filter', - 'ensureSafeMemberName', - 'ensureSafeObject', - 'ensureSafeFunction', - 'getStringValue', - 'ensureSafeAssignContext', - 'ifDefined', - 'plus', - 'text', - fnString))( - this.$filter, - ensureSafeMemberName, - ensureSafeObject, - ensureSafeFunction, - getStringValue, - ensureSafeAssignContext, - ifDefined, - plusFn, - expression); - /* jshint +W054 */ - 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; - 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(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; - } - ensureSafeMemberName(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.not(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)) - ); - if (self.state.expensiveChecks || isPossiblyDangerousMemberName(ast.name)) { - self.addEnsureSafeObject(intoId); - } - 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 (create && create !== 1) { - self.addEnsureSafeAssignContext(left); - } - if (ast.computed) { - right = self.nextId(); - self.recurse(ast.property, right); - self.getStringValue(right); - self.addEnsureSafeMemberName(right); - if (create && create !== 1) { - self.if_(self.not(self.computedMember(left, right)), self.lazyAssign(self.computedMember(left, right), '{}')); - } - expression = self.ensureSafeObject(self.computedMember(left, right)); - self.assign(intoId, expression); - if (nameId) { - nameId.computed = true; - nameId.name = right; - } - } else { - ensureSafeMemberName(ast.property.name); - if (create && create !== 1) { - self.if_(self.not(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), '{}')); - } - expression = self.nonComputedMember(left, ast.property.name); - if (self.state.expensiveChecks || isPossiblyDangerousMemberName(ast.property.name)) { - expression = self.ensureSafeObject(expression); - } - 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() { - self.addEnsureSafeFunction(right); - forEach(ast.arguments, function(expr) { - self.recurse(expr, self.nextId(), undefined, function(argument) { - args.push(self.ensureSafeObject(argument)); - }); - }); - if (left.name) { - if (!self.state.expensiveChecks) { - self.addEnsureSafeObject(left.context); - } - expression = self.member(left.context, left.name, left.computed) + '(' + args.join(',') + ')'; - } else { - expression = right + '(' + args.join(',') + ')'; - } - expression = self.ensureSafeObject(expression); - self.assign(intoId, expression); - }, function() { - self.assign(intoId, 'undefined'); - }); - recursionFn(intoId); - }); - } - break; - case AST.AssignmentExpression: - right = this.nextId(); - left = {}; - if (!isAssignable(ast.left)) { - throw $parseMinErr('lval', 'Trying to assign a value to a non l-value'); - } - this.recurse(ast.left, undefined, left, function() { - self.if_(self.notNull(left.context), function() { - self.recurse(ast.right, right); - self.addEnsureSafeObject(self.member(left.context, left.name, left.computed)); - self.addEnsureSafeAssignContext(left.context); - 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, self.nextId(), undefined, function(argument) { - args.push(argument); - }); - }); - expression = '[' + args.join(',') + ']'; - this.assign(intoId, expression); - recursionFn(expression); - break; - case AST.ObjectExpression: - args = []; - forEach(ast.properties, function(property) { - self.recurse(property.value, 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(expression); - break; - case AST.ThisExpression: - this.assign(intoId, 's'); - recursionFn('s'); - break; - case AST.LocalsExpression: - this.assign(intoId, 'l'); - recursionFn('l'); - break; - case AST.NGValueParameter: - this.assign(intoId, 'v'); - recursionFn('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 + ')'; - }, - - notNull: function(expression) { - return expression + '!=null'; - }, - - nonComputedMember: function(left, right) { - return left + '.' + right; - }, - - computedMember: function(left, right) { - return left + '[' + right + ']'; - }, - - member: function(left, right, computed) { - if (computed) return this.computedMember(left, right); - return this.nonComputedMember(left, right); - }, - - addEnsureSafeObject: function(item) { - this.current().body.push(this.ensureSafeObject(item), ';'); - }, - - addEnsureSafeMemberName: function(item) { - this.current().body.push(this.ensureSafeMemberName(item), ';'); - }, - - addEnsureSafeFunction: function(item) { - this.current().body.push(this.ensureSafeFunction(item), ';'); - }, - - addEnsureSafeAssignContext: function(item) { - this.current().body.push(this.ensureSafeAssignContext(item), ';'); - }, - - ensureSafeObject: function(item) { - return 'ensureSafeObject(' + item + ',text)'; - }, - - ensureSafeMemberName: function(item) { - return 'ensureSafeMemberName(' + item + ',text)'; - }, - - ensureSafeFunction: function(item) { - return 'ensureSafeFunction(' + item + ',text)'; - }, - - getStringValue: function(item) { - this.assign(item, 'getStringValue(' + item + ',text)'); - }, - - ensureSafeAssignContext: function(item) { - return 'ensureSafeAssignContext(' + item + ',text)'; - }, - - 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, expensiveChecks) { - var self = this; - var ast = this.astBuilder.ast(expression); - this.expression = expression; - this.expensiveChecks = expensiveChecks; - 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 ? function() {} : - 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, expression; - 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: - ensureSafeMemberName(ast.name, self.expression); - return self.identifier(ast.name, - self.expensiveChecks || isPossiblyDangerousMemberName(ast.name), - context, create, self.expression); - case AST.MemberExpression: - left = this.recurse(ast.object, false, !!create); - if (!ast.computed) { - ensureSafeMemberName(ast.property.name, self.expression); - right = ast.property.name; - } - if (ast.computed) right = this.recurse(ast.property); - return ast.computed ? - this.computedMember(left, right, context, create, self.expression) : - this.nonComputedMember(left, right, self.expensiveChecks, context, create, self.expression); - 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) { - ensureSafeObject(rhs.context, self.expression); - ensureSafeFunction(rhs.value, self.expression); - var values = []; - for (var i = 0; i < args.length; ++i) { - values.push(ensureSafeObject(args[i](scope, locals, assign, inputs), self.expression)); - } - value = ensureSafeObject(rhs.value.apply(rhs.context, values), self.expression); - } - 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); - ensureSafeObject(lhs.value, self.expression); - ensureSafeAssignContext(lhs.context); - 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) { - args.push({key: property.key.type === AST.Identifier ? - property.key.name : - ('' + property.key.value), - value: self.recurse(property.value) - }); - }); - return function(scope, locals, assign, inputs) { - var value = {}; - for (var i = 0; i < args.length; ++i) { - 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, inputs) { - 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) { - 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; - }; - }, - '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, expensiveChecks, context, create, expression) { - return function(scope, locals, assign, inputs) { - var base = locals && (name in locals) ? locals : scope; - if (create && create !== 1 && base && !(base[name])) { - base[name] = {}; - } - var value = base ? base[name] : undefined; - if (expensiveChecks) { - ensureSafeObject(value, expression); - } - if (context) { - return {context: base, name: name, value: value}; - } else { - return value; - } - }; - }, - computedMember: function(left, right, context, create, expression) { - 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); - ensureSafeMemberName(rhs, expression); - if (create && create !== 1) { - ensureSafeAssignContext(lhs); - if (lhs && !(lhs[rhs])) { - lhs[rhs] = {}; - } - } - value = lhs[rhs]; - ensureSafeObject(value, expression); - } - if (context) { - return {context: lhs, name: rhs, value: value}; - } else { - return value; - } - }; - }, - nonComputedMember: function(left, right, expensiveChecks, context, create, expression) { - return function(scope, locals, assign, inputs) { - var lhs = left(scope, locals, assign, inputs); - if (create && create !== 1) { - ensureSafeAssignContext(lhs); - if (lhs && !(lhs[right])) { - lhs[right] = {}; - } - } - var value = lhs != null ? lhs[right] : undefined; - if (expensiveChecks || isPossiblyDangerousMemberName(right)) { - ensureSafeObject(value, expression); - } - 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(lexer, $filter, options) { - this.lexer = lexer; - this.$filter = $filter; - this.options = options; - this.ast = new AST(this.lexer); - 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, this.options.expensiveChecks); - } -}; - -var getterFnCacheDefault = createMap(); -var getterFnCacheExpensive = createMap(); - -function isPossiblyDangerousMemberName(name) { - return name == 'constructor'; -} - -var objectValueOf = Object.prototype.valueOf; - -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 - * - * @description - * `$parseProvider` can be used for configuring the default behavior of the {@link ng.$parse $parse} - * service. - */ -function $ParseProvider() { - var cacheDefault = createMap(); - var cacheExpensive = createMap(); - - this.$get = ['$filter', function($filter) { - var noUnsafeEval = csp().noUnsafeEval; - var $parseOptions = { - csp: noUnsafeEval, - expensiveChecks: false - }, - $parseOptionsExpensive = { - csp: noUnsafeEval, - expensiveChecks: true - }; - - return function $parse(exp, interceptorFn, expensiveChecks) { - var parsedExpression, oneTime, cacheKey; - - switch (typeof exp) { - case 'string': - exp = exp.trim(); - cacheKey = exp; - - var cache = (expensiveChecks ? cacheExpensive : cacheDefault); - parsedExpression = cache[cacheKey]; - - if (!parsedExpression) { - if (exp.charAt(0) === ':' && exp.charAt(1) === ':') { - oneTime = true; - exp = exp.substring(2); - } - var parseOptions = expensiveChecks ? $parseOptionsExpensive : $parseOptions; - 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 - 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) { - var unwatch, lastValue; - return unwatch = scope.$watch(function oneTimeWatch(scope) { - return parsedExpression(scope); - }, function oneTimeListener(value, old, scope) { - lastValue = value; - if (isFunction(listener)) { - listener.apply(this, arguments); - } - if (isDefined(value)) { - scope.$$postDigest(function() { - if (isDefined(lastValue)) { - unwatch(); - } - }); - } - }, objectEquality); - } - - function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) { - var unwatch, lastValue; - return unwatch = scope.$watch(function oneTimeWatch(scope) { - return parsedExpression(scope); - }, function oneTimeListener(value, old, scope) { - lastValue = value; - if (isFunction(listener)) { - listener.call(this, value, old, scope); - } - if (isAllDefined(value)) { - scope.$$postDigest(function() { - if (isAllDefined(lastValue)) unwatch(); - }); - } - }, objectEquality); - - 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; - return unwatch = scope.$watch(function constantWatch(scope) { - unwatch(); - return parsedExpression(scope); - }, listener, objectEquality); - } - - 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 - if (parsedExpression.$$watchDelegate && - parsedExpression.$$watchDelegate !== inputsWatchDelegate) { - fn.$$watchDelegate = parsedExpression.$$watchDelegate; - } 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; - useInputs = !parsedExpression.inputs; - 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 an 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 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 Harmony, - * 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 Harmony 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 behaviour, 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. - * - * - `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. - */ -function $QProvider() { - - this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) { - return qFactory(function(callback) { - $rootScope.$evalAsync(callback); - }, $exceptionHandler); - }]; -} - -function $$QProvider() { - this.$get = ['$browser', '$exceptionHandler', function($browser, $exceptionHandler) { - return qFactory(function(callback) { - $browser.defer(callback); - }, $exceptionHandler); - }]; -} - -/** - * 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. - * @returns {object} Promise manager. - */ -function qFactory(nextTick, exceptionHandler) { - var $qMinErr = minErr('$q', TypeError); - - /** - * @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. - */ - var defer = function() { - var d = new Deferred(); - //Necessary to support unbound execution :/ - d.resolve = simpleBind(d, d.resolve); - d.reject = simpleBind(d, d.reject); - d.notify = simpleBind(d, d.notify); - return d; - }; - - 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 Deferred(); - - this.$$state.pending = this.$$state.pending || []; - this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]); - if (this.$$state.status > 0) scheduleProcessQueue(this.$$state); - - return result.promise; - }, - - "catch": function(callback) { - return this.then(null, callback); - }, - - "finally": function(callback, progressBack) { - return this.then(function(value) { - return handleCallback(value, true, callback); - }, function(error) { - return handleCallback(error, false, callback); - }, progressBack); - } - }); - - //Faster, more basic than angular.bind http://jsperf.com/angular-bind-vs-custom-vs-native - function simpleBind(context, fn) { - return function(value) { - fn.call(context, value); - }; - } - - function processQueue(state) { - var fn, deferred, pending; - - pending = state.pending; - state.processScheduled = false; - state.pending = undefined; - for (var i = 0, ii = pending.length; i < ii; ++i) { - deferred = pending[i][0]; - fn = pending[i][state.status]; - try { - if (isFunction(fn)) { - deferred.resolve(fn(state.value)); - } else if (state.status === 1) { - deferred.resolve(state.value); - } else { - deferred.reject(state.value); - } - } catch (e) { - deferred.reject(e); - exceptionHandler(e); - } - } - } - - function scheduleProcessQueue(state) { - if (state.processScheduled || !state.pending) return; - state.processScheduled = true; - nextTick(function() { processQueue(state); }); - } - - function Deferred() { - this.promise = new Promise(); - } - - extend(Deferred.prototype, { - resolve: function(val) { - if (this.promise.$$state.status) return; - if (val === this.promise) { - this.$$reject($qMinErr( - 'qcycle', - "Expected promise to be resolved with value other than itself '{0}'", - val)); - } else { - this.$$resolve(val); - } - - }, - - $$resolve: function(val) { - var then; - var that = this; - var done = false; - try { - if ((isObject(val) || isFunction(val))) then = val && val.then; - if (isFunction(then)) { - this.promise.$$state.status = -1; - then.call(val, resolvePromise, rejectPromise, simpleBind(this, this.notify)); - } else { - this.promise.$$state.value = val; - this.promise.$$state.status = 1; - scheduleProcessQueue(this.promise.$$state); - } - } catch (e) { - rejectPromise(e); - exceptionHandler(e); - } - - function resolvePromise(val) { - if (done) return; - done = true; - that.$$resolve(val); - } - function rejectPromise(val) { - if (done) return; - done = true; - that.$$reject(val); - } - }, - - reject: function(reason) { - if (this.promise.$$state.status) return; - this.$$reject(reason); - }, - - $$reject: function(reason) { - this.promise.$$state.value = reason; - this.promise.$$state.status = 2; - scheduleProcessQueue(this.promise.$$state); - }, - - notify: function(progress) { - var callbacks = this.promise.$$state.pending; - - if ((this.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 { - result.notify(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`. - */ - var reject = function(reason) { - var result = new Deferred(); - result.reject(reason); - return result.promise; - }; - - var makePromise = function makePromise(value, resolved) { - var result = new Deferred(); - if (resolved) { - result.resolve(value); - } else { - result.reject(value); - } - return result.promise; - }; - - var handleCallback = function handleCallback(value, isResolved, callback) { - var callbackOutput = null; - try { - if (isFunction(callback)) callbackOutput = callback(); - } catch (e) { - return makePromise(e, false); - } - if (isPromiseLike(callbackOutput)) { - return callbackOutput.then(function() { - return makePromise(value, isResolved); - }, function(error) { - return makePromise(error, false); - }); - } else { - return makePromise(value, isResolved); - } - }; - - /** - * @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 - */ - - - var when = function(value, callback, errback, progressBack) { - var result = new Deferred(); - result.resolve(value); - return result.promise.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 deferred = new Deferred(), - counter = 0, - results = isArray(promises) ? [] : {}; - - forEach(promises, function(promise, key) { - counter++; - when(promise).then(function(value) { - if (results.hasOwnProperty(key)) return; - results[key] = value; - if (!(--counter)) deferred.resolve(results); - }, function(reason) { - if (results.hasOwnProperty(key)) return; - deferred.reject(reason); - }); - }); - - if (counter === 0) { - deferred.resolve(results); - } - - return deferred.promise; - } - - var $Q = function Q(resolver) { - if (!isFunction(resolver)) { - throw $qMinErr('norslvr', "Expected resolverFn, got '{0}'", resolver); - } - - if (!(this instanceof Q)) { - // More useful when $Q is the Promise itself. - return new Q(resolver); - } - - var deferred = new Deferred(); - - function resolveFn(value) { - deferred.resolve(value); - } - - function rejectFn(reason) { - deferred.reject(reason); - } - - resolver(resolveFn, rejectFn); - - return deferred.promise; - }; - - $Q.defer = defer; - $Q.reject = reject; - $Q.when = when; - $Q.resolve = resolve; - $Q.all = all; - - return $Q; -} - -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 - * @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) { - - 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 - $scope.$$childHead && cleanUpScope($scope.$$childHead); - $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. - * - 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 = []; - } - // we use unshift since we use a while loop in $digest for speed. - // the while loop reads in reverse order. - array.unshift(watcher); - incrementWatchersCount(this, 1); - - return function deregisterWatch() { - if (arrayRemove(array, watcher) >= 0) { - incrementWatchersCount(scope, -1); - } - 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 standard $watch operation and are examined on every - * call to $digest() to see if any items changes. - * - 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]; - - 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) { - 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, - watchers, - length, - dirty, ttl = TTL, - next, current, target = this, - watchLog = [], - logIdx, logMsg, 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; - - while (asyncQueue.length) { - try { - asyncTask = asyncQueue.shift(); - asyncTask.scope.$eval(asyncTask.expression, asyncTask.locals); - } catch (e) { - $exceptionHandler(e); - } - lastDirtyWatch = null; - } - - traverseScopesLoop: - do { // "traverse the scopes" loop - if ((watchers = current.$$watchers)) { - // process our watches - length = watchers.length; - while (length--) { - try { - watch = watchers[length]; - // 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) { - if ((value = watch.get(current)) !== (last = watch.last) && - !(watch.eq - ? equals(value, last) - : (typeof value === 'number' && typeof last === 'number' - && isNaN(value) && isNaN(last)))) { - dirty = true; - lastDirtyWatch = watch; - watch.last = watch.eq ? copy(value, null) : value; - watch.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(); - - while (postDigestQueue.length) { - try { - postDigestQueue.shift()(); - } catch (e) { - $exceptionHandler(e); - } - } - }, - - - /** - * @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: 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); - 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; - expr && applyAsyncQueue.push($applyAsyncExpression); - 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 = []; - - 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); - }); - } - } - }]; -} - -/** - * @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? * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -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. - -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('\\*\\*', '.*'). - replace('\\*', '[^:/.?&;]*'); - 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 - * @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 - * @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)}. - */ - -/* jshint maxlen: false*/ - -/** - * @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 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($http, $templateCache, $sce) { - * var self = this; - * $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) { - * self.userComments = userComments; - * }); - * 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().getInnerHtml()) - * .toBe('Is anyone reading this?'); - * }); - * - * it('should NOT sanitize explicitly trusted values', function() { - * expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).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); - * }); - * ``` - * - */ -/* jshint maxlen: 100 */ - -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) { - // 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[camelCase("parse_as_" + lName)] = function(expr) { - return parse(enumValue, expr); - }; - sce[camelCase("get_trusted_" + lName)] = function(value) { - return getTrusted(enumValue, value); - }; - sce[camelCase("trust_as_" + lName)] = function(value) { - return trustAs(enumValue, value); - }; - }); - - return sce; - }]; -} - -/** - * !!! This is an undocumented "private" service !!! - * - * @name $sniffer - * @requires $window - * @requires $document - * - * @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 = {}, - android = - toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), - boxee = /Boxee/i.test(($window.navigator || {}).userAgent), - document = $document[0] || {}, - vendorPrefix, - vendorRegex = /^(Moz|webkit|ms)(?=[A-Z])/, - bodyStyle = document.body && document.body.style, - transitions = false, - animations = false, - match; - - if (bodyStyle) { - for (var prop in bodyStyle) { - if (match = vendorRegex.exec(prop)) { - vendorPrefix = match[0]; - vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1); - break; - } - } - - if (!vendorPrefix) { - vendorPrefix = ('WebkitOpacity' in bodyStyle) && 'webkit'; - } - - transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle)); - animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle)); - - if (android && (!transitions || !animations)) { - transitions = isString(bodyStyle.webkitTransition); - animations = isString(bodyStyle.webkitAnimation); - } - } - - - 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 - // jshint -W018 - history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee), - // jshint +W018 - hasEvent: function(event) { - // 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 <= 11) return false; - - if (isUndefined(eventSupport[event])) { - var divElm = document.createElement('div'); - eventSupport[event] = 'on' + event in divElm; - } - - return eventSupport[event]; - }, - csp: csp(), - vendorPrefix: vendorPrefix, - transitions: transitions, - animations: animations, - android: android - }; - }]; -} - -var $compileMinErr = minErr('$compile'); - -/** - * @ngdoc provider - * @name $templateRequestProvider - * @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 = ['$templateCache', '$http', '$q', '$sce', function($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) || !$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) { - throw $compileMinErr('tpload', 'Failed to load template: {0} (HTTP status: {1} {2})', - tpl, resp.status, resp.statusText); - } - return $q.reject(resp); - } - } - - handleRequestFn.totalPendingRequests = 0; - - return handleRequestFn; - }]; -} - -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; - }]; -} - -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) { - 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 = 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; - - 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 - * - * @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 safeDecodeURIComponent(str) { - try { - return decodeURIComponent(str); - } catch (e) { - return str; - } - } - - return function() { - var cookieArray, cookie, i, index, name; - var currentCookieString = rawDocument.cookie || ''; - - 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']; - -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. - * - * The general syntax in templates is as follows: - * - * {{ 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']; -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 `$` can be used (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 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|undefined} 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|undefined`: A short hand for a function which will look for a substring match in 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). - * - * @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) { - if (!isArrayLike(array)) { - if (array == null) { - return array; - } else { - throw minErr('filter')('notarray', 'Expected array but received: {0}', array); - } - } - - 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; - //jshint -W086 - case 'object': - //jshint +W086 - predicateFn = createPredicateFn(expression, comparator, matchAgainstAnyProp); - break; - default: - return array; - } - - return Array.prototype.filter.call(array, predicateFn); - }; -} - -// Helper functions for `filterFilter` -function createPredicateFn(expression, comparator, matchAgainstAnyProp) { - var shouldMatchPrimitives = isObject(expression) && ('$' 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.$, comparator, false); - } - return deepCompare(item, expression, comparator, matchAgainstAnyProp); - }; - - return predicateFn; -} - -function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatchWholeObject) { - var actualType = getTypeForFilter(actual); - var expectedType = getTypeForFilter(expected); - - if ((expectedType === 'string') && (expected.charAt(0) === '!')) { - return !deepCompare(actual, expected.substring(1), comparator, 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, matchAgainstAnyProp); - }); - } - - switch (actualType) { - case 'object': - var key; - if (matchAgainstAnyProp) { - for (key in actual) { - if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator, true)) { - return true; - } - } - return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, false); - } else if (expectedType === 'object') { - for (key in expected) { - var expectedVal = expected[key]; - if (isFunction(expectedVal) || isUndefined(expectedVal)) { - continue; - } - - var matchAnyProperty = key === '$'; - var actualVal = matchAnyProperty ? actual : actual[key]; - if (!deepCompare(actualVal, expectedVal, comparator, matchAnyProperty, matchAnyProperty)) { - return false; - } - } - return true; - } else { - return comparator(actual, expected); - } - break; - 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/-Infinity) the Infinity symbol '∞' is returned. - * 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 and places a “,” 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++); - - 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) { - digits.splice(roundAt); - } else { - // We rounded to zero so reset the parsedNumber - parsedNumber.i = 1; - digits.length = roundAt = fractionSize + 1; - for (var i=0; i < roundAt; i++) digits[i] = 0; - } - - if (digit >= 5) digits[roundAt - 1]++; - - // Pad out with zeros to get the required fraction length - for (; fractionLen < 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); - } 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).join('')); - } - while (digits.length > pattern.gSize) { - groups.unshift(digits.splice(-pattern.gSize).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) { - var neg = ''; - if (num < 0) { - neg = '-'; - num = -num; - } - 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) { - 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); - }; -} - -function dateStrGetter(name, shortForm) { - return function(date, formats) { - var value = date['get' + name](); - var get = uppercase(shortForm ? ('SHORT' + name) : 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), - yy: dateGetter('FullYear', 2, 0, true), - y: dateGetter('FullYear', 1), - MMMM: dateStrGetter('Month'), - MMM: dateStrGetter('Month', true), - MM: dateGetter('Month', 2, 1), - M: dateGetter('Month', 1, 1), - 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 = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|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) - * * `'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, date.getTimezoneOffset()); - date = convertTimezoneToLocal(date, timezone, true); - } - forEach(parts, function(value) { - fn = DATE_FORMATS[value]; - text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset) - : 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 "name": ?"value"\n}/); - expect(element(by.id('custom-spacing')).getText()).toMatch(/\{\n "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`. If a number is used as input, it is - * converted to a string. - * - * @param {Array|string|number} input Source array, 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 input array - * 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 (isNaN(limit)) return input; - - if (isNumber(input)) input = input.toString(); - if (!isArray(input) && !isString(input)) return input; - - begin = (!begin || isNaN(begin)) ? 0 : toInt(begin); - begin = (begin < 0) ? Math.max(0, input.length + begin) : begin; - - if (limit >= 0) { - return input.slice(begin, begin + limit); - } else { - if (begin === 0) { - return input.slice(limit, input.length); - } else { - return input.slice(Math.max(0, begin + limit), begin); - } - } - }; -} - -/** - * @ngdoc filter - * @name orderBy - * @kind function - * - * @description - * Orders a specified `array` by the `expression` predicate. It is ordered alphabetically - * for strings and numerically for numbers. Note: if you notice numbers are not being sorted - * as expected, make sure they are actually being saved as numbers and not strings. - * Array-like values (e.g. NodeLists, jQuery objects, TypedArrays, Strings, etc) are also supported. - * - * @param {Array} array The array (or array-like object) to sort. - * @param {function(*)|string|Array.<(function(*)|string)>=} expression A predicate to be - * used by the comparator to determine the order of elements. - * - * Can be one of: - * - * - `function`: Getter function. The result of this function will be sorted using the - * `<`, `===`, `>` operator. - * - `string`: An Angular expression. The result of this expression is used to compare elements - * (for example `name` to sort by a property called `name` or `name.substr(0, 3)` to sort by - * 3 first characters of a property called `name`). The result of a constant expression - * is interpreted as a property name to be used in comparisons (for example `"special name"` - * to sort object by the value of their `special name` property). An expression can be - * optionally prefixed with `+` or `-` to control ascending or descending sort order - * (for example, `+name` or `-name`). If no property is provided, (e.g. `'+'`) then the array - * element itself is used to compare where sorting. - * - `Array`: An array of function or string predicates. The first predicate in the array - * is used for sorting, but when two items are equivalent, the next predicate is used. - * - * If the predicate is missing or empty then it defaults to `'+'`. - * - * @param {boolean=} reverse Reverse the order of the array. - * @returns {Array} Sorted copy of the source array. - * - * - * @example - * The example below demonstrates a simple ngRepeat, where the data is sorted - * by age in descending order (predicate is set to `'-age'`). - * `reverse` is not set, which means it defaults to `false`. - - -
- - - - - - - - - - - -
NamePhone NumberAge
{{friend.name}}{{friend.phone}}{{friend.age}}
-
-
- - angular.module('orderByExample', []) - .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}]; - }]); - -
- * - * The predicate and reverse parameters can be controlled dynamically through scope properties, - * as shown in the next example. - * @example - - -
-
Sorting predicate = {{predicate}}; reverse = {{reverse}}
-
- - - - - - - - - - - - -
- - - - - - - - -
{{friend.name}}{{friend.phone}}{{friend.age}}
-
-
- - angular.module('orderByExample', []) - .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}]; - $scope.predicate = 'age'; - $scope.reverse = true; - $scope.order = function(predicate) { - $scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false; - $scope.predicate = predicate; - }; - }]); - - - .sortorder:after { - content: '\25b2'; - } - .sortorder.reverse:after { - content: '\25bc'; - } - -
- * - * It's also possible to call the orderBy filter manually, by injecting `$filter`, retrieving the - * filter routine with `$filter('orderBy')`, and calling the returned filter routine with the - * desired parameters. - * - * Example: - * - * @example - - -
-
Sorting predicate = {{predicate}}; reverse = {{reverse}}
- - - - - - - - - - - -
- - - - - - - - -
{{friend.name}}{{friend.phone}}{{friend.age}}
-
-
- - - angular.module('orderByExample', []) - .controller('ExampleController', ['$scope', '$filter', function($scope, $filter) { - var orderBy = $filter('orderBy'); - $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 } - ]; - $scope.order = function(predicate) { - $scope.predicate = predicate; - $scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false; - $scope.friends = orderBy($scope.friends, predicate, $scope.reverse); - }; - $scope.order('age', true); - }]); - - - - .sortorder:after { - content: '\25b2'; - } - .sortorder.reverse:after { - content: '\25bc'; - } - -
- */ -orderByFilter.$inject = ['$parse']; -function orderByFilter($parse) { - return function(array, sortPredicate, reverseOrder) { - - 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, reverseOrder); - // Add a predicate at the end that evaluates to the element index. This makes the - // sort stable as it works as a tie-breaker when all the input predicates cannot - // distinguish between two elements. - predicates.push({ get: function() { return {}; }, descending: reverseOrder ? -1 : 1}); - - // 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) { - return { - value: value, - predicateValues: predicates.map(function(predicate) { - return getPredicateValue(predicate.get(value), index); - }) - }; - } - - function doComparison(v1, v2) { - var result = 0; - for (var index=0, length = predicates.length; index < length; ++index) { - result = compare(v1.predicateValues[index], v2.predicateValues[index]) * predicates[index].descending; - if (result) break; - } - return result; - } - }; - - function processPredicates(sortPredicate, reverseOrder) { - reverseOrder = reverseOrder ? -1 : 1; - return sortPredicate.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 * reverseOrder }; - }); - } - - function isPrimitive(value) { - switch (typeof value) { - case 'number': /* falls through */ - case 'boolean': /* falls through */ - case 'string': - return true; - default: - return false; - } - } - - function objectValue(value, index) { - // If `valueOf` is a valid function use that - if (typeof value.valueOf === 'function') { - 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; - } - // We have a basic object so we use the position of the object in the collection - return index; - } - - function getPredicateValue(value, index) { - var type = typeof value; - if (value === null) { - type = 'string'; - value = 'null'; - } else if (type === 'string') { - value = value.toLowerCase(); - } else if (type === 'object') { - value = objectValue(value, index); - } - return { value: value, type: type }; - } - - function compare(v1, v2) { - var result = 0; - if (v1.type === v2.type) { - if (v1.value !== v2.value) { - result = v1.value < v2.value ? -1 : 1; - } - } else { - result = v1.type < v2.type ? -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. - * - * This change permits the easy creation of action links with the `ngClick` directive - * without changing the location or causing page reloads, e.g.: - * `Add Item` - */ -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. The following example would make the button enabled on Chrome/Firefox - * but not on older IEs: - * - * ```html - * - *
- * - *
- * ``` - * - * This is because the HTML specification does not require browsers to preserve the values of - * boolean attributes such as `disabled` (Their presence means true and their absence means false.) - * If we put an Angular interpolation expression into such an attribute then the - * binding information would be lost when the browser removes the attribute. - * - * @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. - * - * ### Why do we need `ngChecked`? - * - * The HTML specification does not require browsers to preserve the values of boolean attributes - * such as checked. (Their presence means true and their absence means false.) - * If we put an Angular interpolation expression into such an attribute then the - * binding information would be lost when the browser removes the attribute. - * The `ngChecked` directive solves this problem for the `checked` attribute. - * This complementary directive is not removed by the browser and so provides - * a permanent reliable place to store the binding information. - * @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 - * The HTML specification does not require browsers to preserve the values of boolean attributes - * such as readonly. (Their presence means true and their absence means false.) - * If we put an Angular interpolation expression into such an attribute then the - * binding information would be lost when the browser removes the attribute. - * The `ngReadonly` directive solves this problem for the `readonly` attribute. - * This complementary directive is not removed by the browser and so provides - * a permanent reliable place to store the binding information. - * @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 - * The HTML specification does not require browsers to preserve the values of boolean attributes - * such as selected. (Their presence means true and their absence means false.) - * If we put an Angular interpolation expression into such an attribute then the - * binding information would be lost when the browser removes the attribute. - * The `ngSelected` directive solves this problem for the `selected` attribute. - * This complementary directive is not removed by the browser and so provides - * a permanent reliable place to store the binding information. - * - * @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 - * The HTML specification does not require browsers to preserve the values of boolean attributes - * such as open. (Their presence means true and their absence means false.) - * If we put an Angular interpolation expression into such an attribute then the - * binding information would be lost when the browser removes the attribute. - * The `ngOpen` directive solves this problem for the `open` attribute. - * This complementary directive is not removed by the browser and so provides - * a permanent reliable place to store the binding information. - * @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); - - // 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, -SUBMITTED_CLASS, addSetValidityMethod: true - */ -var nullFormCtrl = { - $addControl: noop, - $$renameControl: nullFormRenameControl, - $removeControl: noop, - $setValidity: noop, - $setDirty: noop, - $setPristine: noop, - $setSubmitted: noop -}, -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) { - var form = this, - controls = []; - - // init state - form.$error = {}; - form.$$success = {}; - form.$pending = undefined; - form.$name = $interpolate(attrs.name || attrs.ngForm || '')($scope); - form.$dirty = false; - form.$pristine = true; - form.$valid = true; - form.$invalid = false; - form.$submitted = false; - form.$$parentForm = nullFormCtrl; - - /** - * @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. - */ - form.$rollbackViewValue = function() { - forEach(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. - */ - form.$commitViewValue = function() { - forEach(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 responsiblity 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. - */ - 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'); - controls.push(control); - - if (control.$name) { - form[control.$name] = control; - } - - control.$$parentForm = form; - }; - - // Private API: rename a form control - form.$$renameControl = function(control, newName) { - var oldName = control.$name; - - if (form[oldName] === control) { - delete form[oldName]; - } - form[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`. - */ - form.$removeControl = function(control) { - if (control.$name && form[control.$name] === control) { - delete form[control.$name]; - } - forEach(form.$pending, function(value, name) { - form.$setValidity(name, null, control); - }); - forEach(form.$error, function(value, name) { - form.$setValidity(name, null, control); - }); - forEach(form.$$success, function(value, name) { - form.$setValidity(name, null, control); - }); - - arrayRemove(controls, control); - control.$$parentForm = nullFormCtrl; - }; - - - /** - * @ngdoc method - * @name form.FormController#$setValidity - * - * @description - * Sets the validity of a form control. - * - * This method will also propagate to parent forms. - */ - addSetValidityMethod({ - ctrl: this, - $element: element, - 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]; - } - }, - $animate: $animate - }); - - /** - * @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. - */ - form.$setDirty = function() { - $animate.removeClass(element, PRISTINE_CLASS); - $animate.addClass(element, DIRTY_CLASS); - form.$dirty = true; - form.$pristine = false; - form.$$parentForm.$setDirty(); - }; - - /** - * @ngdoc method - * @name form.FormController#$setPristine - * - * @description - * Sets the form to its pristine state. - * - * This method can be called to remove the 'ng-dirty' class and set the form to its pristine - * state (ng-pristine class). 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. - */ - form.$setPristine = function() { - $animate.setClass(element, PRISTINE_CLASS, DIRTY_CLASS + ' ' + SUBMITTED_CLASS); - form.$dirty = false; - form.$pristine = true; - form.$submitted = false; - forEach(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. - */ - form.$setUntouched = function() { - forEach(controls, function(control) { - control.$setUntouched(); - }); - }; - - /** - * @ngdoc method - * @name form.FormController#$setSubmitted - * - * @description - * Sets the form to its submitted state. - */ - form.$setSubmitted = function() { - $animate.addClass(element, SUBMITTED_CLASS); - form.$submitted = true; - form.$$parentForm.$setSubmitted(); - }; -} - -/** - * @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 - * `` but can be nested. This allows you to have nested forms, which is very useful when - * using Angular validation directives in forms that are dynamically generated using the - * {@link ng.directive:ngRepeat `ngRepeat`} directive. Since you cannot dynamically generate the `name` - * attribute of input elements using interpolation, you have to wrap each set of repeated inputs in an - * `ngForm` directive and nest these in an outer `form` element. - * - * - * # 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(); - }; - - addEventListenerFn(formElement[0], '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() { - removeEventListenerFn(formElement[0], '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); - -/* global VALID_CLASS: false, - INVALID_CLASS: false, - PRISTINE_CLASS: false, - DIRTY_CLASS: false, - UNTOUCHED_CLASS: false, - TOUCHED_CLASS: false, - ngModelMinErr: false, -*/ - -// Regex code is obtained from SO: 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) -var URL_REGEXP = /^[A-Za-z][A-Za-z\d.+-]*:\/*(?:\w+(?::\w+)?@)?[^\s/]+(?::\d+)?(?:\/[\w#!:.?+=&%@\-/[\]$'()*,;~]*)?$/; -var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i; -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 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')); - var input = element(by.model('example.value')); - - // 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')); - var input = element(by.model('example.value')); - - // 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')); - var input = element(by.model('example.value')); - - // 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')); - var input = element(by.model('example.value')); - - // 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')); - var input = element(by.model('example.value')); - - // 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`. - * @param {string=} max Sets the `max` validation error key if the value entered is greater than `max`. - * @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 color = element(by.binding('color.name')); - - expect(color.getText()).toContain('blue'); - - element.all(by.model('color.name')).get(0).click(); - - expect(color.getText()).toContain('red'); - }); - -
- */ - 'radio': radioInputType, - - - /** - * @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 inputing 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(data) { - composing = true; - }); - - element.on('compositionend', function() { - composing = false; - listener(); - }); - } - - 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 timeout; - - var deferListener = function(ev, input, origValue) { - if (!timeout) { - timeout = $browser.defer(function() { - timeout = null; - if (!input || input.value !== origValue) { - listener(ev); - } - }); - } - }; - - element.on('keydown', 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); - - 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 && ctrl.$options.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 numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { - badInputChecker(scope, element, attr, ctrl); - baseInputType(scope, element, attr, ctrl, $sniffer, $browser); - - 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; - }); - - if (isDefined(attr.min) || attr.ngMin) { - var minVal; - ctrl.$validators.min = function(value) { - return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal; - }; - - attr.$observe('min', function(val) { - if (isDefined(val) && !isNumber(val)) { - val = parseFloat(val, 10); - } - minVal = isNumber(val) && !isNaN(val) ? val : undefined; - // TODO(matsko): implement validateLater to reduce number of validations - ctrl.$validate(); - }); - } - - if (isDefined(attr.max) || attr.ngMax) { - var maxVal; - ctrl.$validators.max = function(value) { - return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal; - }; - - attr.$observe('max', function(val) { - if (isDefined(val) && !isNumber(val)) { - val = parseFloat(val, 10); - } - maxVal = isNumber(val) && !isNaN(val) ? val : undefined; - // 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) { - // make the name unique, if not defined - if (isUndefined(attr.name)) { - element.attr('name', nextUid()); - } - - var listener = function(ev) { - if (element[0].checked) { - ctrl.$setViewValue(attr.value, ev && ev.type); - } - }; - - element.on('click', listener); - - ctrl.$render = function() { - var value = attr.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. - */ - - -/** - * @ngdoc directive - * @name input - * @restrict E - * - * @description - * HTML input element control. When used together with {@link ngModel `ngModel`}, it provides data-binding, - * input state control, and validation. - * Input control follows HTML5 input types and polyfills the HTML5 validation behavior for older browsers. - * - *
- * **Note:** Not every feature offered is available for all input types. - * Specifically, data binding and event handling via `ng-model` is unsupported for `input[file]`. - *
- * - * @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 {boolean=} ngRequired Sets `required` attribute if set to true - * @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} - * value 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! -
- -
- - Too short! - - Too long! -
-
-
- user = {{user}}
- myForm.userName.$valid = {{myForm.userName.$valid}}
- myForm.userName.$error = {{myForm.userName.$error}}
- myForm.lastName.$valid = {{myForm.lastName.$valid}}
- myForm.lastName.$error = {{myForm.lastName.$error}}
- myForm.$valid = {{myForm.$valid}}
- myForm.$error.required = {{!!myForm.$error.required}}
- myForm.$error.minlength = {{!!myForm.$error.minlength}}
- myForm.$error.maxlength = {{!!myForm.$error.maxlength}}
-
-
- - var user = element(by.exactBinding('user')); - var userNameValid = element(by.binding('myForm.userName.$valid')); - var lastNameValid = element(by.binding('myForm.lastName.$valid')); - var lastNameError = element(by.binding('myForm.lastName.$error')); - var formValid = element(by.binding('myForm.$valid')); - var userNameInput = element(by.model('user.name')); - var userLastInput = element(by.model('user.last')); - - it('should initialize to model', function() { - expect(user.getText()).toContain('{"name":"guest","last":"visitor"}'); - expect(userNameValid.getText()).toContain('true'); - expect(formValid.getText()).toContain('true'); - }); - - it('should be invalid if empty when required', function() { - userNameInput.clear(); - userNameInput.sendKeys(''); - - expect(user.getText()).toContain('{"last":"visitor"}'); - expect(userNameValid.getText()).toContain('false'); - expect(formValid.getText()).toContain('false'); - }); - - it('should be valid if empty when min length is set', function() { - userLastInput.clear(); - userLastInput.sendKeys(''); - - expect(user.getText()).toContain('{"name":"guest","last":""}'); - expect(lastNameValid.getText()).toContain('true'); - expect(formValid.getText()).toContain('true'); - }); - - it('should be invalid if less than required min length', function() { - userLastInput.clear(); - userLastInput.sendKeys('xx'); - - expect(user.getText()).toContain('{"name":"guest"}'); - expect(lastNameValid.getText()).toContain('false'); - expect(lastNameError.getText()).toContain('minlength'); - expect(formValid.getText()).toContain('false'); - }); - - it('should be invalid if longer than max length', function() { - userLastInput.clear(); - userLastInput.sendKeys('some ridiculously long name'); - - expect(user.getText()).toContain('{"name":"guest"}'); - expect(lastNameValid.getText()).toContain('false'); - expect(lastNameError.getText()).toContain('maxlength'); - expect(formValid.getText()).toContain('false'); - }); - -
- */ -var inputDirective = ['$browser', '$sniffer', '$filter', '$parse', - function($browser, $sniffer, $filter, $parse) { - return { - restrict: 'E', - require: ['?ngModel'], - link: { - pre: function(scope, element, attr, ctrls) { - if (ctrls[0]) { - (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer, - $browser, $filter, $parse); - } - } - } - }; -}]; - - - -var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/; -/** - * @ngdoc directive - * @name ngValue - * - * @description - * Binds the given expression to the value of `