├── xstatic
├── pkg
│ ├── angular
│ │ ├── data
│ │ │ ├── version.txt
│ │ │ ├── version.json
│ │ │ ├── angular-csp.css
│ │ │ ├── errors.json
│ │ │ ├── angular-cookies.js
│ │ │ ├── angular-touch.js
│ │ │ ├── angular-aria.js
│ │ │ ├── angular-loader.js
│ │ │ ├── angular-messages.js
│ │ │ ├── angular-sanitize.js
│ │ │ └── angular-resource.js
│ │ └── __init__.py
│ └── __init__.py
└── __init__.py
├── .gitreview
├── .gitignore
├── MANIFEST.in
├── tox.ini
├── setup.cfg
├── README.txt
├── setup.py
└── LICENSE
/xstatic/pkg/angular/data/version.txt:
--------------------------------------------------------------------------------
1 | 1.8.2
--------------------------------------------------------------------------------
/xstatic/__init__.py:
--------------------------------------------------------------------------------
1 | __import__('pkg_resources').declare_namespace(__name__)
2 |
--------------------------------------------------------------------------------
/xstatic/pkg/__init__.py:
--------------------------------------------------------------------------------
1 | __import__('pkg_resources').declare_namespace(__name__)
2 |
--------------------------------------------------------------------------------
/.gitreview:
--------------------------------------------------------------------------------
1 | [gerrit]
2 | host=review.opendev.org
3 | port=29418
4 | project=openstack/xstatic-angular.git
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.sw?
3 | *.sqlite3
4 | .DS_STORE
5 | *.egg-info
6 | .eggs
7 | MANIFEST
8 | .venv
9 | .tox
10 | build
11 | dist
12 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include README.txt
2 | recursive-include xstatic *
3 | global-exclude *.pyc
4 | global-exclude *.pyo
5 | global-exclude *.orig
6 | global-exclude *.rej
7 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [tox]
2 | minversion = 1.6
3 | skipsdist = True
4 | envlist = py27,py33,py34
5 |
6 | [testenv:venv]
7 | basepython = python3
8 | commands = {posargs}
9 |
10 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/version.json:
--------------------------------------------------------------------------------
1 | {"raw":"v1.8.2","major":1,"minor":8,"patch":2,"prerelease":[],"build":[],"version":"1.8.2","codeName":"meteoric-mining","full":"1.8.2","branch":"v1.8.x","cdn":{"raw":"v1.8.1","major":1,"minor":8,"patch":1,"prerelease":[],"build":[],"version":"1.8.1","docsUrl":"http://code.angularjs.org/1.8.1/docs"}}
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | name = XStatic-Angular
3 | description = Angular 1.8.2 (XStatic packaging standard)
4 | description_file = README.rst
5 | maintainer = Rob Cresswell
6 | maintainer_email = robert.cresswell@outlook.com
7 | home_page = http://angularjs.org
8 | keywords = angular xstatic
9 | license = MIT
10 | zip_safe = False
11 | namespace_packages =
12 | xstatic
13 | xstatic.pkg
14 |
15 | [files]
16 | packages =
17 | xstatic
18 |
19 | [bdist_wheel]
20 | universal = True
21 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/angular-csp.css:
--------------------------------------------------------------------------------
1 | /* Include this file in your html if you are using the CSP mode. */
2 |
3 | @charset "UTF-8";
4 |
5 | [ng\:cloak],
6 | [ng-cloak],
7 | [data-ng-cloak],
8 | [x-ng-cloak],
9 | .ng-cloak,
10 | .x-ng-cloak,
11 | .ng-hide:not(.ng-hide-animate) {
12 | display: none !important;
13 | }
14 |
15 | ng\:form {
16 | display: block;
17 | }
18 |
19 | .ng-animate-shim {
20 | visibility:hidden;
21 | }
22 |
23 | .ng-anchor {
24 | position:absolute;
25 | }
26 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | XStatic-Angular
2 | ---------------
3 |
4 | Angular JavaScript library packaged for setuptools (easy_install) / pip.
5 |
6 | This package is intended to be used by **any** project that needs these files.
7 |
8 | It intentionally does **not** provide any extra code except some metadata
9 | **nor** has any extra requirements. You MAY use some minimal support code from
10 | the XStatic base package, if you like.
11 |
12 | You can find more info about the xstatic packaging way in the package `XStatic`.
13 |
14 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 | from xstatic.pkg import angular as xs
3 |
4 | # The README.txt file should be written in reST so that PyPI can use
5 | # it to generate your project's PyPI page.
6 | long_description = open('README.txt').read()
7 |
8 | setup(
9 | name=xs.PACKAGE_NAME,
10 | version=xs.PACKAGE_VERSION,
11 | description=xs.DESCRIPTION,
12 | long_description=long_description,
13 | classifiers=xs.CLASSIFIERS,
14 | keywords=xs.KEYWORDS,
15 | maintainer=xs.MAINTAINER,
16 | maintainer_email=xs.MAINTAINER_EMAIL,
17 | license=xs.LICENSE,
18 | url=xs.HOMEPAGE,
19 | platforms=xs.PLATFORMS,
20 | packages=find_packages(),
21 | namespace_packages=['xstatic', 'xstatic.pkg'],
22 | include_package_data=True,
23 | zip_safe=False,
24 | install_requires=[],
25 | )
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | XStatic resource package
3 |
4 | See package 'XStatic' for documentation and basic tools.
5 | """
6 |
7 | DISPLAY_NAME = 'Angular' # official name, upper/lowercase allowed, no spaces
8 | PACKAGE_NAME = 'XStatic-%s' % DISPLAY_NAME # name used for PyPi
9 |
10 | NAME = __name__.split('.')[-1] # package name (e.g. 'foo' or 'foo_bar')
11 | # please use a all-lowercase valid python
12 | # package name
13 |
14 | VERSION = '1.8.2' # version of the packaged files, please use the upstream
15 | # version number
16 | BUILD = '2' # our package build number, so we can release new builds
17 | # with fixes for xstatic stuff.
18 | PACKAGE_VERSION = VERSION + '.' + BUILD # version used for PyPi
19 |
20 | DESCRIPTION = "%s %s (XStatic packaging standard)" % (DISPLAY_NAME, VERSION)
21 |
22 | PLATFORMS = 'any'
23 | CLASSIFIERS = []
24 | KEYWORDS = '%s xstatic' % NAME
25 |
26 | # XStatic-* package maintainer:
27 | MAINTAINER = 'Rob Cresswell'
28 | MAINTAINER_EMAIL = 'robert.cresswell@outlook.com'
29 |
30 | # this refers to the project homepage of the stuff we packaged:
31 | HOMEPAGE = 'http://angularjs.org'
32 |
33 | # this refers to all files:
34 | LICENSE = 'MIT'
35 |
36 | from os.path import join, dirname
37 | BASE_DIR = join(dirname(__file__), 'data')
38 | # linux package maintainers just can point to their file locations like this:
39 | #BASE_DIR = '/usr/share/javascript/angular'
40 |
41 | LOCATIONS = {
42 | # CDN locations (if no public CDN exists, use an empty dict)
43 | # if value is a string, it is a base location, just append relative
44 | # path/filename. if value is a dict, do another lookup using the
45 | # relative path/filename you want.
46 | # your relative path/filenames should usually be without version
47 | # information, because either the base dir/url is exactly for this
48 | # version or the mapping will care for accessing this version.
49 | }
50 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/errors.json:
--------------------------------------------------------------------------------
1 | {"id":"ng","generated":"Wed Oct 21 2020 11:59:43 GMT+0000 (Coordinated Universal Time)","errors":{"ng":{"areq":"Argument '{0}' is {1}","cpta":"Can't copy! TypedArray destination cannot be mutated.","test":"no injector found for element argument to getTestability","cpws":"Can't copy! Making copies of Window or Scope instances is not supported.","aobj":"Argument '{0}' must be an object","btstrpd":"App already bootstrapped with this element '{0}'","cpi":"Can't copy! Source and destination are identical.","badname":"hasOwnProperty is not a valid {0} name"},"$http":{"baddata":"Data must be a valid JSON object. Received: \"{0}\". Parse error: \"{1}\"","badreq":"Http request configuration url must be a string or a $sce trusted object. Received: {0}","badjsonp":"Illegal use of callback param, \"{0}\", in url, \"{1}\""},"ngPattern":{"noregexp":"Expected {0} to be a RegExp but was {1}. Element: {2}"},"$parse":{"ueoe":"Unexpected end of expression: {0}","lexerr":"Lexer Error: {0} at column{1} in expression [{2}].","esc":"IMPOSSIBLE","lval":"Trying to assign a value to a non l-value","syntax":"Syntax Error: Token '{0}' {1} at column {2} of the expression [{3}] starting at [{4}]."},"orderBy":{"notarray":"Expected array but received: {0}"},"$q":{"norslvr":"Expected resolverFn, got '{0}'","qcycle":"Expected promise to be resolved with value other than itself '{0}'"},"$injector":{"pget":"Provider '{0}' must define $get factory method.","cdep":"Circular dependency found: {0}","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.","strictdi":"{0} is not using explicit annotation and cannot be invoked in strict mode","modulerr":"Failed to instantiate module {0} due to:\n{1}","undef":"Provider '{0}' must return a value from $get factory method.","unpr":"Unknown provider: {0}","itkn":"Incorrect injection token! Expected service name as string, got {0}"},"ngTransclude":{"orphan":"Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found. Element: {0}"},"ngModel":{"nopromise":"Expected asynchronous validator to return a promise but got '{0}' instead.","nonassign":"Expression '{0}' is non-assignable. Element: {1}","datefmt":"Expected `{0}` to be a date","constexpr":"Expected constant expression for `{0}`, but saw `{1}`.","numfmt":"Expected `{0}` to be a number"},"ngOptions":{"iexp":"Expected expression in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '{0}'. Element: {1}"},"$rootScope":{"inprog":"{0} already in progress","infdig":"{0} $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: {1}"},"$compile":{"selmulti":"Binding to the 'multiple' attribute is not supported. Element: {0}","ctreq":"Controller '{0}', required by directive '{1}', can't be found!","tplrt":"Template for directive '{0}' must have exactly one root element. {1}","iscp":"Invalid {3} for directive '{0}'. Definition: {... {1}: '{2}' ...}","baddir":"Directive/Component name '{0}' is invalid. The name should not contain leading or trailing whitespaces","multilink":"This element has already been linked.","noctrl":"Cannot bind to controller without directive '{0}'s controller.","srcset":"Can't pass trusted values to `{0}`: \"{1}\"","multidir":"Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}","badrestrict":"Restrict property '{0}' of directive '{1}' is invalid","uterdir":"Unterminated attribute, found '{0}' but no matching '{1}' found.","ctxoverride":"Property context '{0}.{1}' already set to '{2}', cannot override to '{3}'.","infchng":"{0} $onChanges() iterations reached. Aborting!\n","reqslot":"Required transclusion slot `{0}` was not filled.","nodomevents":"Interpolations for HTML DOM event attributes are disallowed","nonassign":"Expression '{0}' in attribute '{1}' used with directive '{2}' is non-assignable!","missingattr":"Attribute '{0}' of '{1}' is non-optional and must be set!","noslot":"No parent directive that requires a transclusion with slot name \"{0}\". Element: {1}"},"ngRepeat":{"badident":"alias '{0}' is invalid --- must be a valid JS identifier which is not a reserved name.","iexp":"Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.","dupes":"Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}","iidexp":"'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'."},"$sce":{"imatcher":"Matchers may only be \"self\", string patterns or RegExp objects","icontext":"Attempted to trust a value in invalid context. Context: {0}; Value: {1}","iwcard":"Illegal sequence *** in string matcher. String: {0}","insecurl":"Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}","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.","unsafe":"Attempting to use an unsafe value in a safe context.","itype":"Attempted to trust a non-string value in a content requiring a string: Context: {0}"},"$timeout":{"badprom":"`$timeout.cancel()` called with a promise that was not generated by `$timeout()`."},"ngRef":{"nonassign":"Expression in ngRef=\"{0}\" is non-assignable!","noctrl":"The controller for ngRefRead=\"{0}\" could not be found on ngRef=\"{1}\""},"$controller":{"ctrlfmt":"Badly formed controller string '{0}'. Must match `__name__ as __id__` or `__name__`.","ctrlreg":"The controller with the name '{0}' is not registered.","noscp":"Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`."},"jqLite":{"offargs":"jqLite#off() does not support the `selector` argument","onargs":"jqLite#on() does not support the `selector` or `eventData` parameters","nosel":"Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element"},"$animate":{"notcsel":"Expecting class selector starting with '.' got '{0}'.","nongcls":"$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the \"{0}\" CSS class."},"$templateRequest":{"tpload":"Failed to load template: {0} (HTTP status: {1} {2})"},"filter":{"notarray":"Expected array but received: {0}"},"$interval":{"badprom":"`$interval.cancel()` called with a promise that was not generated by `$interval()`."},"$location":{"nostate":"History API state support is available only in HTML5 mode and only in browsers supporting HTML5 History API","badpath":"Invalid url \"{0}\".","ipthprfx":"Invalid url \"{0}\", missing path prefix \"{1}\".","isrcharg":"The first argument of the `$location#search()` call must be a string or an object.","nobase":"$location in HTML5 mode requires a tag to be present!"},"$cacheFactory":{"iid":"CacheId '{0}' is already taken!"},"$interpolate":{"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","interr":"Can't interpolate: {0}\n{1}","nochgmustache":"angular-message-format.js currently does not allow you to use custom start and end symbols for interpolation.","reqcomma":"Expected a comma after the keyword “{0}” at line {1}, column {2} of text “{3}”","untermstr":"The string beginning at line {0}, column {1} is unterminated in text “{2}”","badexpr":"Unexpected operator “{0}” at line {1}, column {2} in text. Was expecting “{3}”. Text: “{4}”","dupvalue":"The choice “{0}” is specified more than once. Duplicate key is at line {1}, column {2} in text “{3}”","unsafe":"Use of select/plural MessageFormat syntax is currently disallowed in a secure context ({0}). At line {1}, column {2} of text “{3}”","reqother":"“other” is a required option.","reqendinterp":"Expecting end of interpolation symbol, “{0}”, at line {1}, column {2} in text “{3}”","reqarg":"Expected one of “plural” or “select” at line {0}, column {1} of text “{2}”","wantstring":"Expected the beginning of a string at line {0}, column {1} in text “{2}”","logicbug":"The messageformat parser has encountered an internal error. Please file a github issue against the AngularJS project and provide this message text that triggers the bug. Text: “{0}”","reqopenbrace":"The plural choice “{0}” must be followed by a message in braces at line {1}, column {2} in text “{3}”","unknarg":"Unsupported keyword “{0}” at line {0}, column {1}. Only “plural” and “select” are currently supported. Text: “{3}”","reqendbrace":"The plural/select choice “{0}” message starting at line {1}, column {2} does not have an ending closing brace. Text “{3}”"},"$resource":{"badargs":"Expected up to 4 arguments [params, data, success, error], got {0} arguments","badmember":"Dotted member path \"@{0}\" is invalid.","badname":"hasOwnProperty is not a valid parameter name.","badcfg":"Error in resource configuration for action `{0}`. Expected response to contain an {1} but got an {2} (Request: {3} {4})"},"$route":{"norout":"Tried updating route with no current route"},"linky":{"notstring":"Expected string but received: {0}"},"$sanitize":{"noinert":"Can't create an inert html document","uinput":"Failed to sanitize html because the input is unstable","elclob":"Failed to sanitize html because the element is clobbered: {0}"}}}
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/angular-cookies.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.8.2
3 | * (c) 2010-2020 Google LLC. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular) {'use strict';
7 |
8 | /**
9 | * @ngdoc module
10 | * @name ngCookies
11 | * @description
12 | *
13 | * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
14 | *
15 | * See {@link ngCookies.$cookies `$cookies`} for usage.
16 | */
17 |
18 |
19 | angular.module('ngCookies', ['ng']).
20 | info({ angularVersion: '1.8.2' }).
21 | /**
22 | * @ngdoc provider
23 | * @name $cookiesProvider
24 | * @description
25 | * Use `$cookiesProvider` to change the default behavior of the {@link ngCookies.$cookies $cookies} service.
26 | * */
27 | provider('$cookies', [/** @this */function $CookiesProvider() {
28 | /**
29 | * @ngdoc property
30 | * @name $cookiesProvider#defaults
31 | * @description
32 | *
33 | * Object containing default options to pass when setting cookies.
34 | *
35 | * The object may have following properties:
36 | *
37 | * - **path** - `{string}` - The cookie will be available only for this path and its
38 | * sub-paths. By default, this is the URL that appears in your `` tag.
39 | * - **domain** - `{string}` - The cookie will be available only for this domain and
40 | * its sub-domains. For security reasons the user agent will not accept the cookie
41 | * if the current domain is not a sub-domain of this domain or equal to it.
42 | * - **expires** - `{string|Date}` - String of the form "Wdy, DD Mon YYYY HH:MM:SS GMT"
43 | * or a Date object indicating the exact date/time this cookie will expire.
44 | * - **secure** - `{boolean}` - If `true`, then the cookie will only be available through a
45 | * secured connection.
46 | * - **samesite** - `{string}` - prevents the browser from sending the cookie along with cross-site requests.
47 | * Accepts the values `lax` and `strict`. See the [OWASP Wiki](https://www.owasp.org/index.php/SameSite)
48 | * for more info. Note that as of May 2018, not all browsers support `SameSite`,
49 | * so it cannot be used as a single measure against Cross-Site-Request-Forgery (CSRF) attacks.
50 | *
51 | * Note: By default, the address that appears in your `` tag will be used as the path.
52 | * This is important so that cookies will be visible for all routes when html5mode is enabled.
53 | *
54 | * @example
55 | *
56 | * ```js
57 | * angular.module('cookiesProviderExample', ['ngCookies'])
58 | * .config(['$cookiesProvider', function($cookiesProvider) {
59 | * // Setting default options
60 | * $cookiesProvider.defaults.domain = 'foo.com';
61 | * $cookiesProvider.defaults.secure = true;
62 | * }]);
63 | * ```
64 | **/
65 | var defaults = this.defaults = {};
66 |
67 | function calcOptions(options) {
68 | return options ? angular.extend({}, defaults, options) : defaults;
69 | }
70 |
71 | /**
72 | * @ngdoc service
73 | * @name $cookies
74 | *
75 | * @description
76 | * Provides read/write access to browser's cookies.
77 | *
78 | *
79 | * Up until AngularJS 1.3, `$cookies` exposed properties that represented the
80 | * current browser cookie values. In version 1.4, this behavior has changed, and
81 | * `$cookies` now provides a standard api of getters, setters etc.
82 | *
83 | *
84 | * Requires the {@link ngCookies `ngCookies`} module to be installed.
85 | *
86 | * @example
87 | *
88 | * ```js
89 | * angular.module('cookiesExample', ['ngCookies'])
90 | * .controller('ExampleController', ['$cookies', function($cookies) {
91 | * // Retrieving a cookie
92 | * var favoriteCookie = $cookies.get('myFavorite');
93 | * // Setting a cookie
94 | * $cookies.put('myFavorite', 'oatmeal');
95 | * }]);
96 | * ```
97 | */
98 | this.$get = ['$$cookieReader', '$$cookieWriter', function($$cookieReader, $$cookieWriter) {
99 | return {
100 | /**
101 | * @ngdoc method
102 | * @name $cookies#get
103 | *
104 | * @description
105 | * Returns the value of given cookie key
106 | *
107 | * @param {string} key Id to use for lookup.
108 | * @returns {string} Raw cookie value.
109 | */
110 | get: function(key) {
111 | return $$cookieReader()[key];
112 | },
113 |
114 | /**
115 | * @ngdoc method
116 | * @name $cookies#getObject
117 | *
118 | * @description
119 | * Returns the deserialized value of given cookie key
120 | *
121 | * @param {string} key Id to use for lookup.
122 | * @returns {Object} Deserialized cookie value.
123 | */
124 | getObject: function(key) {
125 | var value = this.get(key);
126 | return value ? angular.fromJson(value) : value;
127 | },
128 |
129 | /**
130 | * @ngdoc method
131 | * @name $cookies#getAll
132 | *
133 | * @description
134 | * Returns a key value object with all the cookies
135 | *
136 | * @returns {Object} All cookies
137 | */
138 | getAll: function() {
139 | return $$cookieReader();
140 | },
141 |
142 | /**
143 | * @ngdoc method
144 | * @name $cookies#put
145 | *
146 | * @description
147 | * Sets a value for given cookie key
148 | *
149 | * @param {string} key Id for the `value`.
150 | * @param {string} value Raw value to be stored.
151 | * @param {Object=} options Options object.
152 | * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
153 | */
154 | put: function(key, value, options) {
155 | $$cookieWriter(key, value, calcOptions(options));
156 | },
157 |
158 | /**
159 | * @ngdoc method
160 | * @name $cookies#putObject
161 | *
162 | * @description
163 | * Serializes and sets a value for given cookie key
164 | *
165 | * @param {string} key Id for the `value`.
166 | * @param {Object} value Value to be stored.
167 | * @param {Object=} options Options object.
168 | * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
169 | */
170 | putObject: function(key, value, options) {
171 | this.put(key, angular.toJson(value), options);
172 | },
173 |
174 | /**
175 | * @ngdoc method
176 | * @name $cookies#remove
177 | *
178 | * @description
179 | * Remove given cookie
180 | *
181 | * @param {string} key Id of the key-value pair to delete.
182 | * @param {Object=} options Options object.
183 | * See {@link ngCookies.$cookiesProvider#defaults $cookiesProvider.defaults}
184 | */
185 | remove: function(key, options) {
186 | $$cookieWriter(key, undefined, calcOptions(options));
187 | }
188 | };
189 | }];
190 | }]);
191 |
192 | /**
193 | * @name $$cookieWriter
194 | * @requires $document
195 | *
196 | * @description
197 | * This is a private service for writing cookies
198 | *
199 | * @param {string} name Cookie name
200 | * @param {string=} value Cookie value (if undefined, cookie will be deleted)
201 | * @param {Object=} options Object with options that need to be stored for the cookie.
202 | */
203 | function $$CookieWriter($document, $log, $browser) {
204 | var cookiePath = $browser.baseHref();
205 | var rawDocument = $document[0];
206 |
207 | function buildCookieString(name, value, options) {
208 | var path, expires;
209 | options = options || {};
210 | expires = options.expires;
211 | path = angular.isDefined(options.path) ? options.path : cookiePath;
212 | if (angular.isUndefined(value)) {
213 | expires = 'Thu, 01 Jan 1970 00:00:00 GMT';
214 | value = '';
215 | }
216 | if (angular.isString(expires)) {
217 | expires = new Date(expires);
218 | }
219 |
220 | var str = encodeURIComponent(name) + '=' + encodeURIComponent(value);
221 | str += path ? ';path=' + path : '';
222 | str += options.domain ? ';domain=' + options.domain : '';
223 | str += expires ? ';expires=' + expires.toUTCString() : '';
224 | str += options.secure ? ';secure' : '';
225 | str += options.samesite ? ';samesite=' + options.samesite : '';
226 |
227 | // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
228 | // - 300 cookies
229 | // - 20 cookies per unique domain
230 | // - 4096 bytes per cookie
231 | var cookieLength = str.length + 1;
232 | if (cookieLength > 4096) {
233 | $log.warn('Cookie \'' + name +
234 | '\' possibly not set or overflowed because it was too large (' +
235 | cookieLength + ' > 4096 bytes)!');
236 | }
237 |
238 | return str;
239 | }
240 |
241 | return function(name, value, options) {
242 | rawDocument.cookie = buildCookieString(name, value, options);
243 | };
244 | }
245 |
246 | $$CookieWriter.$inject = ['$document', '$log', '$browser'];
247 |
248 | angular.module('ngCookies').provider('$$cookieWriter', /** @this */ function $$CookieWriterProvider() {
249 | this.$get = $$CookieWriter;
250 | });
251 |
252 |
253 | })(window, window.angular);
254 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/angular-touch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.8.2
3 | * (c) 2010-2020 Google LLC. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular) {'use strict';
7 |
8 | /**
9 | * @ngdoc module
10 | * @name ngTouch
11 | * @description
12 | *
13 | * The `ngTouch` module provides helpers for touch-enabled devices.
14 | * The implementation is based on jQuery Mobile touch event handling
15 | * ([jquerymobile.com](http://jquerymobile.com/)). *
16 | *
17 | * See {@link ngTouch.$swipe `$swipe`} for usage.
18 | *
19 | * @deprecated
20 | * sinceVersion="1.7.0"
21 | * The ngTouch module with the {@link ngTouch.$swipe `$swipe`} service and
22 | * the {@link ngTouch.ngSwipeLeft} and {@link ngTouch.ngSwipeRight} directives are
23 | * deprecated. Instead, stand-alone libraries for touch handling and gesture interaction
24 | * should be used, for example [HammerJS](https://hammerjs.github.io/) (which is also used by
25 | * Angular).
26 | */
27 |
28 | // define ngTouch module
29 | /* global ngTouch */
30 | var ngTouch = angular.module('ngTouch', []);
31 |
32 | ngTouch.info({ angularVersion: '1.8.2' });
33 |
34 | function nodeName_(element) {
35 | return angular.$$lowercase(element.nodeName || (element[0] && element[0].nodeName));
36 | }
37 |
38 | /* global ngTouch: false */
39 |
40 | /**
41 | * @ngdoc service
42 | * @name $swipe
43 | *
44 | * @deprecated
45 | * sinceVersion="1.7.0"
46 | *
47 | * See the {@link ngTouch module} documentation for more information.
48 | *
49 | * @description
50 | * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe
51 | * behavior, to make implementing swipe-related directives more convenient.
52 | *
53 | * Requires the {@link ngTouch `ngTouch`} module to be installed.
54 | *
55 | * `$swipe` is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`.
56 | *
57 | * # Usage
58 | * The `$swipe` service is an object with a single method: `bind`. `bind` takes an element
59 | * which is to be watched for swipes, and an object with four handler functions. See the
60 | * documentation for `bind` below.
61 | */
62 |
63 | ngTouch.factory('$swipe', [function() {
64 | // The total distance in any direction before we make the call on swipe vs. scroll.
65 | var MOVE_BUFFER_RADIUS = 10;
66 |
67 | var POINTER_EVENTS = {
68 | 'mouse': {
69 | start: 'mousedown',
70 | move: 'mousemove',
71 | end: 'mouseup'
72 | },
73 | 'touch': {
74 | start: 'touchstart',
75 | move: 'touchmove',
76 | end: 'touchend',
77 | cancel: 'touchcancel'
78 | },
79 | 'pointer': {
80 | start: 'pointerdown',
81 | move: 'pointermove',
82 | end: 'pointerup',
83 | cancel: 'pointercancel'
84 | }
85 | };
86 |
87 | function getCoordinates(event) {
88 | var originalEvent = event.originalEvent || event;
89 | var touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent];
90 | var e = (originalEvent.changedTouches && originalEvent.changedTouches[0]) || touches[0];
91 |
92 | return {
93 | x: e.clientX,
94 | y: e.clientY
95 | };
96 | }
97 |
98 | function getEvents(pointerTypes, eventType) {
99 | var res = [];
100 | angular.forEach(pointerTypes, function(pointerType) {
101 | var eventName = POINTER_EVENTS[pointerType][eventType];
102 | if (eventName) {
103 | res.push(eventName);
104 | }
105 | });
106 | return res.join(' ');
107 | }
108 |
109 | return {
110 | /**
111 | * @ngdoc method
112 | * @name $swipe#bind
113 | *
114 | * @description
115 | * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an
116 | * object containing event handlers.
117 | * The pointer types that should be used can be specified via the optional
118 | * third argument, which is an array of strings `'mouse'`, `'touch'` and `'pointer'`. By default,
119 | * `$swipe` will listen for `mouse`, `touch` and `pointer` events.
120 | *
121 | * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end`
122 | * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }` and the raw
123 | * `event`. `cancel` receives the raw `event` as its single parameter.
124 | *
125 | * `start` is called on either `mousedown`, `touchstart` or `pointerdown`. After this event, `$swipe` is
126 | * watching for `touchmove`, `mousemove` or `pointermove` events. These events are ignored until the total
127 | * distance moved in either dimension exceeds a small threshold.
128 | *
129 | * Once this threshold is exceeded, either the horizontal or vertical delta is greater.
130 | * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow.
131 | * - If the vertical distance is greater, this is a scroll, and we let the browser take over.
132 | * A `cancel` event is sent.
133 | *
134 | * `move` is called on `mousemove`, `touchmove` and `pointermove` after the above logic has determined that
135 | * a swipe is in progress.
136 | *
137 | * `end` is called when a swipe is successfully completed with a `touchend`, `mouseup` or `pointerup`.
138 | *
139 | * `cancel` is called either on a `touchcancel` or `pointercancel` from the browser, or when we begin scrolling
140 | * as described above.
141 | *
142 | */
143 | bind: function(element, eventHandlers, pointerTypes) {
144 | // Absolute total movement, used to control swipe vs. scroll.
145 | var totalX, totalY;
146 | // Coordinates of the start position.
147 | var startCoords;
148 | // Last event's position.
149 | var lastPos;
150 | // Whether a swipe is active.
151 | var active = false;
152 |
153 | pointerTypes = pointerTypes || ['mouse', 'touch', 'pointer'];
154 | element.on(getEvents(pointerTypes, 'start'), function(event) {
155 | startCoords = getCoordinates(event);
156 | active = true;
157 | totalX = 0;
158 | totalY = 0;
159 | lastPos = startCoords;
160 | if (eventHandlers['start']) {
161 | eventHandlers['start'](startCoords, event);
162 | }
163 | });
164 | var events = getEvents(pointerTypes, 'cancel');
165 | if (events) {
166 | element.on(events, function(event) {
167 | active = false;
168 | if (eventHandlers['cancel']) {
169 | eventHandlers['cancel'](event);
170 | }
171 | });
172 | }
173 |
174 | element.on(getEvents(pointerTypes, 'move'), function(event) {
175 | if (!active) return;
176 |
177 | // Android will send a touchcancel if it thinks we're starting to scroll.
178 | // So when the total distance (+ or - or both) exceeds 10px in either direction,
179 | // we either:
180 | // - On totalX > totalY, we send preventDefault() and treat this as a swipe.
181 | // - On totalY > totalX, we let the browser handle it as a scroll.
182 |
183 | if (!startCoords) return;
184 | var coords = getCoordinates(event);
185 |
186 | totalX += Math.abs(coords.x - lastPos.x);
187 | totalY += Math.abs(coords.y - lastPos.y);
188 |
189 | lastPos = coords;
190 |
191 | if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
192 | return;
193 | }
194 |
195 | // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll.
196 | if (totalY > totalX) {
197 | // Allow native scrolling to take over.
198 | active = false;
199 | if (eventHandlers['cancel']) {
200 | eventHandlers['cancel'](event);
201 | }
202 | return;
203 | } else {
204 | // Prevent the browser from scrolling.
205 | event.preventDefault();
206 | if (eventHandlers['move']) {
207 | eventHandlers['move'](coords, event);
208 | }
209 | }
210 | });
211 |
212 | element.on(getEvents(pointerTypes, 'end'), function(event) {
213 | if (!active) return;
214 | active = false;
215 | if (eventHandlers['end']) {
216 | eventHandlers['end'](getCoordinates(event), event);
217 | }
218 | });
219 | }
220 | };
221 | }]);
222 |
223 | /* global ngTouch: false */
224 |
225 | /**
226 | * @ngdoc directive
227 | * @name ngSwipeLeft
228 | *
229 | * @deprecated
230 | * sinceVersion="1.7.0"
231 | *
232 | * See the {@link ngTouch module} documentation for more information.
233 | *
234 | * @description
235 | * Specify custom behavior when an element is swiped to the left on a touchscreen device.
236 | * A leftward swipe is a quick, right-to-left slide of the finger.
237 | * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag
238 | * too.
239 | *
240 | * To disable the mouse click and drag functionality, add `ng-swipe-disable-mouse` to
241 | * the `ng-swipe-left` or `ng-swipe-right` DOM Element.
242 | *
243 | * Requires the {@link ngTouch `ngTouch`} module to be installed.
244 | *
245 | * @element ANY
246 | * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate
247 | * upon left swipe. (Event object is available as `$event`)
248 | *
249 | * @example
250 |
251 |
252 |
253 | Some list content, like an email in the inbox
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 | angular.module('ngSwipeLeftExample', ['ngTouch']);
262 |
263 |
264 | */
265 |
266 | /**
267 | * @ngdoc directive
268 | * @name ngSwipeRight
269 | *
270 | * @deprecated
271 | * sinceVersion="1.7.0"
272 | *
273 | * See the {@link ngTouch module} documentation for more information.
274 | *
275 | * @description
276 | * Specify custom behavior when an element is swiped to the right on a touchscreen device.
277 | * A rightward swipe is a quick, left-to-right slide of the finger.
278 | * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag
279 | * too.
280 | *
281 | * Requires the {@link ngTouch `ngTouch`} module to be installed.
282 | *
283 | * @element ANY
284 | * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate
285 | * upon right swipe. (Event object is available as `$event`)
286 | *
287 | * @example
288 |
289 |
290 |
291 | Some list content, like an email in the inbox
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 | angular.module('ngSwipeRightExample', ['ngTouch']);
300 |
301 |
302 | */
303 |
304 | function makeSwipeDirective(directiveName, direction, eventName) {
305 | ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) {
306 | // The maximum vertical delta for a swipe should be less than 75px.
307 | var MAX_VERTICAL_DISTANCE = 75;
308 | // Vertical distance should not be more than a fraction of the horizontal distance.
309 | var MAX_VERTICAL_RATIO = 0.3;
310 | // At least a 30px lateral motion is necessary for a swipe.
311 | var MIN_HORIZONTAL_DISTANCE = 30;
312 |
313 | return function(scope, element, attr) {
314 | var swipeHandler = $parse(attr[directiveName]);
315 |
316 | var startCoords, valid;
317 |
318 | function validSwipe(coords) {
319 | // Check that it's within the coordinates.
320 | // Absolute vertical distance must be within tolerances.
321 | // Horizontal distance, we take the current X - the starting X.
322 | // This is negative for leftward swipes and positive for rightward swipes.
323 | // After multiplying by the direction (-1 for left, +1 for right), legal swipes
324 | // (ie. same direction as the directive wants) will have a positive delta and
325 | // illegal ones a negative delta.
326 | // Therefore this delta must be positive, and larger than the minimum.
327 | if (!startCoords) return false;
328 | var deltaY = Math.abs(coords.y - startCoords.y);
329 | var deltaX = (coords.x - startCoords.x) * direction;
330 | return valid && // Short circuit for already-invalidated swipes.
331 | deltaY < MAX_VERTICAL_DISTANCE &&
332 | deltaX > 0 &&
333 | deltaX > MIN_HORIZONTAL_DISTANCE &&
334 | deltaY / deltaX < MAX_VERTICAL_RATIO;
335 | }
336 |
337 | var pointerTypes = ['touch'];
338 | if (!angular.isDefined(attr['ngSwipeDisableMouse'])) {
339 | pointerTypes.push('mouse');
340 | }
341 | $swipe.bind(element, {
342 | 'start': function(coords, event) {
343 | startCoords = coords;
344 | valid = true;
345 | },
346 | 'cancel': function(event) {
347 | valid = false;
348 | },
349 | 'end': function(coords, event) {
350 | if (validSwipe(coords)) {
351 | scope.$apply(function() {
352 | element.triggerHandler(eventName);
353 | swipeHandler(scope, {$event: event});
354 | });
355 | }
356 | }
357 | }, pointerTypes);
358 | };
359 | }]);
360 | }
361 |
362 | // Left is negative X-coordinate, right is positive.
363 | makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft');
364 | makeSwipeDirective('ngSwipeRight', 1, 'swiperight');
365 |
366 |
367 |
368 | })(window, window.angular);
369 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/angular-aria.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.8.2
3 | * (c) 2010-2020 Google LLC. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular) {'use strict';
7 |
8 | /**
9 | * @ngdoc module
10 | * @name ngAria
11 | * @description
12 | *
13 | * The `ngAria` module provides support for common
14 | * [ARIA](http://www.w3.org/TR/wai-aria/)
15 | * attributes that convey state or semantic information about the application for users
16 | * of assistive technologies, such as screen readers.
17 | *
18 | * ## Usage
19 | *
20 | * For ngAria to do its magic, simply include the module `ngAria` as a dependency. The following
21 | * directives are supported:
22 | * `ngModel`, `ngChecked`, `ngReadonly`, `ngRequired`, `ngValue`, `ngDisabled`, `ngShow`, `ngHide`,
23 | * `ngClick`, `ngDblClick`, and `ngMessages`.
24 | *
25 | * Below is a more detailed breakdown of the attributes handled by ngAria:
26 | *
27 | * | Directive | Supported Attributes |
28 | * |---------------------------------------------|-----------------------------------------------------------------------------------------------------|
29 | * | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required, input roles |
30 | * | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
31 | * | {@link ng.directive:ngRequired ngRequired} | aria-required |
32 | * | {@link ng.directive:ngChecked ngChecked} | aria-checked |
33 | * | {@link ng.directive:ngReadonly ngReadonly} | aria-readonly |
34 | * | {@link ng.directive:ngValue ngValue} | aria-checked |
35 | * | {@link ng.directive:ngShow ngShow} | aria-hidden |
36 | * | {@link ng.directive:ngHide ngHide} | aria-hidden |
37 | * | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
38 | * | {@link module:ngMessages ngMessages} | aria-live |
39 | * | {@link ng.directive:ngClick ngClick} | tabindex, keydown event, button role |
40 | *
41 | * Find out more information about each directive by reading the
42 | * {@link guide/accessibility ngAria Developer Guide}.
43 | *
44 | * ## Example
45 | * Using ngDisabled with ngAria:
46 | * ```html
47 | *
48 | * ```
49 | * Becomes:
50 | * ```html
51 | *
52 | * ```
53 | *
54 | * ## Disabling Specific Attributes
55 | * It is possible to disable individual attributes added by ngAria with the
56 | * {@link ngAria.$ariaProvider#config config} method. For more details, see the
57 | * {@link guide/accessibility Developer Guide}.
58 | *
59 | * ## Disabling `ngAria` on Specific Elements
60 | * It is possible to make `ngAria` ignore a specific element, by adding the `ng-aria-disable`
61 | * attribute on it. Note that only the element itself (and not its child elements) will be ignored.
62 | */
63 | var ARIA_DISABLE_ATTR = 'ngAriaDisable';
64 |
65 | var ngAriaModule = angular.module('ngAria', ['ng']).
66 | info({ angularVersion: '1.8.2' }).
67 | provider('$aria', $AriaProvider);
68 |
69 | /**
70 | * Internal Utilities
71 | */
72 | var nativeAriaNodeNames = ['BUTTON', 'A', 'INPUT', 'TEXTAREA', 'SELECT', 'DETAILS', 'SUMMARY'];
73 |
74 | var isNodeOneOf = function(elem, nodeTypeArray) {
75 | if (nodeTypeArray.indexOf(elem[0].nodeName) !== -1) {
76 | return true;
77 | }
78 | };
79 | /**
80 | * @ngdoc provider
81 | * @name $ariaProvider
82 | * @this
83 | *
84 | * @description
85 | *
86 | * Used for configuring the ARIA attributes injected and managed by ngAria.
87 | *
88 | * ```js
89 | * angular.module('myApp', ['ngAria'], function config($ariaProvider) {
90 | * $ariaProvider.config({
91 | * ariaValue: true,
92 | * tabindex: false
93 | * });
94 | * });
95 | *```
96 | *
97 | * ## Dependencies
98 | * Requires the {@link ngAria} module to be installed.
99 | *
100 | */
101 | function $AriaProvider() {
102 | var config = {
103 | ariaHidden: true,
104 | ariaChecked: true,
105 | ariaReadonly: true,
106 | ariaDisabled: true,
107 | ariaRequired: true,
108 | ariaInvalid: true,
109 | ariaValue: true,
110 | tabindex: true,
111 | bindKeydown: true,
112 | bindRoleForClick: true
113 | };
114 |
115 | /**
116 | * @ngdoc method
117 | * @name $ariaProvider#config
118 | *
119 | * @param {object} config object to enable/disable specific ARIA attributes
120 | *
121 | * - **ariaHidden** – `{boolean}` – Enables/disables aria-hidden tags
122 | * - **ariaChecked** – `{boolean}` – Enables/disables aria-checked tags
123 | * - **ariaReadonly** – `{boolean}` – Enables/disables aria-readonly tags
124 | * - **ariaDisabled** – `{boolean}` – Enables/disables aria-disabled tags
125 | * - **ariaRequired** – `{boolean}` – Enables/disables aria-required tags
126 | * - **ariaInvalid** – `{boolean}` – Enables/disables aria-invalid tags
127 | * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and
128 | * aria-valuenow tags
129 | * - **tabindex** – `{boolean}` – Enables/disables tabindex tags
130 | * - **bindKeydown** – `{boolean}` – Enables/disables keyboard event binding on non-interactive
131 | * elements (such as `div` or `li`) using ng-click, making them more accessible to users of
132 | * assistive technologies
133 | * - **bindRoleForClick** – `{boolean}` – Adds role=button to non-interactive elements (such as
134 | * `div` or `li`) using ng-click, making them more accessible to users of assistive
135 | * technologies
136 | *
137 | * @description
138 | * Enables/disables various ARIA attributes
139 | */
140 | this.config = function(newConfig) {
141 | config = angular.extend(config, newConfig);
142 | };
143 |
144 | function watchExpr(attrName, ariaAttr, nativeAriaNodeNames, negate) {
145 | return function(scope, elem, attr) {
146 | if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
147 |
148 | var ariaCamelName = attr.$normalize(ariaAttr);
149 | if (config[ariaCamelName] && !isNodeOneOf(elem, nativeAriaNodeNames) && !attr[ariaCamelName]) {
150 | scope.$watch(attr[attrName], function(boolVal) {
151 | // ensure boolean value
152 | boolVal = negate ? !boolVal : !!boolVal;
153 | elem.attr(ariaAttr, boolVal);
154 | });
155 | }
156 | };
157 | }
158 | /**
159 | * @ngdoc service
160 | * @name $aria
161 | *
162 | * @description
163 | *
164 | * The $aria service contains helper methods for applying common
165 | * [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives.
166 | *
167 | * ngAria injects common accessibility attributes that tell assistive technologies when HTML
168 | * elements are enabled, selected, hidden, and more. To see how this is performed with ngAria,
169 | * let's review a code snippet from ngAria itself:
170 | *
171 | *```js
172 | * ngAriaModule.directive('ngDisabled', ['$aria', function($aria) {
173 | * return $aria.$$watchExpr('ngDisabled', 'aria-disabled', nativeAriaNodeNames, false);
174 | * }])
175 | *```
176 | * Shown above, the ngAria module creates a directive with the same signature as the
177 | * traditional `ng-disabled` directive. But this ngAria version is dedicated to
178 | * solely managing accessibility attributes on custom elements. The internal `$aria` service is
179 | * used to watch the boolean attribute `ngDisabled`. If it has not been explicitly set by the
180 | * developer, `aria-disabled` is injected as an attribute with its value synchronized to the
181 | * value in `ngDisabled`.
182 | *
183 | * Because ngAria hooks into the `ng-disabled` directive, developers do not have to do
184 | * anything to enable this feature. The `aria-disabled` attribute is automatically managed
185 | * simply as a silent side-effect of using `ng-disabled` with the ngAria module.
186 | *
187 | * The full list of directives that interface with ngAria:
188 | * * **ngModel**
189 | * * **ngChecked**
190 | * * **ngReadonly**
191 | * * **ngRequired**
192 | * * **ngDisabled**
193 | * * **ngValue**
194 | * * **ngShow**
195 | * * **ngHide**
196 | * * **ngClick**
197 | * * **ngDblclick**
198 | * * **ngMessages**
199 | *
200 | * Read the {@link guide/accessibility ngAria Developer Guide} for a thorough explanation of each
201 | * directive.
202 | *
203 | *
204 | * ## Dependencies
205 | * Requires the {@link ngAria} module to be installed.
206 | */
207 | this.$get = function() {
208 | return {
209 | config: function(key) {
210 | return config[key];
211 | },
212 | $$watchExpr: watchExpr
213 | };
214 | };
215 | }
216 |
217 |
218 | ngAriaModule.directive('ngShow', ['$aria', function($aria) {
219 | return $aria.$$watchExpr('ngShow', 'aria-hidden', [], true);
220 | }])
221 | .directive('ngHide', ['$aria', function($aria) {
222 | return $aria.$$watchExpr('ngHide', 'aria-hidden', [], false);
223 | }])
224 | .directive('ngValue', ['$aria', function($aria) {
225 | return $aria.$$watchExpr('ngValue', 'aria-checked', nativeAriaNodeNames, false);
226 | }])
227 | .directive('ngChecked', ['$aria', function($aria) {
228 | return $aria.$$watchExpr('ngChecked', 'aria-checked', nativeAriaNodeNames, false);
229 | }])
230 | .directive('ngReadonly', ['$aria', function($aria) {
231 | return $aria.$$watchExpr('ngReadonly', 'aria-readonly', nativeAriaNodeNames, false);
232 | }])
233 | .directive('ngRequired', ['$aria', function($aria) {
234 | return $aria.$$watchExpr('ngRequired', 'aria-required', nativeAriaNodeNames, false);
235 | }])
236 | .directive('ngModel', ['$aria', function($aria) {
237 |
238 | function shouldAttachAttr(attr, normalizedAttr, elem, allowNonAriaNodes) {
239 | return $aria.config(normalizedAttr) &&
240 | !elem.attr(attr) &&
241 | (allowNonAriaNodes || !isNodeOneOf(elem, nativeAriaNodeNames)) &&
242 | (elem.attr('type') !== 'hidden' || elem[0].nodeName !== 'INPUT');
243 | }
244 |
245 | function shouldAttachRole(role, elem) {
246 | // if element does not have role attribute
247 | // AND element type is equal to role (if custom element has a type equaling shape) <-- remove?
248 | // AND element is not in nativeAriaNodeNames
249 | return !elem.attr('role') && (elem.attr('type') === role) && !isNodeOneOf(elem, nativeAriaNodeNames);
250 | }
251 |
252 | function getShape(attr, elem) {
253 | var type = attr.type,
254 | role = attr.role;
255 |
256 | return ((type || role) === 'checkbox' || role === 'menuitemcheckbox') ? 'checkbox' :
257 | ((type || role) === 'radio' || role === 'menuitemradio') ? 'radio' :
258 | (type === 'range' || role === 'progressbar' || role === 'slider') ? 'range' : '';
259 | }
260 |
261 | return {
262 | restrict: 'A',
263 | require: 'ngModel',
264 | priority: 200, //Make sure watches are fired after any other directives that affect the ngModel value
265 | compile: function(elem, attr) {
266 | if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
267 |
268 | var shape = getShape(attr, elem);
269 |
270 | return {
271 | post: function(scope, elem, attr, ngModel) {
272 | var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem, false);
273 |
274 | function ngAriaWatchModelValue() {
275 | return ngModel.$modelValue;
276 | }
277 |
278 | function getRadioReaction(newVal) {
279 | // Strict comparison would cause a BC
280 | // eslint-disable-next-line eqeqeq
281 | var boolVal = (attr.value == ngModel.$viewValue);
282 | elem.attr('aria-checked', boolVal);
283 | }
284 |
285 | function getCheckboxReaction() {
286 | elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue));
287 | }
288 |
289 | switch (shape) {
290 | case 'radio':
291 | case 'checkbox':
292 | if (shouldAttachRole(shape, elem)) {
293 | elem.attr('role', shape);
294 | }
295 | if (shouldAttachAttr('aria-checked', 'ariaChecked', elem, false)) {
296 | scope.$watch(ngAriaWatchModelValue, shape === 'radio' ?
297 | getRadioReaction : getCheckboxReaction);
298 | }
299 | if (needsTabIndex) {
300 | elem.attr('tabindex', 0);
301 | }
302 | break;
303 | case 'range':
304 | if (shouldAttachRole(shape, elem)) {
305 | elem.attr('role', 'slider');
306 | }
307 | if ($aria.config('ariaValue')) {
308 | var needsAriaValuemin = !elem.attr('aria-valuemin') &&
309 | (attr.hasOwnProperty('min') || attr.hasOwnProperty('ngMin'));
310 | var needsAriaValuemax = !elem.attr('aria-valuemax') &&
311 | (attr.hasOwnProperty('max') || attr.hasOwnProperty('ngMax'));
312 | var needsAriaValuenow = !elem.attr('aria-valuenow');
313 |
314 | if (needsAriaValuemin) {
315 | attr.$observe('min', function ngAriaValueMinReaction(newVal) {
316 | elem.attr('aria-valuemin', newVal);
317 | });
318 | }
319 | if (needsAriaValuemax) {
320 | attr.$observe('max', function ngAriaValueMinReaction(newVal) {
321 | elem.attr('aria-valuemax', newVal);
322 | });
323 | }
324 | if (needsAriaValuenow) {
325 | scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) {
326 | elem.attr('aria-valuenow', newVal);
327 | });
328 | }
329 | }
330 | if (needsTabIndex) {
331 | elem.attr('tabindex', 0);
332 | }
333 | break;
334 | }
335 |
336 | if (!attr.hasOwnProperty('ngRequired') && ngModel.$validators.required
337 | && shouldAttachAttr('aria-required', 'ariaRequired', elem, false)) {
338 | // ngModel.$error.required is undefined on custom controls
339 | attr.$observe('required', function() {
340 | elem.attr('aria-required', !!attr['required']);
341 | });
342 | }
343 |
344 | if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem, true)) {
345 | scope.$watch(function ngAriaInvalidWatch() {
346 | return ngModel.$invalid;
347 | }, function ngAriaInvalidReaction(newVal) {
348 | elem.attr('aria-invalid', !!newVal);
349 | });
350 | }
351 | }
352 | };
353 | }
354 | };
355 | }])
356 | .directive('ngDisabled', ['$aria', function($aria) {
357 | return $aria.$$watchExpr('ngDisabled', 'aria-disabled', nativeAriaNodeNames, false);
358 | }])
359 | .directive('ngMessages', function() {
360 | return {
361 | restrict: 'A',
362 | require: '?ngMessages',
363 | link: function(scope, elem, attr, ngMessages) {
364 | if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
365 |
366 | if (!elem.attr('aria-live')) {
367 | elem.attr('aria-live', 'assertive');
368 | }
369 | }
370 | };
371 | })
372 | .directive('ngClick',['$aria', '$parse', function($aria, $parse) {
373 | return {
374 | restrict: 'A',
375 | compile: function(elem, attr) {
376 | if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
377 |
378 | var fn = $parse(attr.ngClick);
379 | return function(scope, elem, attr) {
380 |
381 | if (!isNodeOneOf(elem, nativeAriaNodeNames)) {
382 |
383 | if ($aria.config('bindRoleForClick') && !elem.attr('role')) {
384 | elem.attr('role', 'button');
385 | }
386 |
387 | if ($aria.config('tabindex') && !elem.attr('tabindex')) {
388 | elem.attr('tabindex', 0);
389 | }
390 |
391 | if ($aria.config('bindKeydown') && !attr.ngKeydown && !attr.ngKeypress && !attr.ngKeyup) {
392 | elem.on('keydown', function(event) {
393 | var keyCode = event.which || event.keyCode;
394 |
395 | if (keyCode === 13 || keyCode === 32) {
396 | // If the event is triggered on a non-interactive element ...
397 | if (nativeAriaNodeNames.indexOf(event.target.nodeName) === -1 && !event.target.isContentEditable) {
398 | // ... prevent the default browser behavior (e.g. scrolling when pressing spacebar)
399 | // See https://github.com/angular/angular.js/issues/16664
400 | event.preventDefault();
401 | }
402 | scope.$apply(callback);
403 | }
404 |
405 | function callback() {
406 | fn(scope, { $event: event });
407 | }
408 | });
409 | }
410 | }
411 | };
412 | }
413 | };
414 | }])
415 | .directive('ngDblclick', ['$aria', function($aria) {
416 | return function(scope, elem, attr) {
417 | if (attr.hasOwnProperty(ARIA_DISABLE_ATTR)) return;
418 |
419 | if ($aria.config('tabindex') && !elem.attr('tabindex') && !isNodeOneOf(elem, nativeAriaNodeNames)) {
420 | elem.attr('tabindex', 0);
421 | }
422 | };
423 | }]);
424 |
425 |
426 | })(window, window.angular);
427 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/angular-loader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.8.2
3 | * (c) 2010-2020 Google LLC. http://angularjs.org
4 | * License: MIT
5 | */
6 |
7 | (function() {'use strict';
8 | // NOTE:
9 | // These functions are copied here from `src/Angular.js`, because they are needed inside the
10 | // `angular-loader.js` closure and need to be available before the main `angular.js` script has
11 | // been loaded.
12 | function isFunction(value) {return typeof value === 'function';}
13 | function isDefined(value) {return typeof value !== 'undefined';}
14 | function isNumber(value) {return typeof value === 'number';}
15 | function isObject(value) {return value !== null && typeof value === 'object';}
16 | function isScope(obj) {return obj && obj.$evalAsync && obj.$watch;}
17 | function isUndefined(value) {return typeof value === 'undefined';}
18 | function isWindow(obj) {return obj && obj.window === obj;}
19 | function sliceArgs(args, startIndex) {return Array.prototype.slice.call(args, startIndex || 0);}
20 | function toJsonReplacer(key, value) {
21 | var val = value;
22 |
23 | if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
24 | val = undefined;
25 | } else if (isWindow(value)) {
26 | val = '$WINDOW';
27 | } else if (value && window.document === value) {
28 | val = '$DOCUMENT';
29 | } else if (isScope(value)) {
30 | val = '$SCOPE';
31 | }
32 |
33 | return val;
34 | }
35 |
36 | /* exported toDebugString */
37 |
38 | function serializeObject(obj, maxDepth) {
39 | var seen = [];
40 |
41 | // There is no direct way to stringify object until reaching a specific depth
42 | // and a very deep object can cause a performance issue, so we copy the object
43 | // based on this specific depth and then stringify it.
44 | if (isValidObjectMaxDepth(maxDepth)) {
45 | // This file is also included in `angular-loader`, so `copy()` might not always be available in
46 | // the closure. Therefore, it is lazily retrieved as `angular.copy()` when needed.
47 | obj = angular.copy(obj, null, maxDepth);
48 | }
49 | return JSON.stringify(obj, function(key, val) {
50 | val = toJsonReplacer(key, val);
51 | if (isObject(val)) {
52 |
53 | if (seen.indexOf(val) >= 0) return '...';
54 |
55 | seen.push(val);
56 | }
57 | return val;
58 | });
59 | }
60 |
61 | function toDebugString(obj, maxDepth) {
62 | if (typeof obj === 'function') {
63 | return obj.toString().replace(/ \{[\s\S]*$/, '');
64 | } else if (isUndefined(obj)) {
65 | return 'undefined';
66 | } else if (typeof obj !== 'string') {
67 | return serializeObject(obj, maxDepth);
68 | }
69 | return obj;
70 | }
71 |
72 | /* exported
73 | minErrConfig,
74 | errorHandlingConfig,
75 | isValidObjectMaxDepth
76 | */
77 |
78 | var minErrConfig = {
79 | objectMaxDepth: 5,
80 | urlErrorParamsEnabled: true
81 | };
82 |
83 | /**
84 | * @ngdoc function
85 | * @name angular.errorHandlingConfig
86 | * @module ng
87 | * @kind function
88 | *
89 | * @description
90 | * Configure several aspects of error handling in AngularJS if used as a setter or return the
91 | * current configuration if used as a getter. The following options are supported:
92 | *
93 | * - **objectMaxDepth**: The maximum depth to which objects are traversed when stringified for error messages.
94 | *
95 | * Omitted or undefined options will leave the corresponding configuration values unchanged.
96 | *
97 | * @param {Object=} config - The configuration object. May only contain the options that need to be
98 | * updated. Supported keys:
99 | *
100 | * * `objectMaxDepth` **{Number}** - The max depth for stringifying objects. Setting to a
101 | * non-positive or non-numeric value, removes the max depth limit.
102 | * Default: 5
103 | *
104 | * * `urlErrorParamsEnabled` **{Boolean}** - Specifies whether the generated error url will
105 | * contain the parameters of the thrown error. Disabling the parameters can be useful if the
106 | * generated error url is very long.
107 | *
108 | * Default: true. When used without argument, it returns the current value.
109 | */
110 | function errorHandlingConfig(config) {
111 | if (isObject(config)) {
112 | if (isDefined(config.objectMaxDepth)) {
113 | minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN;
114 | }
115 | if (isDefined(config.urlErrorParamsEnabled) && isBoolean(config.urlErrorParamsEnabled)) {
116 | minErrConfig.urlErrorParamsEnabled = config.urlErrorParamsEnabled;
117 | }
118 | } else {
119 | return minErrConfig;
120 | }
121 | }
122 |
123 | /**
124 | * @private
125 | * @param {Number} maxDepth
126 | * @return {boolean}
127 | */
128 | function isValidObjectMaxDepth(maxDepth) {
129 | return isNumber(maxDepth) && maxDepth > 0;
130 | }
131 |
132 |
133 | /**
134 | * @description
135 | *
136 | * This object provides a utility for producing rich Error messages within
137 | * AngularJS. It can be called as follows:
138 | *
139 | * var exampleMinErr = minErr('example');
140 | * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
141 | *
142 | * The above creates an instance of minErr in the example namespace. The
143 | * resulting error will have a namespaced error code of example.one. The
144 | * resulting error will replace {0} with the value of foo, and {1} with the
145 | * value of bar. The object is not restricted in the number of arguments it can
146 | * take.
147 | *
148 | * If fewer arguments are specified than necessary for interpolation, the extra
149 | * interpolation markers will be preserved in the final string.
150 | *
151 | * Since data will be parsed statically during a build step, some restrictions
152 | * are applied with respect to how minErr instances are created and called.
153 | * Instances should have names of the form namespaceMinErr for a minErr created
154 | * using minErr('namespace'). Error codes, namespaces and template strings
155 | * should all be static strings, not variables or general expressions.
156 | *
157 | * @param {string} module The namespace to use for the new minErr instance.
158 | * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
159 | * error from returned function, for cases when a particular type of error is useful.
160 | * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
161 | */
162 |
163 | function minErr(module, ErrorConstructor) {
164 | ErrorConstructor = ErrorConstructor || Error;
165 |
166 | var url = 'https://errors.angularjs.org/1.8.2/';
167 | var regex = url.replace('.', '\\.') + '[\\s\\S]*';
168 | var errRegExp = new RegExp(regex, 'g');
169 |
170 | return function() {
171 | var code = arguments[0],
172 | template = arguments[1],
173 | message = '[' + (module ? module + ':' : '') + code + '] ',
174 | templateArgs = sliceArgs(arguments, 2).map(function(arg) {
175 | return toDebugString(arg, minErrConfig.objectMaxDepth);
176 | }),
177 | paramPrefix, i;
178 |
179 | // A minErr message has two parts: the message itself and the url that contains the
180 | // encoded message.
181 | // The message's parameters can contain other error messages which also include error urls.
182 | // To prevent the messages from getting too long, we strip the error urls from the parameters.
183 |
184 | message += template.replace(/\{\d+\}/g, function(match) {
185 | var index = +match.slice(1, -1);
186 |
187 | if (index < templateArgs.length) {
188 | return templateArgs[index].replace(errRegExp, '');
189 | }
190 |
191 | return match;
192 | });
193 |
194 | message += '\n' + url + (module ? module + '/' : '') + code;
195 |
196 | if (minErrConfig.urlErrorParamsEnabled) {
197 | for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
198 | message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]);
199 | }
200 | }
201 |
202 | return new ErrorConstructor(message);
203 | };
204 | }
205 |
206 | /**
207 | * @ngdoc type
208 | * @name angular.Module
209 | * @module ng
210 | * @description
211 | *
212 | * Interface for configuring AngularJS {@link angular.module modules}.
213 | */
214 |
215 | function setupModuleLoader(window) {
216 |
217 | var $injectorMinErr = minErr('$injector');
218 | var ngMinErr = minErr('ng');
219 |
220 | function ensure(obj, name, factory) {
221 | return obj[name] || (obj[name] = factory());
222 | }
223 |
224 | var angular = ensure(window, 'angular', Object);
225 |
226 | // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
227 | angular.$$minErr = angular.$$minErr || minErr;
228 |
229 | return ensure(angular, 'module', function() {
230 | /** @type {Object.} */
231 | var modules = {};
232 |
233 | /**
234 | * @ngdoc function
235 | * @name angular.module
236 | * @module ng
237 | * @description
238 | *
239 | * The `angular.module` is a global place for creating, registering and retrieving AngularJS
240 | * modules.
241 | * All modules (AngularJS core or 3rd party) that should be available to an application must be
242 | * registered using this mechanism.
243 | *
244 | * Passing one argument retrieves an existing {@link angular.Module},
245 | * whereas passing more than one argument creates a new {@link angular.Module}
246 | *
247 | *
248 | * # Module
249 | *
250 | * A module is a collection of services, directives, controllers, filters, and configuration information.
251 | * `angular.module` is used to configure the {@link auto.$injector $injector}.
252 | *
253 | * ```js
254 | * // Create a new module
255 | * var myModule = angular.module('myModule', []);
256 | *
257 | * // register a new service
258 | * myModule.value('appName', 'MyCoolApp');
259 | *
260 | * // configure existing services inside initialization blocks.
261 | * myModule.config(['$locationProvider', function($locationProvider) {
262 | * // Configure existing providers
263 | * $locationProvider.hashPrefix('!');
264 | * }]);
265 | * ```
266 | *
267 | * Then you can create an injector and load your modules like this:
268 | *
269 | * ```js
270 | * var injector = angular.injector(['ng', 'myModule'])
271 | * ```
272 | *
273 | * However it's more likely that you'll just use
274 | * {@link ng.directive:ngApp ngApp} or
275 | * {@link angular.bootstrap} to simplify this process for you.
276 | *
277 | * @param {!string} name The name of the module to create or retrieve.
278 | * @param {!Array.=} requires If specified then new module is being created. If
279 | * unspecified then the module is being retrieved for further configuration.
280 | * @param {Function=} configFn Optional configuration function for the module. Same as
281 | * {@link angular.Module#config Module#config()}.
282 | * @returns {angular.Module} new module with the {@link angular.Module} api.
283 | */
284 | return function module(name, requires, configFn) {
285 |
286 | var info = {};
287 |
288 | var assertNotHasOwnProperty = function(name, context) {
289 | if (name === 'hasOwnProperty') {
290 | throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
291 | }
292 | };
293 |
294 | assertNotHasOwnProperty(name, 'module');
295 | if (requires && modules.hasOwnProperty(name)) {
296 | modules[name] = null;
297 | }
298 | return ensure(modules, name, function() {
299 | if (!requires) {
300 | throw $injectorMinErr('nomod', 'Module \'{0}\' is not available! You either misspelled ' +
301 | 'the module name or forgot to load it. If registering a module ensure that you ' +
302 | 'specify the dependencies as the second argument.', name);
303 | }
304 |
305 | /** @type {!Array.>} */
306 | var invokeQueue = [];
307 |
308 | /** @type {!Array.} */
309 | var configBlocks = [];
310 |
311 | /** @type {!Array.} */
312 | var runBlocks = [];
313 |
314 | var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
315 |
316 | /** @type {angular.Module} */
317 | var moduleInstance = {
318 | // Private state
319 | _invokeQueue: invokeQueue,
320 | _configBlocks: configBlocks,
321 | _runBlocks: runBlocks,
322 |
323 | /**
324 | * @ngdoc method
325 | * @name angular.Module#info
326 | * @module ng
327 | *
328 | * @param {Object=} info Information about the module
329 | * @returns {Object|Module} The current info object for this module if called as a getter,
330 | * or `this` if called as a setter.
331 | *
332 | * @description
333 | * Read and write custom information about this module.
334 | * For example you could put the version of the module in here.
335 | *
336 | * ```js
337 | * angular.module('myModule', []).info({ version: '1.0.0' });
338 | * ```
339 | *
340 | * The version could then be read back out by accessing the module elsewhere:
341 | *
342 | * ```
343 | * var version = angular.module('myModule').info().version;
344 | * ```
345 | *
346 | * You can also retrieve this information during runtime via the
347 | * {@link $injector#modules `$injector.modules`} property:
348 | *
349 | * ```js
350 | * var version = $injector.modules['myModule'].info().version;
351 | * ```
352 | */
353 | info: function(value) {
354 | if (isDefined(value)) {
355 | if (!isObject(value)) throw ngMinErr('aobj', 'Argument \'{0}\' must be an object', 'value');
356 | info = value;
357 | return this;
358 | }
359 | return info;
360 | },
361 |
362 | /**
363 | * @ngdoc property
364 | * @name angular.Module#requires
365 | * @module ng
366 | *
367 | * @description
368 | * Holds the list of modules which the injector will load before the current module is
369 | * loaded.
370 | */
371 | requires: requires,
372 |
373 | /**
374 | * @ngdoc property
375 | * @name angular.Module#name
376 | * @module ng
377 | *
378 | * @description
379 | * Name of the module.
380 | */
381 | name: name,
382 |
383 |
384 | /**
385 | * @ngdoc method
386 | * @name angular.Module#provider
387 | * @module ng
388 | * @param {string} name service name
389 | * @param {Function} providerType Construction function for creating new instance of the
390 | * service.
391 | * @description
392 | * See {@link auto.$provide#provider $provide.provider()}.
393 | */
394 | provider: invokeLaterAndSetModuleName('$provide', 'provider'),
395 |
396 | /**
397 | * @ngdoc method
398 | * @name angular.Module#factory
399 | * @module ng
400 | * @param {string} name service name
401 | * @param {Function} providerFunction Function for creating new instance of the service.
402 | * @description
403 | * See {@link auto.$provide#factory $provide.factory()}.
404 | */
405 | factory: invokeLaterAndSetModuleName('$provide', 'factory'),
406 |
407 | /**
408 | * @ngdoc method
409 | * @name angular.Module#service
410 | * @module ng
411 | * @param {string} name service name
412 | * @param {Function} constructor A constructor function that will be instantiated.
413 | * @description
414 | * See {@link auto.$provide#service $provide.service()}.
415 | */
416 | service: invokeLaterAndSetModuleName('$provide', 'service'),
417 |
418 | /**
419 | * @ngdoc method
420 | * @name angular.Module#value
421 | * @module ng
422 | * @param {string} name service name
423 | * @param {*} object Service instance object.
424 | * @description
425 | * See {@link auto.$provide#value $provide.value()}.
426 | */
427 | value: invokeLater('$provide', 'value'),
428 |
429 | /**
430 | * @ngdoc method
431 | * @name angular.Module#constant
432 | * @module ng
433 | * @param {string} name constant name
434 | * @param {*} object Constant value.
435 | * @description
436 | * Because the constants are fixed, they get applied before other provide methods.
437 | * See {@link auto.$provide#constant $provide.constant()}.
438 | */
439 | constant: invokeLater('$provide', 'constant', 'unshift'),
440 |
441 | /**
442 | * @ngdoc method
443 | * @name angular.Module#decorator
444 | * @module ng
445 | * @param {string} name The name of the service to decorate.
446 | * @param {Function} decorFn This function will be invoked when the service needs to be
447 | * instantiated and should return the decorated service instance.
448 | * @description
449 | * See {@link auto.$provide#decorator $provide.decorator()}.
450 | */
451 | decorator: invokeLaterAndSetModuleName('$provide', 'decorator', configBlocks),
452 |
453 | /**
454 | * @ngdoc method
455 | * @name angular.Module#animation
456 | * @module ng
457 | * @param {string} name animation name
458 | * @param {Function} animationFactory Factory function for creating new instance of an
459 | * animation.
460 | * @description
461 | *
462 | * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
463 | *
464 | *
465 | * Defines an animation hook that can be later used with
466 | * {@link $animate $animate} service and directives that use this service.
467 | *
468 | * ```js
469 | * module.animation('.animation-name', function($inject1, $inject2) {
470 | * return {
471 | * eventName : function(element, done) {
472 | * //code to run the animation
473 | * //once complete, then run done()
474 | * return function cancellationFunction(element) {
475 | * //code to cancel the animation
476 | * }
477 | * }
478 | * }
479 | * })
480 | * ```
481 | *
482 | * See {@link ng.$animateProvider#register $animateProvider.register()} and
483 | * {@link ngAnimate ngAnimate module} for more information.
484 | */
485 | animation: invokeLaterAndSetModuleName('$animateProvider', 'register'),
486 |
487 | /**
488 | * @ngdoc method
489 | * @name angular.Module#filter
490 | * @module ng
491 | * @param {string} name Filter name - this must be a valid AngularJS expression identifier
492 | * @param {Function} filterFactory Factory function for creating new instance of filter.
493 | * @description
494 | * See {@link ng.$filterProvider#register $filterProvider.register()}.
495 | *
496 | *
497 | * **Note:** Filter names must be valid AngularJS {@link expression} identifiers, such as `uppercase` or `orderBy`.
498 | * Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
499 | * your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
500 | * (`myapp_subsection_filterx`).
501 | *
502 | */
503 | filter: invokeLaterAndSetModuleName('$filterProvider', 'register'),
504 |
505 | /**
506 | * @ngdoc method
507 | * @name angular.Module#controller
508 | * @module ng
509 | * @param {string|Object} name Controller name, or an object map of controllers where the
510 | * keys are the names and the values are the constructors.
511 | * @param {Function} constructor Controller constructor function.
512 | * @description
513 | * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
514 | */
515 | controller: invokeLaterAndSetModuleName('$controllerProvider', 'register'),
516 |
517 | /**
518 | * @ngdoc method
519 | * @name angular.Module#directive
520 | * @module ng
521 | * @param {string|Object} name Directive name, or an object map of directives where the
522 | * keys are the names and the values are the factories.
523 | * @param {Function} directiveFactory Factory function for creating new instance of
524 | * directives.
525 | * @description
526 | * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
527 | */
528 | directive: invokeLaterAndSetModuleName('$compileProvider', 'directive'),
529 |
530 | /**
531 | * @ngdoc method
532 | * @name angular.Module#component
533 | * @module ng
534 | * @param {string|Object} name Name of the component in camelCase (i.e. `myComp` which will match ``),
535 | * or an object map of components where the keys are the names and the values are the component definition objects.
536 | * @param {Object} options Component definition object (a simplified
537 | * {@link ng.$compile#directive-definition-object directive definition object})
538 | *
539 | * @description
540 | * See {@link ng.$compileProvider#component $compileProvider.component()}.
541 | */
542 | component: invokeLaterAndSetModuleName('$compileProvider', 'component'),
543 |
544 | /**
545 | * @ngdoc method
546 | * @name angular.Module#config
547 | * @module ng
548 | * @param {Function} configFn Execute this function on module load. Useful for service
549 | * configuration.
550 | * @description
551 | * Use this method to configure services by injecting their
552 | * {@link angular.Module#provider `providers`}, e.g. for adding routes to the
553 | * {@link ngRoute.$routeProvider $routeProvider}.
554 | *
555 | * Note that you can only inject {@link angular.Module#provider `providers`} and
556 | * {@link angular.Module#constant `constants`} into this function.
557 | *
558 | * For more about how to configure services, see
559 | * {@link providers#provider-recipe Provider Recipe}.
560 | */
561 | config: config,
562 |
563 | /**
564 | * @ngdoc method
565 | * @name angular.Module#run
566 | * @module ng
567 | * @param {Function} initializationFn Execute this function after injector creation.
568 | * Useful for application initialization.
569 | * @description
570 | * Use this method to register work which should be performed when the injector is done
571 | * loading all modules.
572 | */
573 | run: function(block) {
574 | runBlocks.push(block);
575 | return this;
576 | }
577 | };
578 |
579 | if (configFn) {
580 | config(configFn);
581 | }
582 |
583 | return moduleInstance;
584 |
585 | /**
586 | * @param {string} provider
587 | * @param {string} method
588 | * @param {String=} insertMethod
589 | * @returns {angular.Module}
590 | */
591 | function invokeLater(provider, method, insertMethod, queue) {
592 | if (!queue) queue = invokeQueue;
593 | return function() {
594 | queue[insertMethod || 'push']([provider, method, arguments]);
595 | return moduleInstance;
596 | };
597 | }
598 |
599 | /**
600 | * @param {string} provider
601 | * @param {string} method
602 | * @returns {angular.Module}
603 | */
604 | function invokeLaterAndSetModuleName(provider, method, queue) {
605 | if (!queue) queue = invokeQueue;
606 | return function(recipeName, factoryFunction) {
607 | if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
608 | queue.push([provider, method, arguments]);
609 | return moduleInstance;
610 | };
611 | }
612 | });
613 | };
614 | });
615 |
616 | }
617 |
618 | setupModuleLoader(window);
619 | })(window);
620 |
621 | /**
622 | * Closure compiler type information
623 | *
624 | * @typedef { {
625 | * requires: !Array.,
626 | * invokeQueue: !Array.>,
627 | *
628 | * service: function(string, Function):angular.Module,
629 | * factory: function(string, Function):angular.Module,
630 | * value: function(string, *):angular.Module,
631 | *
632 | * filter: function(string, Function):angular.Module,
633 | *
634 | * init: function(Function):angular.Module
635 | * } }
636 | */
637 | angular.Module;
638 |
639 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/angular-messages.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.8.2
3 | * (c) 2010-2020 Google LLC. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular) {'use strict';
7 |
8 | var forEach;
9 | var isArray;
10 | var isString;
11 | var jqLite;
12 |
13 | /**
14 | * @ngdoc module
15 | * @name ngMessages
16 | * @description
17 | *
18 | * The `ngMessages` module provides enhanced support for displaying messages within templates
19 | * (typically within forms or when rendering message objects that return key/value data).
20 | * Instead of relying on JavaScript code and/or complex ng-if statements within your form template to
21 | * show and hide error messages specific to the state of an input field, the `ngMessages` and
22 | * `ngMessage` directives are designed to handle the complexity, inheritance and priority
23 | * sequencing based on the order of how the messages are defined in the template.
24 | *
25 | * Currently, the ngMessages module only contains the code for the `ngMessages`, `ngMessagesInclude`
26 | * `ngMessage`, `ngMessageExp` and `ngMessageDefault` directives.
27 | *
28 | * ## Usage
29 | * The `ngMessages` directive allows keys in a key/value collection to be associated with a child element
30 | * (or 'message') that will show or hide based on the truthiness of that key's value in the collection. A common use
31 | * case for `ngMessages` is to display error messages for inputs using the `$error` object exposed by the
32 | * {@link ngModel ngModel} directive.
33 | *
34 | * The child elements of the `ngMessages` directive are matched to the collection keys by a `ngMessage` or
35 | * `ngMessageExp` directive. The value of these attributes must match a key in the collection that is provided by
36 | * the `ngMessages` directive.
37 | *
38 | * Consider the following example, which illustrates a typical use case of `ngMessages`. Within the form `myForm` we
39 | * have a text input named `myField` which is bound to the scope variable `field` using the {@link ngModel ngModel}
40 | * directive.
41 | *
42 | * The `myField` field is a required input of type `email` with a maximum length of 15 characters.
43 | *
44 | * ```html
45 | *
56 | * ```
57 | *
58 | * In order to show error messages corresponding to `myField` we first create an element with an `ngMessages` attribute
59 | * set to the `$error` object owned by the `myField` input in our `myForm` form.
60 | *
61 | * Within this element we then create separate elements for each of the possible errors that `myField` could have.
62 | * The `ngMessage` attribute is used to declare which element(s) will appear for which error - for example,
63 | * setting `ng-message="required"` specifies that this particular element should be displayed when there
64 | * is no value present for the required field `myField` (because the key `required` will be `true` in the object
65 | * `myForm.myField.$error`).
66 | *
67 | * ### Message order
68 | *
69 | * By default, `ngMessages` will only display one message for a particular key/value collection at any time. If more
70 | * than one message (or error) key is currently true, then which message is shown is determined by the order of messages
71 | * in the HTML template code (messages declared first are prioritised). This mechanism means the developer does not have
72 | * to prioritize messages using custom JavaScript code.
73 | *
74 | * Given the following error object for our example (which informs us that the field `myField` currently has both the
75 | * `required` and `email` errors):
76 | *
77 | * ```javascript
78 | *
79 | * myField.$error = { required : true, email: true, maxlength: false };
80 | * ```
81 | * The `required` message will be displayed to the user since it appears before the `email` message in the DOM.
82 | * Once the user types a single character, the `required` message will disappear (since the field now has a value)
83 | * but the `email` message will be visible because it is still applicable.
84 | *
85 | * ### Displaying multiple messages at the same time
86 | *
87 | * While `ngMessages` will by default only display one error element at a time, the `ng-messages-multiple` attribute can
88 | * be applied to the `ngMessages` container element to cause it to display all applicable error messages at once:
89 | *
90 | * ```html
91 | *
92 | *
...
93 | *
94 | *
95 | * ...
96 | * ```
97 | *
98 | * ## Reusing and Overriding Messages
99 | * In addition to prioritization, ngMessages also allows for including messages from a remote or an inline
100 | * template. This allows for generic collection of messages to be reused across multiple parts of an
101 | * application.
102 | *
103 | * ```html
104 | *
108 | *
109 | *
110 | *
111 | *
112 | * ```
113 | *
114 | * However, including generic messages may not be useful enough to match all input fields, therefore,
115 | * `ngMessages` provides the ability to override messages defined in the remote template by redefining
116 | * them within the directive container.
117 | *
118 | * ```html
119 | *
120 | *
124 | *
125 | *
148 | * ```
149 | *
150 | * In the example HTML code above the message that is set on required will override the corresponding
151 | * required message defined within the remote template. Therefore, with particular input fields (such
152 | * email addresses, date fields, autocomplete inputs, etc...), specialized error messages can be applied
153 | * while more generic messages can be used to handle other, more general input errors.
154 | *
155 | * ## Dynamic Messaging
156 | * ngMessages also supports using expressions to dynamically change key values. Using arrays and
157 | * repeaters to list messages is also supported. This means that the code below will be able to
158 | * fully adapt itself and display the appropriate message when any of the expression data changes:
159 | *
160 | * ```html
161 | *
178 | * ```
179 | *
180 | * The `errorMessage.type` expression can be a string value or it can be an array so
181 | * that multiple errors can be associated with a single error message:
182 | *
183 | * ```html
184 | *
193 | *
194 | *
You did not enter your email address
195 | *
196 | * Your email must be between 5 and 100 characters long
197 | *
198 | *
199 | * ```
200 | *
201 | * Feel free to use other structural directives such as ng-if and ng-switch to further control
202 | * what messages are active and when. Be careful, if you place ng-message on the same element
203 | * as these structural directives, AngularJS may not be able to determine if a message is active
204 | * or not. Therefore it is best to place the ng-message on a child element of the structural
205 | * directive.
206 | *
207 | * ```html
208 | *
209 | *
210 | *
Please enter something
211 | *
212 | *
213 | * ```
214 | *
215 | * ## Animations
216 | * If the `ngAnimate` module is active within the application then the `ngMessages`, `ngMessage` and
217 | * `ngMessageExp` directives will trigger animations whenever any messages are added and removed from
218 | * the DOM by the `ngMessages` directive.
219 | *
220 | * Whenever the `ngMessages` directive contains one or more visible messages then the `.ng-active` CSS
221 | * class will be added to the element. The `.ng-inactive` CSS class will be applied when there are no
222 | * messages present. Therefore, CSS transitions and keyframes as well as JavaScript animations can
223 | * hook into the animations whenever these classes are added/removed.
224 | *
225 | * Let's say that our HTML code for our messages container looks like so:
226 | *
227 | * ```html
228 | *
229 | *
...
230 | *
...
231 | *
232 | * ```
233 | *
234 | * Then the CSS animation code for the message container looks like so:
235 | *
236 | * ```css
237 | * .my-messages {
238 | * transition:1s linear all;
239 | * }
240 | * .my-messages.ng-active {
241 | * // messages are visible
242 | * }
243 | * .my-messages.ng-inactive {
244 | * // messages are hidden
245 | * }
246 | * ```
247 | *
248 | * Whenever an inner message is attached (becomes visible) or removed (becomes hidden) then the enter
249 | * and leave animation is triggered for each particular element bound to the `ngMessage` directive.
250 | *
251 | * Therefore, the CSS code for the inner messages looks like so:
252 | *
253 | * ```css
254 | * .some-message {
255 | * transition:1s linear all;
256 | * }
257 | *
258 | * .some-message.ng-enter {}
259 | * .some-message.ng-enter.ng-enter-active {}
260 | *
261 | * .some-message.ng-leave {}
262 | * .some-message.ng-leave.ng-leave-active {}
263 | * ```
264 | *
265 | * {@link ngAnimate See the ngAnimate docs} to learn how to use JavaScript animations or to learn
266 | * more about ngAnimate.
267 | *
268 | * ## Displaying a default message
269 | * If the ngMessages renders no inner ngMessage directive (i.e. when none of the truthy
270 | * keys are matched by a defined message), then it will render a default message
271 | * using the {@link ngMessageDefault} directive.
272 | * Note that matched messages will always take precedence over unmatched messages. That means
273 | * the default message will not be displayed when another message is matched. This is also
274 | * true for `ng-messages-multiple`.
275 | *
276 | * ```html
277 | *
278 | *
This field is required
279 | *
This field is too short
280 | *
This field has an input error
281 | *
282 | * ```
283 | *
284 |
285 | */
286 | angular.module('ngMessages', [], function initAngularHelpers() {
287 | // Access helpers from AngularJS core.
288 | // Do it inside a `config` block to ensure `window.angular` is available.
289 | forEach = angular.forEach;
290 | isArray = angular.isArray;
291 | isString = angular.isString;
292 | jqLite = angular.element;
293 | })
294 | .info({ angularVersion: '1.8.2' })
295 |
296 | /**
297 | * @ngdoc directive
298 | * @module ngMessages
299 | * @name ngMessages
300 | * @restrict AE
301 | *
302 | * @description
303 | * `ngMessages` is a directive that is designed to show and hide messages based on the state
304 | * of a key/value object that it listens on. The directive itself complements error message
305 | * reporting with the `ngModel` $error object (which stores a key/value state of validation errors).
306 | *
307 | * `ngMessages` manages the state of internal messages within its container element. The internal
308 | * messages use the `ngMessage` directive and will be inserted/removed from the page depending
309 | * on if they're present within the key/value object. By default, only one message will be displayed
310 | * at a time and this depends on the prioritization of the messages within the template. (This can
311 | * be changed by using the `ng-messages-multiple` or `multiple` attribute on the directive container.)
312 | *
313 | * A remote template can also be used (With {@link ngMessagesInclude}) to promote message
314 | * reusability and messages can also be overridden.
315 | *
316 | * A default message can also be displayed when no `ngMessage` directive is inserted, using the
317 | * {@link ngMessageDefault} directive.
318 | *
319 | * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`.
320 | *
321 | * @usage
322 | * ```html
323 | *
324 | *
325 | * ...
326 | * ...
327 | * ...
328 | * ...
329 | *
330 | *
331 | *
332 | *
333 | * ...
334 | * ...
335 | * ...
336 | * ...
337 | *
338 | * ```
339 | *
340 | * @param {string} ngMessages an AngularJS expression evaluating to a key/value object
341 | * (this is typically the $error object on an ngModel instance).
342 | * @param {string=} ngMessagesMultiple|multiple when set, all messages will be displayed with true
343 | *
344 | * @example
345 | *
348 | *
349 | *
368 | *
369 | *
370 | * angular.module('ngMessagesExample', ['ngMessages']);
371 | *
372 | *
373 | */
374 | .directive('ngMessages', ['$animate', function($animate) {
375 | var ACTIVE_CLASS = 'ng-active';
376 | var INACTIVE_CLASS = 'ng-inactive';
377 |
378 | return {
379 | require: 'ngMessages',
380 | restrict: 'AE',
381 | controller: ['$element', '$scope', '$attrs', function NgMessagesCtrl($element, $scope, $attrs) {
382 | var ctrl = this;
383 | var latestKey = 0;
384 | var nextAttachId = 0;
385 |
386 | this.getAttachId = function getAttachId() { return nextAttachId++; };
387 |
388 | var messages = this.messages = {};
389 | var renderLater, cachedCollection;
390 |
391 | this.render = function(collection) {
392 | collection = collection || {};
393 |
394 | renderLater = false;
395 | cachedCollection = collection;
396 |
397 | // this is true if the attribute is empty or if the attribute value is truthy
398 | var multiple = isAttrTruthy($scope, $attrs.ngMessagesMultiple) ||
399 | isAttrTruthy($scope, $attrs.multiple);
400 |
401 | var unmatchedMessages = [];
402 | var matchedKeys = {};
403 | var truthyKeys = 0;
404 | var messageItem = ctrl.head;
405 | var messageFound = false;
406 | var totalMessages = 0;
407 |
408 | // we use != instead of !== to allow for both undefined and null values
409 | while (messageItem != null) {
410 | totalMessages++;
411 | var messageCtrl = messageItem.message;
412 |
413 | var messageUsed = false;
414 | if (!messageFound) {
415 | forEach(collection, function(value, key) {
416 | if (truthy(value) && !messageUsed) {
417 | truthyKeys++;
418 |
419 | if (messageCtrl.test(key)) {
420 | // this is to prevent the same error name from showing up twice
421 | if (matchedKeys[key]) return;
422 | matchedKeys[key] = true;
423 |
424 | messageUsed = true;
425 | messageCtrl.attach();
426 | }
427 | }
428 | });
429 | }
430 |
431 | if (messageUsed) {
432 | // unless we want to display multiple messages then we should
433 | // set a flag here to avoid displaying the next message in the list
434 | messageFound = !multiple;
435 | } else {
436 | unmatchedMessages.push(messageCtrl);
437 | }
438 |
439 | messageItem = messageItem.next;
440 | }
441 |
442 | forEach(unmatchedMessages, function(messageCtrl) {
443 | messageCtrl.detach();
444 | });
445 |
446 | var messageMatched = unmatchedMessages.length !== totalMessages;
447 | var attachDefault = ctrl.default && !messageMatched && truthyKeys > 0;
448 |
449 | if (attachDefault) {
450 | ctrl.default.attach();
451 | } else if (ctrl.default) {
452 | ctrl.default.detach();
453 | }
454 |
455 | if (messageMatched || attachDefault) {
456 | $animate.setClass($element, ACTIVE_CLASS, INACTIVE_CLASS);
457 | } else {
458 | $animate.setClass($element, INACTIVE_CLASS, ACTIVE_CLASS);
459 | }
460 | };
461 |
462 | $scope.$watchCollection($attrs.ngMessages || $attrs['for'], ctrl.render);
463 |
464 | this.reRender = function() {
465 | if (!renderLater) {
466 | renderLater = true;
467 | $scope.$evalAsync(function() {
468 | if (renderLater && cachedCollection) {
469 | ctrl.render(cachedCollection);
470 | }
471 | });
472 | }
473 | };
474 |
475 | this.register = function(comment, messageCtrl, isDefault) {
476 | if (isDefault) {
477 | ctrl.default = messageCtrl;
478 | } else {
479 | var nextKey = latestKey.toString();
480 | messages[nextKey] = {
481 | message: messageCtrl
482 | };
483 | insertMessageNode($element[0], comment, nextKey);
484 | comment.$$ngMessageNode = nextKey;
485 | latestKey++;
486 | }
487 |
488 | ctrl.reRender();
489 | };
490 |
491 | this.deregister = function(comment, isDefault) {
492 | if (isDefault) {
493 | delete ctrl.default;
494 | } else {
495 | var key = comment.$$ngMessageNode;
496 | delete comment.$$ngMessageNode;
497 | removeMessageNode($element[0], comment, key);
498 | delete messages[key];
499 | }
500 | ctrl.reRender();
501 | };
502 |
503 | function findPreviousMessage(parent, comment) {
504 | var prevNode = comment;
505 | var parentLookup = [];
506 |
507 | while (prevNode && prevNode !== parent) {
508 | var prevKey = prevNode.$$ngMessageNode;
509 | if (prevKey && prevKey.length) {
510 | return messages[prevKey];
511 | }
512 |
513 | // dive deeper into the DOM and examine its children for any ngMessage
514 | // comments that may be in an element that appears deeper in the list
515 | if (prevNode.childNodes.length && parentLookup.indexOf(prevNode) === -1) {
516 | parentLookup.push(prevNode);
517 | prevNode = prevNode.childNodes[prevNode.childNodes.length - 1];
518 | } else if (prevNode.previousSibling) {
519 | prevNode = prevNode.previousSibling;
520 | } else {
521 | prevNode = prevNode.parentNode;
522 | parentLookup.push(prevNode);
523 | }
524 | }
525 | }
526 |
527 | function insertMessageNode(parent, comment, key) {
528 | var messageNode = messages[key];
529 | if (!ctrl.head) {
530 | ctrl.head = messageNode;
531 | } else {
532 | var match = findPreviousMessage(parent, comment);
533 | if (match) {
534 | messageNode.next = match.next;
535 | match.next = messageNode;
536 | } else {
537 | messageNode.next = ctrl.head;
538 | ctrl.head = messageNode;
539 | }
540 | }
541 | }
542 |
543 | function removeMessageNode(parent, comment, key) {
544 | var messageNode = messages[key];
545 |
546 | // This message node may have already been removed by a call to deregister()
547 | if (!messageNode) return;
548 |
549 | var match = findPreviousMessage(parent, comment);
550 | if (match) {
551 | match.next = messageNode.next;
552 | } else {
553 | ctrl.head = messageNode.next;
554 | }
555 | }
556 | }]
557 | };
558 |
559 | function isAttrTruthy(scope, attr) {
560 | return (isString(attr) && attr.length === 0) || //empty attribute
561 | truthy(scope.$eval(attr));
562 | }
563 |
564 | function truthy(val) {
565 | return isString(val) ? val.length : !!val;
566 | }
567 | }])
568 |
569 | /**
570 | * @ngdoc directive
571 | * @name ngMessagesInclude
572 | * @restrict AE
573 | * @scope
574 | *
575 | * @description
576 | * `ngMessagesInclude` is a directive with the purpose to import existing ngMessage template
577 | * code from a remote template and place the downloaded template code into the exact spot
578 | * that the ngMessagesInclude directive is placed within the ngMessages container. This allows
579 | * for a series of pre-defined messages to be reused and also allows for the developer to
580 | * determine what messages are overridden due to the placement of the ngMessagesInclude directive.
581 | *
582 | * @usage
583 | * ```html
584 | *
585 | *
586 | * ...
587 | *
588 | *
589 | *
590 | *
591 | * ...
592 | *
593 | * ```
594 | *
595 | * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`.
596 | *
597 | * @param {string} ngMessagesInclude|src a string value corresponding to the remote template.
598 | */
599 | .directive('ngMessagesInclude',
600 | ['$templateRequest', '$document', '$compile', function($templateRequest, $document, $compile) {
601 |
602 | return {
603 | restrict: 'AE',
604 | require: '^^ngMessages', // we only require this for validation sake
605 | link: function($scope, element, attrs) {
606 | var src = attrs.ngMessagesInclude || attrs.src;
607 | $templateRequest(src).then(function(html) {
608 | if ($scope.$$destroyed) return;
609 |
610 | if (isString(html) && !html.trim()) {
611 | // Empty template - nothing to compile
612 | replaceElementWithMarker(element, src);
613 | } else {
614 | // Non-empty template - compile and link
615 | $compile(html)($scope, function(contents) {
616 | element.after(contents);
617 | replaceElementWithMarker(element, src);
618 | });
619 | }
620 | });
621 | }
622 | };
623 |
624 | // Helpers
625 | function replaceElementWithMarker(element, src) {
626 | // A comment marker is placed for debugging purposes
627 | var comment = $compile.$$createComment ?
628 | $compile.$$createComment('ngMessagesInclude', src) :
629 | $document[0].createComment(' ngMessagesInclude: ' + src + ' ');
630 | var marker = jqLite(comment);
631 | element.after(marker);
632 |
633 | // Don't pollute the DOM anymore by keeping an empty directive element
634 | element.remove();
635 | }
636 | }])
637 |
638 | /**
639 | * @ngdoc directive
640 | * @name ngMessage
641 | * @restrict AE
642 | * @scope
643 | * @priority 1
644 | *
645 | * @description
646 | * `ngMessage` is a directive with the purpose to show and hide a particular message.
647 | * For `ngMessage` to operate, a parent `ngMessages` directive on a parent DOM element
648 | * must be situated since it determines which messages are visible based on the state
649 | * of the provided key/value map that `ngMessages` listens on.
650 | *
651 | * More information about using `ngMessage` can be found in the
652 | * {@link module:ngMessages `ngMessages` module documentation}.
653 | *
654 | * @usage
655 | * ```html
656 | *
657 | *
658 | * ...
659 | * ...
660 | *
661 | *
662 | *
663 | *
664 | * ...
665 | * ...
666 | *
667 | * ```
668 | *
669 | * @param {expression} ngMessage|when a string value corresponding to the message key.
670 | */
671 | .directive('ngMessage', ngMessageDirectiveFactory())
672 |
673 |
674 | /**
675 | * @ngdoc directive
676 | * @name ngMessageExp
677 | * @restrict AE
678 | * @priority 1
679 | * @scope
680 | *
681 | * @description
682 | * `ngMessageExp` is the same as {@link directive:ngMessage `ngMessage`}, but instead of a static
683 | * value, it accepts an expression to be evaluated for the message key.
684 | *
685 | * @usage
686 | * ```html
687 | *
688 | *
689 | * ...
690 | *
691 | *
692 | *
693 | *
694 | * ...
695 | *
696 | * ```
697 | *
698 | * {@link module:ngMessages Click here} to learn more about `ngMessages` and `ngMessage`.
699 | *
700 | * @param {expression} ngMessageExp|whenExp an expression value corresponding to the message key.
701 | */
702 | .directive('ngMessageExp', ngMessageDirectiveFactory())
703 |
704 | /**
705 | * @ngdoc directive
706 | * @name ngMessageDefault
707 | * @restrict AE
708 | * @scope
709 | *
710 | * @description
711 | * `ngMessageDefault` is a directive with the purpose to show and hide a default message for
712 | * {@link directive:ngMessages}, when none of provided messages matches.
713 | *
714 | * More information about using `ngMessageDefault` can be found in the
715 | * {@link module:ngMessages `ngMessages` module documentation}.
716 | *
717 | * @usage
718 | * ```html
719 | *
720 | *
721 | * ...
722 | * ...
723 | * ...
724 | *
725 | *
726 | *
727 | *
728 | * ...
729 | * ...
730 | * ...
731 | *
732 | *
733 | */
734 | .directive('ngMessageDefault', ngMessageDirectiveFactory(true));
735 |
736 | function ngMessageDirectiveFactory(isDefault) {
737 | return ['$animate', function($animate) {
738 | return {
739 | restrict: 'AE',
740 | transclude: 'element',
741 | priority: 1, // must run before ngBind, otherwise the text is set on the comment
742 | terminal: true,
743 | require: '^^ngMessages',
744 | link: function(scope, element, attrs, ngMessagesCtrl, $transclude) {
745 | var commentNode, records, staticExp, dynamicExp;
746 |
747 | if (!isDefault) {
748 | commentNode = element[0];
749 | staticExp = attrs.ngMessage || attrs.when;
750 | dynamicExp = attrs.ngMessageExp || attrs.whenExp;
751 |
752 | var assignRecords = function(items) {
753 | records = items
754 | ? (isArray(items)
755 | ? items
756 | : items.split(/[\s,]+/))
757 | : null;
758 | ngMessagesCtrl.reRender();
759 | };
760 |
761 | if (dynamicExp) {
762 | assignRecords(scope.$eval(dynamicExp));
763 | scope.$watchCollection(dynamicExp, assignRecords);
764 | } else {
765 | assignRecords(staticExp);
766 | }
767 | }
768 |
769 | var currentElement, messageCtrl;
770 | ngMessagesCtrl.register(commentNode, messageCtrl = {
771 | test: function(name) {
772 | return contains(records, name);
773 | },
774 | attach: function() {
775 | if (!currentElement) {
776 | $transclude(function(elm, newScope) {
777 | $animate.enter(elm, null, element);
778 | currentElement = elm;
779 |
780 | // Each time we attach this node to a message we get a new id that we can match
781 | // when we are destroying the node later.
782 | var $$attachId = currentElement.$$attachId = ngMessagesCtrl.getAttachId();
783 |
784 | // in the event that the element or a parent element is destroyed
785 | // by another structural directive then it's time
786 | // to deregister the message from the controller
787 | currentElement.on('$destroy', function() {
788 | // If the message element was removed via a call to `detach` then `currentElement` will be null
789 | // So this handler only handles cases where something else removed the message element.
790 | if (currentElement && currentElement.$$attachId === $$attachId) {
791 | ngMessagesCtrl.deregister(commentNode, isDefault);
792 | messageCtrl.detach();
793 | }
794 | newScope.$destroy();
795 | });
796 | });
797 | }
798 | },
799 | detach: function() {
800 | if (currentElement) {
801 | var elm = currentElement;
802 | currentElement = null;
803 | $animate.leave(elm);
804 | }
805 | }
806 | }, isDefault);
807 |
808 | // We need to ensure that this directive deregisters itself when it no longer exists
809 | // Normally this is done when the attached element is destroyed; but if this directive
810 | // gets removed before we attach the message to the DOM there is nothing to watch
811 | // in which case we must deregister when the containing scope is destroyed.
812 | scope.$on('$destroy', function() {
813 | ngMessagesCtrl.deregister(commentNode, isDefault);
814 | });
815 | }
816 | };
817 | }];
818 |
819 | function contains(collection, key) {
820 | if (collection) {
821 | return isArray(collection)
822 | ? collection.indexOf(key) >= 0
823 | : collection.hasOwnProperty(key);
824 | }
825 | }
826 | }
827 |
828 |
829 | })(window, window.angular);
830 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/angular-sanitize.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.8.2
3 | * (c) 2010-2020 Google LLC. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular) {'use strict';
7 |
8 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
9 | * Any commits to this file should be reviewed with security in mind. *
10 | * Changes to this file can potentially create security vulnerabilities. *
11 | * An approval from 2 Core members with history of modifying *
12 | * this file is required. *
13 | * *
14 | * Does the change somehow allow for arbitrary javascript to be executed? *
15 | * Or allows for someone to change the prototype of built-in objects? *
16 | * Or gives undesired access to variables likes document or window? *
17 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
18 |
19 | var $sanitizeMinErr = angular.$$minErr('$sanitize');
20 | var bind;
21 | var extend;
22 | var forEach;
23 | var isArray;
24 | var isDefined;
25 | var lowercase;
26 | var noop;
27 | var nodeContains;
28 | var htmlParser;
29 | var htmlSanitizeWriter;
30 |
31 | /**
32 | * @ngdoc module
33 | * @name ngSanitize
34 | * @description
35 | *
36 | * The `ngSanitize` module provides functionality to sanitize HTML.
37 | *
38 | * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
39 | */
40 |
41 | /**
42 | * @ngdoc service
43 | * @name $sanitize
44 | * @kind function
45 | *
46 | * @description
47 | * Sanitizes an html string by stripping all potentially dangerous tokens.
48 | *
49 | * The input is sanitized by parsing the HTML into tokens. All safe tokens (from a trusted URI list) are
50 | * then serialized back to a properly escaped HTML string. This means that no unsafe input can make
51 | * it into the returned string.
52 | *
53 | * The trusted URIs for URL sanitization of attribute values is configured using the functions
54 | * `aHrefSanitizationTrustedUrlList` and `imgSrcSanitizationTrustedUrlList` of {@link $compileProvider}.
55 | *
56 | * The input may also contain SVG markup if this is enabled via {@link $sanitizeProvider}.
57 | *
58 | * @param {string} html HTML input.
59 | * @returns {string} Sanitized HTML.
60 | *
61 | * @example
62 |
63 |
64 |
76 |
77 | Snippet:
78 |
79 |
80 |
Directive
81 |
How
82 |
Source
83 |
Rendered
84 |
85 |
86 |
ng-bind-html
87 |
Automatically uses $sanitize
88 |
<div ng-bind-html="snippet"> </div>
89 |
90 |
91 |
92 |
ng-bind-html
93 |
Bypass $sanitize by explicitly trusting the dangerous value
By enabling this setting without taking other precautions, you might expose your
181 | * application to click-hijacking attacks. In these attacks, sanitized svg elements could be positioned
182 | * outside of the containing element and be rendered over other elements on the page (e.g. a login
183 | * link). Such behavior can then result in phishing incidents.
184 | *
185 | *
To protect against these, explicitly setup `overflow: hidden` css rule for all potential svg
186 | * tags within the sanitized content:
196 | *
197 | * @param {boolean=} flag Enable or disable SVG support in the sanitizer.
198 | * @returns {boolean|$sanitizeProvider} Returns the currently configured value if called
199 | * without an argument or self for chaining otherwise.
200 | */
201 | this.enableSvg = function(enableSvg) {
202 | if (isDefined(enableSvg)) {
203 | svgEnabled = enableSvg;
204 | return this;
205 | } else {
206 | return svgEnabled;
207 | }
208 | };
209 |
210 |
211 | /**
212 | * @ngdoc method
213 | * @name $sanitizeProvider#addValidElements
214 | * @kind function
215 | *
216 | * @description
217 | * Extends the built-in lists of valid HTML/SVG elements, i.e. elements that are considered safe
218 | * and are not stripped off during sanitization. You can extend the following lists of elements:
219 | *
220 | * - `htmlElements`: A list of elements (tag names) to extend the current list of safe HTML
221 | * elements. HTML elements considered safe will not be removed during sanitization. All other
222 | * elements will be stripped off.
223 | *
224 | * - `htmlVoidElements`: This is similar to `htmlElements`, but marks the elements as
225 | * "void elements" (similar to HTML
226 | * [void elements](https://rawgit.com/w3c/html/html5.1-2/single-page.html#void-elements)). These
227 | * elements have no end tag and cannot have content.
228 | *
229 | * - `svgElements`: This is similar to `htmlElements`, but for SVG elements. This list is only
230 | * taken into account if SVG is {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for
231 | * `$sanitize`.
232 | *
233 | *
234 | * This method must be called during the {@link angular.Module#config config} phase. Once the
235 | * `$sanitize` service has been instantiated, this method has no effect.
236 | *
237 | *
238 | *
239 | * Keep in mind that extending the built-in lists of elements may expose your app to XSS or
240 | * other vulnerabilities. Be very mindful of the elements you add.
241 | *
242 | *
243 | * @param {Array|Object} elements - A list of valid HTML elements or an object with one or
244 | * more of the following properties:
245 | * - **htmlElements** - `{Array}` - A list of elements to extend the current list of
246 | * HTML elements.
247 | * - **htmlVoidElements** - `{Array}` - A list of elements to extend the current list of
248 | * void HTML elements; i.e. elements that do not have an end tag.
249 | * - **svgElements** - `{Array}` - A list of elements to extend the current list of SVG
250 | * elements. The list of SVG elements is only taken into account if SVG is
251 | * {@link ngSanitize.$sanitizeProvider#enableSvg enabled} for `$sanitize`.
252 | *
253 | * Passing an array (`[...]`) is equivalent to passing `{htmlElements: [...]}`.
254 | *
255 | * @return {$sanitizeProvider} Returns self for chaining.
256 | */
257 | this.addValidElements = function(elements) {
258 | if (!hasBeenInstantiated) {
259 | if (isArray(elements)) {
260 | elements = {htmlElements: elements};
261 | }
262 |
263 | addElementsTo(svgElements, elements.svgElements);
264 | addElementsTo(voidElements, elements.htmlVoidElements);
265 | addElementsTo(validElements, elements.htmlVoidElements);
266 | addElementsTo(validElements, elements.htmlElements);
267 | }
268 |
269 | return this;
270 | };
271 |
272 |
273 | /**
274 | * @ngdoc method
275 | * @name $sanitizeProvider#addValidAttrs
276 | * @kind function
277 | *
278 | * @description
279 | * Extends the built-in list of valid attributes, i.e. attributes that are considered safe and are
280 | * not stripped off during sanitization.
281 | *
282 | * **Note**:
283 | * The new attributes will not be treated as URI attributes, which means their values will not be
284 | * sanitized as URIs using `$compileProvider`'s
285 | * {@link ng.$compileProvider#aHrefSanitizationTrustedUrlList aHrefSanitizationTrustedUrlList} and
286 | * {@link ng.$compileProvider#imgSrcSanitizationTrustedUrlList imgSrcSanitizationTrustedUrlList}.
287 | *
288 | *
289 | * This method must be called during the {@link angular.Module#config config} phase. Once the
290 | * `$sanitize` service has been instantiated, this method has no effect.
291 | *
292 | *
293 | *
294 | * Keep in mind that extending the built-in list of attributes may expose your app to XSS or
295 | * other vulnerabilities. Be very mindful of the attributes you add.
296 | *
297 | *
298 | * @param {Array} attrs - A list of valid attributes.
299 | *
300 | * @returns {$sanitizeProvider} Returns self for chaining.
301 | */
302 | this.addValidAttrs = function(attrs) {
303 | if (!hasBeenInstantiated) {
304 | extend(validAttrs, arrayToMap(attrs, true));
305 | }
306 | return this;
307 | };
308 |
309 | //////////////////////////////////////////////////////////////////////////////////////////////////
310 | // Private stuff
311 | //////////////////////////////////////////////////////////////////////////////////////////////////
312 |
313 | bind = angular.bind;
314 | extend = angular.extend;
315 | forEach = angular.forEach;
316 | isArray = angular.isArray;
317 | isDefined = angular.isDefined;
318 | lowercase = angular.$$lowercase;
319 | noop = angular.noop;
320 |
321 | htmlParser = htmlParserImpl;
322 | htmlSanitizeWriter = htmlSanitizeWriterImpl;
323 |
324 | nodeContains = window.Node.prototype.contains || /** @this */ function(arg) {
325 | // eslint-disable-next-line no-bitwise
326 | return !!(this.compareDocumentPosition(arg) & 16);
327 | };
328 |
329 | // Regular Expressions for parsing tags and attributes
330 | var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
331 | // Match everything outside of normal chars and " (quote character)
332 | NON_ALPHANUMERIC_REGEXP = /([^#-~ |!])/g;
333 |
334 |
335 | // Good source of info about elements and attributes
336 | // http://dev.w3.org/html5/spec/Overview.html#semantics
337 | // http://simon.html5.org/html-elements
338 |
339 | // Safe Void Elements - HTML5
340 | // http://dev.w3.org/html5/spec/Overview.html#void-elements
341 | var voidElements = stringToMap('area,br,col,hr,img,wbr');
342 |
343 | // Elements that you can, intentionally, leave open (and which close themselves)
344 | // http://dev.w3.org/html5/spec/Overview.html#optional-tags
345 | var optionalEndTagBlockElements = stringToMap('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr'),
346 | optionalEndTagInlineElements = stringToMap('rp,rt'),
347 | optionalEndTagElements = extend({},
348 | optionalEndTagInlineElements,
349 | optionalEndTagBlockElements);
350 |
351 | // Safe Block Elements - HTML5
352 | var blockElements = extend({}, optionalEndTagBlockElements, stringToMap('address,article,' +
353 | 'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
354 | 'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul'));
355 |
356 | // Inline Elements - HTML5
357 | var inlineElements = extend({}, optionalEndTagInlineElements, stringToMap('a,abbr,acronym,b,' +
358 | 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' +
359 | 'samp,small,span,strike,strong,sub,sup,time,tt,u,var'));
360 |
361 | // SVG Elements
362 | // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
363 | // Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted.
364 | // They can potentially allow for arbitrary javascript to be executed. See #11290
365 | var svgElements = stringToMap('circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
366 | 'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' +
367 | 'radialGradient,rect,stop,svg,switch,text,title,tspan');
368 |
369 | // Blocked Elements (will be stripped)
370 | var blockedElements = stringToMap('script,style');
371 |
372 | var validElements = extend({},
373 | voidElements,
374 | blockElements,
375 | inlineElements,
376 | optionalEndTagElements);
377 |
378 | //Attributes that have href and hence need to be sanitized
379 | var uriAttrs = stringToMap('background,cite,href,longdesc,src,xlink:href,xml:base');
380 |
381 | var htmlAttrs = stringToMap('abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
382 | 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
383 | 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
384 | 'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' +
385 | 'valign,value,vspace,width');
386 |
387 | // SVG attributes (without "id" and "name" attributes)
388 | // https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
389 | var svgAttrs = stringToMap('accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
390 | 'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' +
391 | 'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' +
392 | 'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' +
393 | 'height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,' +
394 | 'marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,' +
395 | 'max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,' +
396 | 'path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,' +
397 | 'requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,' +
398 | 'stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,' +
399 | 'stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,' +
400 | 'stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,' +
401 | 'underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,' +
402 | 'width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,' +
403 | 'xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan', true);
404 |
405 | var validAttrs = extend({},
406 | uriAttrs,
407 | svgAttrs,
408 | htmlAttrs);
409 |
410 | function stringToMap(str, lowercaseKeys) {
411 | return arrayToMap(str.split(','), lowercaseKeys);
412 | }
413 |
414 | function arrayToMap(items, lowercaseKeys) {
415 | var obj = {}, i;
416 | for (i = 0; i < items.length; i++) {
417 | obj[lowercaseKeys ? lowercase(items[i]) : items[i]] = true;
418 | }
419 | return obj;
420 | }
421 |
422 | function addElementsTo(elementsMap, newElements) {
423 | if (newElements && newElements.length) {
424 | extend(elementsMap, arrayToMap(newElements));
425 | }
426 | }
427 |
428 | /**
429 | * Create an inert document that contains the dirty HTML that needs sanitizing.
430 | * We use the DOMParser API by default and fall back to createHTMLDocument if DOMParser is not
431 | * available.
432 | */
433 | var getInertBodyElement /* function(html: string): HTMLBodyElement */ = (function(window, document) {
434 | if (isDOMParserAvailable()) {
435 | return getInertBodyElement_DOMParser;
436 | }
437 |
438 | if (!document || !document.implementation) {
439 | throw $sanitizeMinErr('noinert', 'Can\'t create an inert html document');
440 | }
441 | var inertDocument = document.implementation.createHTMLDocument('inert');
442 | var inertBodyElement = (inertDocument.documentElement || inertDocument.getDocumentElement()).querySelector('body');
443 | return getInertBodyElement_InertDocument;
444 |
445 | function isDOMParserAvailable() {
446 | try {
447 | return !!getInertBodyElement_DOMParser('');
448 | } catch (e) {
449 | return false;
450 | }
451 | }
452 |
453 | function getInertBodyElement_DOMParser(html) {
454 | // We add this dummy element to ensure that the rest of the content is parsed as expected
455 | // e.g. leading whitespace is maintained and tags like `` do not get hoisted to the `` tag.
456 | html = '' + html;
457 | try {
458 | var body = new window.DOMParser().parseFromString(html, 'text/html').body;
459 | body.firstChild.remove();
460 | return body;
461 | } catch (e) {
462 | return undefined;
463 | }
464 | }
465 |
466 | function getInertBodyElement_InertDocument(html) {
467 | inertBodyElement.innerHTML = html;
468 |
469 | // Support: IE 9-11 only
470 | // strip custom-namespaced attributes on IE<=11
471 | if (document.documentMode) {
472 | stripCustomNsAttrs(inertBodyElement);
473 | }
474 |
475 | return inertBodyElement;
476 | }
477 | })(window, window.document);
478 |
479 | /**
480 | * @example
481 | * htmlParser(htmlString, {
482 | * start: function(tag, attrs) {},
483 | * end: function(tag) {},
484 | * chars: function(text) {},
485 | * comment: function(text) {}
486 | * });
487 | *
488 | * @param {string} html string
489 | * @param {object} handler
490 | */
491 | function htmlParserImpl(html, handler) {
492 | if (html === null || html === undefined) {
493 | html = '';
494 | } else if (typeof html !== 'string') {
495 | html = '' + html;
496 | }
497 |
498 | var inertBodyElement = getInertBodyElement(html);
499 | if (!inertBodyElement) return '';
500 |
501 | //mXSS protection
502 | var mXSSAttempts = 5;
503 | do {
504 | if (mXSSAttempts === 0) {
505 | throw $sanitizeMinErr('uinput', 'Failed to sanitize html because the input is unstable');
506 | }
507 | mXSSAttempts--;
508 |
509 | // trigger mXSS if it is going to happen by reading and writing the innerHTML
510 | html = inertBodyElement.innerHTML;
511 | inertBodyElement = getInertBodyElement(html);
512 | } while (html !== inertBodyElement.innerHTML);
513 |
514 | var node = inertBodyElement.firstChild;
515 | while (node) {
516 | switch (node.nodeType) {
517 | case 1: // ELEMENT_NODE
518 | handler.start(node.nodeName.toLowerCase(), attrToMap(node.attributes));
519 | break;
520 | case 3: // TEXT NODE
521 | handler.chars(node.textContent);
522 | break;
523 | }
524 |
525 | var nextNode;
526 | if (!(nextNode = node.firstChild)) {
527 | if (node.nodeType === 1) {
528 | handler.end(node.nodeName.toLowerCase());
529 | }
530 | nextNode = getNonDescendant('nextSibling', node);
531 | if (!nextNode) {
532 | while (nextNode == null) {
533 | node = getNonDescendant('parentNode', node);
534 | if (node === inertBodyElement) break;
535 | nextNode = getNonDescendant('nextSibling', node);
536 | if (node.nodeType === 1) {
537 | handler.end(node.nodeName.toLowerCase());
538 | }
539 | }
540 | }
541 | }
542 | node = nextNode;
543 | }
544 |
545 | while ((node = inertBodyElement.firstChild)) {
546 | inertBodyElement.removeChild(node);
547 | }
548 | }
549 |
550 | function attrToMap(attrs) {
551 | var map = {};
552 | for (var i = 0, ii = attrs.length; i < ii; i++) {
553 | var attr = attrs[i];
554 | map[attr.name] = attr.value;
555 | }
556 | return map;
557 | }
558 |
559 |
560 | /**
561 | * Escapes all potentially dangerous characters, so that the
562 | * resulting string can be safely inserted into attribute or
563 | * element text.
564 | * @param value
565 | * @returns {string} escaped text
566 | */
567 | function encodeEntities(value) {
568 | return value.
569 | replace(/&/g, '&').
570 | replace(SURROGATE_PAIR_REGEXP, function(value) {
571 | var hi = value.charCodeAt(0);
572 | var low = value.charCodeAt(1);
573 | return '' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
574 | }).
575 | replace(NON_ALPHANUMERIC_REGEXP, function(value) {
576 | return '' + value.charCodeAt(0) + ';';
577 | }).
578 | replace(//g, '>');
580 | }
581 |
582 | /**
583 | * create an HTML/XML writer which writes to buffer
584 | * @param {Array} buf use buf.join('') to get out sanitized html string
585 | * @returns {object} in the form of {
586 | * start: function(tag, attrs) {},
587 | * end: function(tag) {},
588 | * chars: function(text) {},
589 | * comment: function(text) {}
590 | * }
591 | */
592 | function htmlSanitizeWriterImpl(buf, uriValidator) {
593 | var ignoreCurrentElement = false;
594 | var out = bind(buf, buf.push);
595 | return {
596 | start: function(tag, attrs) {
597 | tag = lowercase(tag);
598 | if (!ignoreCurrentElement && blockedElements[tag]) {
599 | ignoreCurrentElement = tag;
600 | }
601 | if (!ignoreCurrentElement && validElements[tag] === true) {
602 | out('<');
603 | out(tag);
604 | forEach(attrs, function(value, key) {
605 | var lkey = lowercase(key);
606 | var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
607 | if (validAttrs[lkey] === true &&
608 | (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
609 | out(' ');
610 | out(key);
611 | out('="');
612 | out(encodeEntities(value));
613 | out('"');
614 | }
615 | });
616 | out('>');
617 | }
618 | },
619 | end: function(tag) {
620 | tag = lowercase(tag);
621 | if (!ignoreCurrentElement && validElements[tag] === true && voidElements[tag] !== true) {
622 | out('');
623 | out(tag);
624 | out('>');
625 | }
626 | // eslint-disable-next-line eqeqeq
627 | if (tag == ignoreCurrentElement) {
628 | ignoreCurrentElement = false;
629 | }
630 | },
631 | chars: function(chars) {
632 | if (!ignoreCurrentElement) {
633 | out(encodeEntities(chars));
634 | }
635 | }
636 | };
637 | }
638 |
639 |
640 | /**
641 | * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1' attribute to declare
642 | * ns1 namespace and prefixes the attribute with 'ns1' (e.g. 'ns1:xlink:foo'). This is undesirable since we don't want
643 | * to allow any of these custom attributes. This method strips them all.
644 | *
645 | * @param node Root element to process
646 | */
647 | function stripCustomNsAttrs(node) {
648 | while (node) {
649 | if (node.nodeType === window.Node.ELEMENT_NODE) {
650 | var attrs = node.attributes;
651 | for (var i = 0, l = attrs.length; i < l; i++) {
652 | var attrNode = attrs[i];
653 | var attrName = attrNode.name.toLowerCase();
654 | if (attrName === 'xmlns:ns1' || attrName.lastIndexOf('ns1:', 0) === 0) {
655 | node.removeAttributeNode(attrNode);
656 | i--;
657 | l--;
658 | }
659 | }
660 | }
661 |
662 | var nextNode = node.firstChild;
663 | if (nextNode) {
664 | stripCustomNsAttrs(nextNode);
665 | }
666 |
667 | node = getNonDescendant('nextSibling', node);
668 | }
669 | }
670 |
671 | function getNonDescendant(propName, node) {
672 | // An element is clobbered if its `propName` property points to one of its descendants
673 | var nextNode = node[propName];
674 | if (nextNode && nodeContains.call(node, nextNode)) {
675 | throw $sanitizeMinErr('elclob', 'Failed to sanitize html because the element is clobbered: {0}', node.outerHTML || node.outerText);
676 | }
677 | return nextNode;
678 | }
679 | }
680 |
681 | function sanitizeText(chars) {
682 | var buf = [];
683 | var writer = htmlSanitizeWriter(buf, noop);
684 | writer.chars(chars);
685 | return buf.join('');
686 | }
687 |
688 |
689 | // define ngSanitize module and register $sanitize service
690 | angular.module('ngSanitize', [])
691 | .provider('$sanitize', $SanitizeProvider)
692 | .info({ angularVersion: '1.8.2' });
693 |
694 | /**
695 | * @ngdoc filter
696 | * @name linky
697 | * @kind function
698 | *
699 | * @description
700 | * Finds links in text input and turns them into html links. Supports `http/https/ftp/sftp/mailto` and
701 | * plain email address links.
702 | *
703 | * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
704 | *
705 | * @param {string} text Input text.
706 | * @param {string} [target] Window (`_blank|_self|_parent|_top`) or named frame to open links in.
707 | * @param {object|function(url)} [attributes] Add custom attributes to the link element.
708 | *
709 | * Can be one of:
710 | *
711 | * - `object`: A map of attributes
712 | * - `function`: Takes the url as a parameter and returns a map of attributes
713 | *
714 | * If the map of attributes contains a value for `target`, it overrides the value of
715 | * the target parameter.
716 | *
717 | *
718 | * @returns {string} Html-linkified and {@link $sanitize sanitized} text.
719 | *
720 | * @usage
721 |
722 | *
723 | * @example
724 |
725 |
726 |
767 |
768 |
769 | angular.module('linkyExample', ['ngSanitize'])
770 | .controller('ExampleController', ['$scope', function($scope) {
771 | $scope.snippet =
772 | 'Pretty text with some links:\n' +
773 | 'http://angularjs.org/,\n' +
774 | 'mailto:us@somewhere.org,\n' +
775 | 'another@somewhere.org,\n' +
776 | 'and one more: ftp://127.0.0.1/.';
777 | $scope.snippetWithSingleURL = 'http://angularjs.org/';
778 | }]);
779 |
780 |
781 | it('should linkify the snippet with urls', function() {
782 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
783 | toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
784 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
785 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
786 | });
787 |
788 | it('should not linkify snippet without the linky filter', function() {
789 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
790 | toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
791 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
792 | expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
793 | });
794 |
795 | it('should update', function() {
796 | element(by.model('snippet')).clear();
797 | element(by.model('snippet')).sendKeys('new http://link.');
798 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
799 | toBe('new http://link.');
800 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
801 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
802 | .toBe('new http://link.');
803 | });
804 |
805 | it('should work with the target property', function() {
806 | expect(element(by.id('linky-target')).
807 | element(by.binding("snippetWithSingleURL | linky:'_blank'")).getText()).
808 | toBe('http://angularjs.org/');
809 | expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
810 | });
811 |
812 | it('should optionally add custom attributes', function() {
813 | expect(element(by.id('linky-custom-attributes')).
814 | element(by.binding("snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}")).getText()).
815 | toBe('http://angularjs.org/');
816 | expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow');
817 | });
818 |
819 |
820 | */
821 | angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
822 | var LINKY_URL_REGEXP =
823 | /((s?ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/i,
824 | MAILTO_REGEXP = /^mailto:/i;
825 |
826 | var linkyMinErr = angular.$$minErr('linky');
827 | var isDefined = angular.isDefined;
828 | var isFunction = angular.isFunction;
829 | var isObject = angular.isObject;
830 | var isString = angular.isString;
831 |
832 | return function(text, target, attributes) {
833 | if (text == null || text === '') return text;
834 | if (!isString(text)) throw linkyMinErr('notstring', 'Expected string but received: {0}', text);
835 |
836 | var attributesFn =
837 | isFunction(attributes) ? attributes :
838 | isObject(attributes) ? function getAttributesObject() {return attributes;} :
839 | function getEmptyAttributesObject() {return {};};
840 |
841 | var match;
842 | var raw = text;
843 | var html = [];
844 | var url;
845 | var i;
846 | while ((match = raw.match(LINKY_URL_REGEXP))) {
847 | // We can not end in these as they are sometimes found at the end of the sentence
848 | url = match[0];
849 | // if we did not match ftp/http/www/mailto then assume mailto
850 | if (!match[2] && !match[4]) {
851 | url = (match[3] ? 'http://' : 'mailto:') + url;
852 | }
853 | i = match.index;
854 | addText(raw.substr(0, i));
855 | addLink(url, match[0].replace(MAILTO_REGEXP, ''));
856 | raw = raw.substring(i + match[0].length);
857 | }
858 | addText(raw);
859 | return $sanitize(html.join(''));
860 |
861 | function addText(text) {
862 | if (!text) {
863 | return;
864 | }
865 | html.push(sanitizeText(text));
866 | }
867 |
868 | function addLink(url, text) {
869 | var key, linkAttributes = attributesFn(url);
870 | html.push('');
884 | addText(text);
885 | html.push('');
886 | }
887 | };
888 | }]);
889 |
890 |
891 | })(window, window.angular);
892 |
--------------------------------------------------------------------------------
/xstatic/pkg/angular/data/angular-resource.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.8.2
3 | * (c) 2010-2020 Google LLC. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular) {'use strict';
7 |
8 | var $resourceMinErr = angular.$$minErr('$resource');
9 |
10 | // Helper functions and regex to lookup a dotted path on an object
11 | // stopping at undefined/null. The path must be composed of ASCII
12 | // identifiers (just like $parse)
13 | var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;
14 |
15 | function isValidDottedPath(path) {
16 | return (path != null && path !== '' && path !== 'hasOwnProperty' &&
17 | MEMBER_NAME_REGEX.test('.' + path));
18 | }
19 |
20 | function lookupDottedPath(obj, path) {
21 | if (!isValidDottedPath(path)) {
22 | throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path);
23 | }
24 | var keys = path.split('.');
25 | for (var i = 0, ii = keys.length; i < ii && angular.isDefined(obj); i++) {
26 | var key = keys[i];
27 | obj = (obj !== null) ? obj[key] : undefined;
28 | }
29 | return obj;
30 | }
31 |
32 | /**
33 | * Create a shallow copy of an object and clear other fields from the destination
34 | */
35 | function shallowClearAndCopy(src, dst) {
36 | dst = dst || {};
37 |
38 | angular.forEach(dst, function(value, key) {
39 | delete dst[key];
40 | });
41 |
42 | for (var key in src) {
43 | if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
44 | dst[key] = src[key];
45 | }
46 | }
47 |
48 | return dst;
49 | }
50 |
51 | /**
52 | * @ngdoc module
53 | * @name ngResource
54 | * @description
55 | *
56 | * The `ngResource` module provides interaction support with RESTful services
57 | * via the $resource service.
58 | *
59 | * See {@link ngResource.$resourceProvider} and {@link ngResource.$resource} for usage.
60 | */
61 |
62 | /**
63 | * @ngdoc provider
64 | * @name $resourceProvider
65 | *
66 | * @description
67 | *
68 | * Use `$resourceProvider` to change the default behavior of the {@link ngResource.$resource}
69 | * service.
70 | *
71 | * ## Dependencies
72 | * Requires the {@link ngResource } module to be installed.
73 | *
74 | */
75 |
76 | /**
77 | * @ngdoc service
78 | * @name $resource
79 | * @requires $http
80 | * @requires ng.$log
81 | * @requires $q
82 | * @requires ng.$timeout
83 | *
84 | * @description
85 | * A factory which creates a resource object that lets you interact with
86 | * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources.
87 | *
88 | * The returned resource object has action methods which provide high-level behaviors without
89 | * the need to interact with the low level {@link ng.$http $http} service.
90 | *
91 | * Requires the {@link ngResource `ngResource`} module to be installed.
92 | *
93 | * By default, trailing slashes will be stripped from the calculated URLs,
94 | * which can pose problems with server backends that do not expect that
95 | * behavior. This can be disabled by configuring the `$resourceProvider` like
96 | * this:
97 | *
98 | * ```js
99 | app.config(['$resourceProvider', function($resourceProvider) {
100 | // Don't strip trailing slashes from calculated URLs
101 | $resourceProvider.defaults.stripTrailingSlashes = false;
102 | }]);
103 | * ```
104 | *
105 | * @param {string} url A parameterized URL template with parameters prefixed by `:` as in
106 | * `/user/:username`. If you are using a URL with a port number (e.g.
107 | * `http://example.com:8080/api`), it will be respected.
108 | *
109 | * If you are using a url with a suffix, just add the suffix, like this:
110 | * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')`
111 | * or even `$resource('http://example.com/resource/:resource_id.:format')`
112 | * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be
113 | * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you
114 | * can escape it with `/\.`.
115 | *
116 | * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in
117 | * `actions` methods. If a parameter value is a function, it will be called every time
118 | * a param value needs to be obtained for a request (unless the param was overridden). The
119 | * function will be passed the current data value as an argument.
120 | *
121 | * Each key value in the parameter object is first bound to url template if present and then any
122 | * excess keys are appended to the url search query after the `?`.
123 | *
124 | * Given a template `/path/:verb` and parameter `{verb: 'greet', salutation: 'Hello'}` results in
125 | * URL `/path/greet?salutation=Hello`.
126 | *
127 | * If the parameter value is prefixed with `@`, then the value for that parameter will be
128 | * extracted from the corresponding property on the `data` object (provided when calling actions
129 | * with a request body).
130 | * For example, if the `defaultParam` object is `{someParam: '@someProp'}` then the value of
131 | * `someParam` will be `data.someProp`.
132 | * Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action
133 | * method that does not accept a request body).
134 | *
135 | * @param {Object.