diff --git a/dist/bundles/can/test/test.css b/dist/bundles/can/test/test.css new file mode 100644 index 0000000000..59c7e89ab6 --- /dev/null +++ b/dist/bundles/can/test/test.css @@ -0,0 +1,483 @@ +/*qunit@2.17.2#qunit/qunit.css!steal-css@1.3.2#css*/ +/*! + * QUnit 2.17.2 + * https://qunitjs.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + */ + +/** Font Family and Sizes */ + +/* Style our buttons in a simple way, uninfluenced by the styles + the tested app might load. Don't affect buttons in #qunit-fixture! + https://github.com/qunitjs/qunit/pull/1395 + https://github.com/qunitjs/qunit/issues/1437 */ +#qunit-testrunner-toolbar button, +#qunit-testresult button { + font-size: initial; + border: initial; + background-color: buttonface; +} + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult { + font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif; +} + +#qunit-testrunner-toolbar, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; } +#qunit-tests { font-size: smaller; } + + +/** Resets */ + +#qunit-tests, #qunit-header, #qunit-banner, #qunit-filteredTest, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter { + margin: 0; + padding: 0; +} + + +/** Fixed headers with scrollable tests */ + +@supports (display: flex) or (display: -webkit-box) { + @media (min-height: 500px) { + #qunit { + position: fixed; + left: 0px; + right: 0px; + top: 0px; + bottom: 0px; + padding: 8px; + display: -webkit-box; + display: flex; + flex-direction: column; + } + + #qunit-tests { + overflow: scroll; + } + + #qunit-banner { + flex: 5px 0 0; + } + } +} + + +/** Header (excluding toolbar) */ + +#qunit-header { + padding: 0.5em 0 0.5em 1em; + + color: #C2CCD1; + background-color: #0D3349; + + font-size: 1.5em; + line-height: 1em; + font-weight: 400; + + border-radius: 5px 5px 0 0; +} + +#qunit-header a { + text-decoration: none; + color: inherit; +} + +#qunit-header a:hover, +#qunit-header a:focus { + color: #FFF; +} + +#qunit-banner { + height: 5px; +} + +#qunit-filteredTest { + padding: 0.5em 1em 0.5em 1em; + color: #366097; + background-color: #F4FF77; +} + +#qunit-userAgent { + padding: 0.5em 1em 0.5em 1em; + color: #FFF; + background-color: #2B81AF; + text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px; +} + + +/** Toolbar */ + +#qunit-testrunner-toolbar { + padding: 0.5em 1em 0.5em 1em; + color: #5E740B; + background-color: #EEE; +} + +#qunit-testrunner-toolbar .clearfix { + height: 0; + clear: both; +} + +#qunit-testrunner-toolbar label { + display: inline-block; +} + +#qunit-testrunner-toolbar input[type=checkbox], +#qunit-testrunner-toolbar input[type=radio] { + margin: 3px; + vertical-align: -2px; +} + +#qunit-testrunner-toolbar input[type=text] { + box-sizing: border-box; + height: 1.6em; +} + +#qunit-toolbar-filters { + float: right; +} + +.qunit-url-config, +.qunit-filter, +#qunit-modulefilter { + display: inline-block; + line-height: 2.1em; +} + +.qunit-filter, +#qunit-modulefilter { + position: relative; + margin-left: 1em; +} + +.qunit-url-config label { + margin-right: 0.5em; +} + +#qunit-modulefilter-search { + box-sizing: border-box; + min-width: 400px; +} + +#qunit-modulefilter-search-container:after { + position: absolute; + right: 0.3em; + content: "\25bc"; + color: black; +} + +#qunit-modulefilter-dropdown { + /* align with #qunit-modulefilter-search */ + box-sizing: border-box; + min-width: 400px; + position: absolute; + right: 0; + top: 50%; + margin-top: 0.8em; + + border: 1px solid #D3D3D3; + border-top: none; + border-radius: 0 0 .25em .25em; + color: #0D3349; + background-color: #F5F5F5; + z-index: 99; +} + +#qunit-modulefilter-dropdown a { + color: inherit; + text-decoration: none; +} + +#qunit-modulefilter-dropdown .clickable.checked { + font-weight: bold; + color: #0D3349; + background-color: #E2F0F7; +} + +#qunit-modulefilter-dropdown .clickable:hover { + color: #FFF; + background-color: #0D3349; +} + +#qunit-modulefilter-actions { + display: block; + overflow: auto; + + /* align with #qunit-modulefilter-dropdown-list */ + font: smaller/1.5em sans-serif; +} + +#qunit-modulefilter-dropdown #qunit-modulefilter-actions > * { + box-sizing: border-box; + max-height: 2.8em; + display: block; + padding: 0.4em; +} + +#qunit-modulefilter-dropdown #qunit-modulefilter-actions > button { + float: right; + font: inherit; +} + +#qunit-modulefilter-dropdown #qunit-modulefilter-actions > :last-child { + /* insert padding to align with checkbox margins */ + padding-left: 3px; +} + +#qunit-modulefilter-dropdown-list { + max-height: 200px; + overflow-y: auto; + margin: 0; + border-top: 2px groove threedhighlight; + padding: 0.4em 0 0; + font: smaller/1.5em sans-serif; +} + +#qunit-modulefilter-dropdown-list li { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +#qunit-modulefilter-dropdown-list .clickable { + display: block; + padding-left: 0.15em; + padding-right: 0.5em; +} + + +/** Tests: Pass/Fail */ + +#qunit-tests { + list-style-position: inside; +} + +#qunit-tests li { + padding: 0.4em 1em 0.4em 1em; + border-bottom: 1px solid #FFF; + list-style-position: inside; +} + +#qunit-tests > li { + display: none; +} + +#qunit-tests li.running, +#qunit-tests li.pass, +#qunit-tests li.fail, +#qunit-tests li.skipped, +#qunit-tests li.aborted { + display: list-item; +} + +#qunit-tests.hidepass { + position: relative; +} + +#qunit-tests.hidepass li.running, +#qunit-tests.hidepass li.pass:not(.todo) { + visibility: hidden; + position: absolute; + width: 0; + height: 0; + padding: 0; + border: 0; + margin: 0; +} + +#qunit-tests li strong { + cursor: pointer; +} + +#qunit-tests li.skipped strong { + cursor: default; +} + +#qunit-tests li a { + padding: 0.5em; + color: inherit; + text-decoration: underline; +} +#qunit-tests li a:hover, +#qunit-tests li a:focus { + color: #0D3349; +} + +#qunit-tests li .runtime { + float: right; + font-size: smaller; +} + +.qunit-assert-list { + margin-top: 0.5em; + padding: 0.5em; + + background-color: #FFF; + + border-radius: 5px; +} + +.qunit-source { + margin: 0.6em 0 0.3em; +} + +.qunit-collapsed { + display: none; +} + +#qunit-tests table { + border-collapse: collapse; + margin-top: 0.2em; +} + +#qunit-tests th { + text-align: right; + vertical-align: top; + padding: 0 0.5em 0 0; +} + +#qunit-tests td { + vertical-align: top; +} + +#qunit-tests pre { + margin: 0; + white-space: pre-wrap; + word-wrap: break-word; +} + +#qunit-tests del { + color: #374E0C; + background-color: #E0F2BE; + text-decoration: none; +} + +#qunit-tests ins { + color: #500; + background-color: #FFCACA; + text-decoration: none; +} + +/*** Test Counts */ + +#qunit-tests b.counts { color: #0D3349; } +#qunit-tests b.passed { color: #5E740B; } +#qunit-tests b.failed { color: #710909; } + +#qunit-tests li li { + padding: 5px; + background-color: #FFF; + border-bottom: none; + list-style-position: inside; +} + +/*** Passing Styles */ + + +#qunit-tests .pass { + color: #2F68DA; + background-color: #E2F0F7; +} + +#qunit-tests .pass .test-name { + color: #366097; +} + +#qunit-tests li li.pass { + color: #3C510C; + background-color: #FFF; + border-left: 10px solid #C6E746; +} + +#qunit-tests .pass .test-actual, +#qunit-tests .pass .test-expected { color: #999; } + +#qunit-banner.qunit-pass { background-color: #C6E746; } + +/*** Failing Styles */ + +#qunit-tests .fail { + color: #000; + background-color: #EE5757; +} + +#qunit-tests li li.fail { + color: #710909; + background-color: #FFF; + border-left: 10px solid #EE5757; + white-space: pre; +} + +#qunit-tests > li:last-child { + border-radius: 0 0 5px 5px; +} + +#qunit-tests .fail .test-actual { color: #EE5757; } +#qunit-tests .fail .test-expected { color: #008000; } + +#qunit-banner.qunit-fail { background-color: #EE5757; } + + +/*** Aborted tests */ +#qunit-tests .aborted { color: #000; background-color: orange; } +/*** Skipped tests */ + +#qunit-tests .skipped { + background-color: #EBECE9; +} + +#qunit-tests .qunit-todo-label, +#qunit-tests .qunit-skipped-label { + background-color: #F4FF77; + display: inline-block; + font-style: normal; + color: #366097; + line-height: 1.8em; + padding: 0 0.5em; + margin: -0.4em 0.4em -0.4em 0; +} + +#qunit-tests .qunit-todo-label { + background-color: #EEE; +} + +/** Result */ + +#qunit-testresult { + color: #366097; + background-color: #E2F0F7; + + border-bottom: 1px solid #FFF; +} +#qunit-testresult a { + color: #2F68DA; +} +#qunit-testresult .clearfix { + height: 0; + clear: both; +} +#qunit-testresult .module-name { + font-weight: 700; +} +#qunit-testresult-display { + padding: 0.5em 1em 0.5em 1em; + width: 85%; + float:left; +} +#qunit-testresult-controls { + padding: 0.5em 1em 0.5em 1em; + width: 10%; + float:left; +} + +/** Fixture */ + +#qunit-fixture { + position: absolute; + top: -10000px; + left: -10000px; + width: 1000px; + height: 1000px; +} diff --git a/dist/bundles/can/test/test.js b/dist/bundles/can/test/test.js new file mode 100644 index 0000000000..1afa9c120f --- /dev/null +++ b/dist/bundles/can/test/test.js @@ -0,0 +1,107427 @@ +/*[system-bundles-config]*/ +System.bundles = {"bundles/can/test/test.css!":["qunit@2.17.2#qunit/qunit.css!steal-css@1.3.2#css"]}; +/*npm-utils*/ +define('npm-utils', function (require, exports, module) { + (function (global, require, exports, module) { + var slice = Array.prototype.slice; + var npmModuleRegEx = /.+@.+\..+\..+#.+/; + var conditionalModuleRegEx = /#\{[^\}]+\}|#\?.+$/; + var gitUrlEx = /(git|http(s?)):\/\//; + var supportsSet = typeof Set === 'function'; + var utils = { + extend: function (d, s, deep, existingSet) { + var val; + var set = existingSet; + if (deep) { + if (!set) { + if (supportsSet) { + set = new Set(); + } else { + set = []; + } + } + if (supportsSet) { + if (set.has(s)) { + return s; + } else { + set.add(s); + } + } else { + if (set.indexOf(s) !== -1) { + return s; + } else { + set.push(s); + } + } + } + for (var prop in s) { + val = s[prop]; + if (deep) { + if (utils.isArray(val)) { + d[prop] = slice.call(val); + } else if (utils.isPlainObject(val)) { + d[prop] = utils.extend({}, val, deep, set); + } else { + d[prop] = s[prop]; + } + } else { + d[prop] = s[prop]; + } + } + return d; + }, + map: function (arr, fn) { + var i = 0, len = arr.length, out = []; + for (; i < len; i++) { + out.push(fn.call(arr, arr[i])); + } + return out; + }, + filter: function (arr, fn) { + var i = 0, len = arr.length, out = [], res; + for (; i < len; i++) { + res = fn.call(arr, arr[i]); + if (res) { + out.push(arr[i]); + } + } + return out; + }, + forEach: function (arr, fn) { + var i = 0, len = arr.length; + for (; i < len; i++) { + fn.call(arr, arr[i], i); + } + }, + flow: function (fns) { + return function () { + var res = fns[0].apply(this, arguments); + for (var i = 1; i < fns.length; i++) { + res = fns[i].call(this, res); + } + return res; + }; + }, + isObject: function (obj) { + return typeof obj === 'object'; + }, + isPlainObject: function (obj) { + return utils.isObject(obj) && (!obj || obj.__proto__ === Object.prototype); + }, + isArray: Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) === '[object Array]'; + }, + isEnv: function (name) { + return this.isEnv ? this.isEnv(name) : this.env === name; + }, + isGitUrl: function (str) { + return gitUrlEx.test(str); + }, + warnOnce: function (msg) { + var w = this._warnings = this._warnings || {}; + if (w[msg]) + return; + w[msg] = true; + this.warn(msg); + }, + warn: function (msg) { + if (typeof steal !== 'undefined' && typeof console !== 'undefined' && console.warn) { + steal.done().then(function () { + if (steal.dev && steal.dev.warn) { + } else if (console.warn) { + console.warn('steal.js WARNING: ' + msg); + } else { + console.log(msg); + } + }); + } + }, + relativeURI: function (baseURL, url) { + return typeof steal !== 'undefined' ? steal.relativeURI(baseURL, url) : url; + }, + moduleName: { + create: function (descriptor, standard) { + if (standard) { + return descriptor.moduleName; + } else { + if (descriptor === '@empty') { + return descriptor; + } + var modulePath; + if (descriptor.modulePath) { + modulePath = descriptor.modulePath.substr(0, 2) === './' ? descriptor.modulePath.substr(2) : descriptor.modulePath; + } + var version = descriptor.version; + if (version && version[0] !== '^') { + version = encodeURIComponent(decodeURIComponent(version)); + } + return descriptor.packageName + (version ? '@' + version : '') + (modulePath ? '#' + modulePath : '') + (descriptor.plugin ? descriptor.plugin : ''); + } + }, + isNpm: function (moduleName) { + return npmModuleRegEx.test(moduleName); + }, + isConditional: function (moduleName) { + return conditionalModuleRegEx.test(moduleName); + }, + isFullyConvertedNpm: function (parsedModuleName) { + return !!(parsedModuleName.packageName && parsedModuleName.version && parsedModuleName.modulePath); + }, + isScoped: function (moduleName) { + return moduleName[0] === '@'; + }, + parse: function (moduleName, currentPackageName, global, context) { + var pluginParts = moduleName.split('!'); + var modulePathParts = pluginParts[0].split('#'); + var versionParts = modulePathParts[0].split('@'); + if (!modulePathParts[1] && !versionParts[0]) { + versionParts = ['@' + versionParts[1]]; + } + if (versionParts.length === 3 && utils.moduleName.isScoped(moduleName)) { + versionParts.splice(0, 1); + versionParts[0] = '@' + versionParts[0]; + } + var packageName, modulePath; + if (currentPackageName && utils.path.isRelative(moduleName)) { + packageName = currentPackageName; + modulePath = versionParts[0]; + } else if (currentPackageName && utils.path.isInHomeDir(moduleName, context)) { + packageName = currentPackageName; + modulePath = versionParts[0].split('/').slice(1).join('/'); + } else { + if (modulePathParts[1]) { + packageName = versionParts[0]; + modulePath = modulePathParts[1]; + } else { + var folderParts = versionParts[0].split('/'); + if (folderParts.length && folderParts[0][0] === '@') { + packageName = folderParts.splice(0, 2).join('/'); + } else { + packageName = folderParts.shift(); + } + modulePath = folderParts.join('/'); + } + } + modulePath = utils.path.removeJS(modulePath); + return { + plugin: pluginParts.length === 2 ? '!' + pluginParts[1] : undefined, + version: versionParts[1], + modulePath: modulePath, + packageName: packageName, + moduleName: moduleName, + isGlobal: global + }; + }, + parseFromPackage: function (loader, refPkg, name, parentName) { + var packageName = utils.pkg.name(refPkg), parsedModuleName = utils.moduleName.parse(name, packageName, undefined, { loader: loader }), isRelative = utils.path.isRelative(parsedModuleName.modulePath); + if (isRelative && !parentName) { + throw new Error('Cannot resolve a relative module identifier ' + 'with no parent module:', name); + } + if (isRelative) { + var parentParsed = utils.moduleName.parse(parentName, packageName); + if (parentParsed.packageName === parsedModuleName.packageName && parentParsed.modulePath) { + var makePathRelative = true; + if (name === '../' || name === './' || name === '..') { + var relativePath = utils.path.relativeTo(parentParsed.modulePath, name); + var isInRoot = utils.path.isPackageRootDir(relativePath); + if (isInRoot) { + parsedModuleName.modulePath = utils.pkg.main(refPkg); + makePathRelative = false; + } else { + parsedModuleName.modulePath = name + (utils.path.endsWithSlash(name) ? '' : '/') + 'index'; + } + } + if (makePathRelative) { + parsedModuleName.modulePath = utils.path.makeRelative(utils.path.joinURIs(parentParsed.modulePath, parsedModuleName.modulePath)); + } + } + } + var mapName = utils.moduleName.create(parsedModuleName), refSteal = utils.pkg.config(refPkg), mappedName; + if (refPkg.browser && typeof refPkg.browser !== 'string' && mapName in refPkg.browser && (!refSteal || !refSteal.ignoreBrowser)) { + mappedName = refPkg.browser[mapName] === false ? '@empty' : refPkg.browser[mapName]; + } + var global = loader && loader.globalBrowser && loader.globalBrowser[mapName]; + if (global) { + mappedName = global.moduleName === false ? '@empty' : global.moduleName; + } + if (mappedName) { + return utils.moduleName.parse(mappedName, packageName, !!global); + } else { + return parsedModuleName; + } + }, + nameAndVersion: function (parsedModuleName) { + return parsedModuleName.packageName + '@' + parsedModuleName.version; + }, + isBareIdentifier: function (identifier) { + return identifier && identifier[0] !== '.' && identifier[0] !== '@'; + } + }, + pkg: { + name: function (pkg) { + var steal = utils.pkg.config(pkg); + return steal && steal.name || pkg.name; + }, + main: function (pkg) { + var main; + var steal = utils.pkg.config(pkg); + if (steal && steal.main) { + main = steal.main; + } else if (typeof pkg.browser === 'string') { + if (utils.path.endsWithSlash(pkg.browser)) { + main = pkg.browser + 'index'; + } else { + main = pkg.browser; + } + } else if (typeof pkg.jam === 'object' && pkg.jam.main) { + main = pkg.jam.main; + } else if (pkg.main) { + if (utils.path.endsWithSlash(pkg.main)) { + main = pkg.main + 'index'; + } else { + main = pkg.main; + } + } else { + main = 'index'; + } + return utils.path.removeJS(utils.path.removeDotSlash(main)); + }, + rootDir: function (pkg, isRoot) { + var root = isRoot ? utils.path.removePackage(pkg.fileUrl) : utils.path.pkgDir(pkg.fileUrl); + var lib = utils.pkg.directoriesLib(pkg); + if (lib) { + root = utils.path.joinURIs(utils.path.addEndingSlash(root), lib); + } + return root; + }, + isRoot: function (loader, pkg) { + var root = utils.pkg.getDefault(loader); + return pkg && pkg.name === root.name && pkg.version === root.version; + }, + homeAlias: function (context) { + return context && context.loader && context.loader.homeAlias || '~'; + }, + getDefault: function (loader) { + return loader.npmPaths.__default; + }, + findByModuleNameOrAddress: function (loader, moduleName, moduleAddress) { + if (loader.npm) { + if (moduleName) { + var parsed = utils.moduleName.parse(moduleName); + if (parsed.version && parsed.packageName) { + var name = parsed.packageName + '@' + parsed.version; + if (name in loader.npm) { + return loader.npm[name]; + } + } + } + if (moduleAddress) { + var startingAddress = utils.relativeURI(loader.baseURL, moduleAddress); + var packageFolder = utils.pkg.folderAddress(startingAddress); + return packageFolder ? loader.npmPaths[packageFolder] : utils.pkg.getDefault(loader); + } else { + return utils.pkg.getDefault(loader); + } + } + }, + folderAddress: function (address) { + var nodeModules = '/node_modules/', nodeModulesIndex = address.lastIndexOf(nodeModules), nextSlash = address.indexOf('/', nodeModulesIndex + nodeModules.length); + if (nodeModulesIndex >= 0) { + return nextSlash >= 0 ? address.substr(0, nextSlash) : address; + } + }, + findDep: function (loader, refPkg, name) { + if (loader.npm && refPkg && !utils.path.startsWithDotSlash(name)) { + var nameAndVersion = name + '@' + refPkg.resolutions[name]; + var pkg = loader.npm[nameAndVersion]; + return pkg; + } + }, + findDepWalking: function (loader, refPackage, name) { + if (loader.npm && refPackage && !utils.path.startsWithDotSlash(name)) { + var curPackage = utils.path.depPackageDir(refPackage.fileUrl, name); + while (curPackage) { + var pkg = loader.npmPaths[curPackage]; + if (pkg) { + return pkg; + } + var parentAddress = utils.path.parentNodeModuleAddress(curPackage); + if (!parentAddress) { + return; + } + curPackage = parentAddress + '/' + name; + } + } + }, + findByName: function (loader, name) { + if (loader.npm && !utils.path.startsWithDotSlash(name)) { + return loader.npm[name]; + } + }, + findByNameAndVersion: function (loader, name, version) { + if (loader.npm && !utils.path.startsWithDotSlash(name)) { + var nameAndVersion = name + '@' + version; + return loader.npm[nameAndVersion]; + } + }, + findByUrl: function (loader, url) { + if (loader.npm) { + var fullUrl = utils.pkg.folderAddress(url); + return loader.npmPaths[fullUrl]; + } + }, + directoriesLib: function (pkg) { + var steal = utils.pkg.config(pkg); + var lib = steal && steal.directories && steal.directories.lib; + var ignores = [ + '.', + '/' + ], ignore; + if (!lib) + return undefined; + while (!!(ignore = ignores.shift())) { + if (lib[0] === ignore) { + lib = lib.substr(1); + } + } + return lib; + }, + hasDirectoriesLib: function (pkg) { + var steal = utils.pkg.config(pkg); + return steal && steal.directories && !!steal.directories.lib; + }, + findPackageInfo: function (context, pkg) { + var pkgInfo = context.pkgInfo; + if (pkgInfo) { + var out; + utils.forEach(pkgInfo, function (p) { + if (pkg.name === p.name && pkg.version === p.version) { + out = p; + } + }); + return out; + } + }, + saveResolution: function (context, refPkg, pkg) { + var npmPkg = utils.pkg.findPackageInfo(context, refPkg); + npmPkg.resolutions[pkg.name] = refPkg.resolutions[pkg.name] = pkg.version; + }, + config: function (pkg) { + return pkg.steal || pkg.system; + } + }, + path: { + makeRelative: function (path) { + if (utils.path.isRelative(path) && path.substr(0, 1) !== '/') { + return path; + } else { + return './' + path; + } + }, + removeJS: function (path) { + return path.replace(/\.js(!|$)/, function (whole, part) { + return part; + }); + }, + removePackage: function (path) { + return path.replace(/\/package\.json.*/, ''); + }, + addJS: function (path) { + if (/\.m?js(on)?$/.test(path)) { + return path; + } else { + return path + '.js'; + } + }, + isRelative: function (path) { + return path.substr(0, 1) === '.'; + }, + isInHomeDir: function (path, context) { + return path.substr(0, 2) === utils.pkg.homeAlias(context) + '/'; + }, + joinURIs: function (baseUri, rel) { + function removeDotSegments(input) { + var output = []; + input.replace(/^(\.\.?(\/|$))+/, '').replace(/\/(\.(\/|$))+/g, '/').replace(/\/\.\.$/, '/../').replace(/\/?[^\/]*/g, function (p) { + if (p === '/..') { + output.pop(); + } else { + output.push(p); + } + }); + return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); + } + var href = parseURI(rel || ''); + var base = parseURI(baseUri || ''); + return !href || !base ? null : (href.protocol || base.protocol) + (href.protocol || href.authority ? href.authority : base.authority) + removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : href.pathname ? (base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname : base.pathname) + (href.protocol || href.authority || href.pathname ? href.search : href.search || base.search) + href.hash; + }, + startsWithDotSlash: function (path) { + return path.substr(0, 2) === './'; + }, + removeDotSlash: function (path) { + return utils.path.startsWithDotSlash(path) ? path.substr(2) : path; + }, + endsWithSlash: function (path) { + return path[path.length - 1] === '/'; + }, + addEndingSlash: function (path) { + return utils.path.endsWithSlash(path) ? path : path + '/'; + }, + depPackage: function (parentPackageAddress, childName) { + var packageFolderName = parentPackageAddress.replace(/\/package\.json.*/, ''); + return (packageFolderName ? packageFolderName + '/' : '') + 'node_modules/' + childName + '/package.json'; + }, + peerPackage: function (parentPackageAddress, childName) { + var packageFolderName = parentPackageAddress.replace(/\/package\.json.*/, ''); + return packageFolderName.substr(0, packageFolderName.lastIndexOf('/')) + '/' + childName + '/package.json'; + }, + depPackageDir: function (parentPackageAddress, childName) { + return utils.path.depPackage(parentPackageAddress, childName).replace(/\/package\.json.*/, ''); + }, + peerNodeModuleAddress: function (address) { + var nodeModules = '/node_modules/', nodeModulesIndex = address.lastIndexOf(nodeModules); + if (nodeModulesIndex >= 0) { + return address.substr(0, nodeModulesIndex + nodeModules.length - 1); + } + }, + parentNodeModuleAddress: function (address) { + var nodeModules = '/node_modules/', nodeModulesIndex = address.lastIndexOf(nodeModules), prevModulesIndex = address.lastIndexOf(nodeModules, nodeModulesIndex - 1); + if (prevModulesIndex >= 0) { + return address.substr(0, prevModulesIndex + nodeModules.length - 1); + } + }, + pkgDir: function (address) { + var nodeModules = '/node_modules/', nodeModulesIndex = address.lastIndexOf(nodeModules), nextSlash = address.indexOf('/', nodeModulesIndex + nodeModules.length); + if (address[nodeModulesIndex + nodeModules.length] === '@') { + nextSlash = address.indexOf('/', nextSlash + 1); + } + if (nodeModulesIndex >= 0) { + return nextSlash >= 0 ? address.substr(0, nextSlash) : address; + } + }, + basename: function (address) { + var parts = address.split('/'); + return parts[parts.length - 1]; + }, + relativeTo: function (modulePath, rel) { + var parts = modulePath.split('/'); + var idx = 1; + while (rel[idx] === '.') { + parts.pop(); + idx++; + } + return parts.join('/'); + }, + isPackageRootDir: function (pth) { + return pth.indexOf('/') === -1; + } + }, + json: { + transform: function (loader, load, data) { + data.steal = utils.pkg.config(data); + var fn = loader.jsonOptions && loader.jsonOptions.transform; + if (!fn) + return data; + return fn.call(loader, load, data); + } + }, + includeInBuild: true + }; + function parseURI(url) { + var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@\/]*(?::[^:@\/]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); + return m ? { + href: m[0] || '', + protocol: m[1] || '', + authority: m[2] || '', + host: m[3] || '', + hostname: m[4] || '', + port: m[5] || '', + pathname: m[6] || '', + search: m[7] || '', + hash: m[8] || '' + } : null; + } + module.exports = utils; + }(function () { + return this; + }(), require, exports, module)); +}); +/*npm-extension*/ +define('npm-extension', [ + 'require', + 'exports', + 'module', + '@steal', + './npm-utils' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'format cjs'; + var steal = require('@steal'); + var utils = require('./npm-utils'); + exports.includeInBuild = true; + var isNode = typeof process === 'object' && {}.toString.call(process) === '[object process]'; + var isWorker = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope; + var isElectron = isNode && !!process.versions.electron; + var isBrowser = typeof window !== 'undefined' && (!isNode || isElectron) && !isWorker; + exports.addExtension = function addNpmExtension(System) { + if (System._extensions) { + System._extensions.push(addNpmExtension); + } + var oldNormalize = System.normalize; + System.normalize = function (identifier, parentModuleName, parentAddress, pluginNormalize) { + var name = identifier; + var parentName = parentModuleName; + if (parentName && this.npmParentMap && this.npmParentMap[parentName]) { + parentName = this.npmParentMap[parentName]; + } + var hasNoParent = !parentName; + var nameIsRelative = utils.path.isRelative(name); + var nameIsNpmModule = utils.moduleName.isNpm(name); + var parentIsNpmModule = utils.moduleName.isNpm(parentName); + var identifierEndsWithSlash = utils.path.endsWithSlash(name); + if (nameIsNpmModule && parentModuleName) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + if (parentName && nameIsRelative && !parentIsNpmModule) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + if (utils.moduleName.isConditional(name)) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + var hasContextualMap = typeof this.map[parentName] === 'object' && this.map[parentName][name]; + if (hasContextualMap) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + var refPkg = utils.pkg.findByModuleNameOrAddress(this, parentName, parentAddress); + if (!refPkg) { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + var isPointingAtParentFolder = name === '../' || name === './'; + if (parentIsNpmModule && isPointingAtParentFolder) { + var parsedParentModuleName = utils.moduleName.parse(parentName); + var parentModulePath = parsedParentModuleName.modulePath || ''; + var relativePath = utils.path.relativeTo(parentModulePath, name); + var isInRoot = utils.path.isPackageRootDir(relativePath); + if (isInRoot) { + name = refPkg.name + '#' + utils.path.removeJS(utils.path.removeDotSlash(refPkg.main)); + } else { + name = name + 'index'; + } + } + var parsedModuleName = utils.moduleName.parseFromPackage(this, refPkg, name, parentName); + var isRoot = utils.pkg.isRoot(this, refPkg); + var parsedPackageNameIsReferringPackage = parsedModuleName.packageName === refPkg.name; + var isRelativeToParentNpmModule = parentIsNpmModule && nameIsRelative && parsedPackageNameIsReferringPackage; + var depPkg, wantedPkg; + if (isRelativeToParentNpmModule) { + depPkg = refPkg; + } + var context = this.npmContext; + var crawl = context && context.crawl; + var isDev = !!crawl; + if (!depPkg) { + if (crawl) { + var parentPkg = nameIsRelative ? null : crawl.matchedVersion(context, refPkg.name, refPkg.version); + if (parentPkg) { + var depMap = crawl.getFullDependencyMap(this, parentPkg, isRoot); + wantedPkg = depMap[parsedModuleName.packageName]; + if (wantedPkg) { + var wantedVersion = refPkg.resolutions && refPkg.resolutions[wantedPkg.name] || wantedPkg.version; + var foundPkg = crawl.matchedVersion(this.npmContext, wantedPkg.name, wantedVersion); + if (foundPkg) { + depPkg = utils.pkg.findByUrl(this, foundPkg.fileUrl); + } + } + } + } else { + if (isRoot) { + depPkg = utils.pkg.findDepWalking(this, refPkg, parsedModuleName.packageName); + } else { + depPkg = utils.pkg.findDep(this, refPkg, parsedModuleName.packageName); + } + } + } + if (parsedPackageNameIsReferringPackage) { + depPkg = utils.pkg.findByNameAndVersion(this, parsedModuleName.packageName, refPkg.version); + } + var lookupByName = parsedModuleName.isGlobal || hasNoParent; + if (!depPkg) { + depPkg = utils.pkg.findByName(this, parsedModuleName.packageName); + } + var isThePackageWeWant = !isDev || !depPkg || (wantedPkg ? crawl.pkgSatisfies(depPkg, wantedPkg.version) : true); + if (!isThePackageWeWant) { + depPkg = undefined; + } else if (isDev && depPkg) { + utils.pkg.saveResolution(context, refPkg, depPkg); + } + if (!depPkg) { + var browserPackageName = this.globalBrowser[parsedModuleName.packageName]; + if (browserPackageName) { + parsedModuleName.packageName = browserPackageName.moduleName; + depPkg = utils.pkg.findByName(this, parsedModuleName.packageName); + } + } + if (!depPkg && isRoot && name === refPkg.main && utils.pkg.hasDirectoriesLib(refPkg)) { + parsedModuleName.version = refPkg.version; + parsedModuleName.packageName = refPkg.name; + parsedModuleName.modulePath = utils.pkg.main(refPkg); + return oldNormalize.call(this, utils.moduleName.create(parsedModuleName), parentName, parentAddress, pluginNormalize); + } + var loader = this; + if (!depPkg) { + if (crawl) { + var parentPkg = crawl.matchedVersion(this.npmContext, refPkg.name, refPkg.version); + if (parentPkg) { + var depMap = crawl.getFullDependencyMap(this, parentPkg, isRoot); + depPkg = depMap[parsedModuleName.packageName]; + if (!depPkg) { + var parents = crawl.findPackageAndParents(this.npmContext, parsedModuleName.packageName); + if (parents) { + depPkg = parents.package; + } + } + } + } + if (!depPkg) { + if (refPkg.browser && refPkg.browser[name]) { + return oldNormalize.call(this, refPkg.browser[name], parentName, parentAddress, pluginNormalize); + } + var steal = utils.pkg.config(refPkg); + if (steal && steal.map && typeof steal.map[name] === 'string') { + var mappedName = steal.map[name]; + var envConfig = steal.envs && steal.envs[loader.env]; + if (envConfig && envConfig.map && typeof envConfig.map[name] === 'string') { + mappedName = envConfig.map[name]; + } + return loader.normalize(mappedName, parentName, parentAddress, pluginNormalize); + } else { + return oldNormalize.call(this, name, parentName, parentAddress, pluginNormalize); + } + } + return crawl.dep(this.npmContext, parentPkg, refPkg, depPkg, isRoot).then(createModuleNameAndNormalize); + } else { + return createModuleNameAndNormalize(depPkg); + } + function createModuleNameAndNormalize(depPkg) { + parsedModuleName.version = depPkg.version; + if (!parsedModuleName.modulePath) { + parsedModuleName.modulePath = utils.pkg.main(depPkg); + } + var p = oldNormalize.call(loader, utils.moduleName.create(parsedModuleName), parentName, parentAddress, pluginNormalize); + if (identifierEndsWithSlash) { + p.then(function (name) { + if (context && context.forwardSlashMap) { + context.forwardSlashMap[name] = true; + } + }); + } + return p; + } + }; + var oldLocate = System.locate; + System.locate = function (load) { + var parsedModuleName = utils.moduleName.parse(load.name), loader = this; + var pmn = load.metadata.parsedModuleName = parsedModuleName; + load.metadata.npmPackage = utils.pkg.findByNameAndVersion(this, pmn.packageName, pmn.version); + if (parsedModuleName.version && this.npm && !loader.paths[load.name]) { + var pkg = this.npm[utils.moduleName.nameAndVersion(parsedModuleName)]; + if (pkg) { + return oldLocate.call(this, load).then(function (locatedAddress) { + var address = locatedAddress; + var expectedAddress = utils.path.joinURIs(System.baseURL, load.name); + if (isBrowser) { + expectedAddress = expectedAddress.replace(/#/g, '%23'); + } + if (address !== expectedAddress + '.js' && address !== expectedAddress) { + return address; + } + var root = utils.pkg.rootDir(pkg, utils.pkg.isRoot(loader, pkg)); + if (parsedModuleName.modulePath) { + var npmAddress = utils.path.joinURIs(utils.path.addEndingSlash(root), parsedModuleName.plugin ? parsedModuleName.modulePath : utils.path.addJS(parsedModuleName.modulePath)); + address = typeof steal !== 'undefined' ? utils.path.joinURIs(loader.baseURL, npmAddress) : npmAddress; + } + return address; + }); + } + } + return oldLocate.call(this, load); + }; + var oldFetch = System.fetch; + System.fetch = function (load) { + if (load.metadata.dryRun) { + return oldFetch.apply(this, arguments); + } + var loader = this; + var context = loader.npmContext; + var fetchPromise = Promise.resolve(oldFetch.apply(this, arguments)); + if (utils.moduleName.isNpm(load.name)) { + fetchPromise = fetchPromise.then(null, function (err) { + var statusCode = err.statusCode; + if (statusCode !== 404 && statusCode !== 0) { + return Promise.reject(err); + } + if (!loader.npmContext) { + loader.npmContext = { forwardSlashMap: {} }; + } + var types = [].slice.call(retryTypes); + return retryAll(types, err).then(null, function (e) { + return Promise.reject(err); + }); + function retryAll(types, err) { + if (!types.length) { + throw err; + } + var type = types.shift(); + if (!type.test(load)) { + throw err; + } + return Promise.resolve(retryFetch.call(loader, load, type)).then(null, function (err) { + return retryAll(types, err); + }); + } + }); + } + return fetchPromise.catch(function (error) { + var statusCode = error.statusCode; + if ((statusCode === 404 || statusCode === 0) && utils.moduleName.isBareIdentifier(load.name) && !utils.pkg.isRoot(loader, load.metadata.npmPackage)) { + var newError = new Error([ + 'Could not load \'' + load.name + '\'', + 'Is this an npm module not saved in your package.json?' + ].join('\n')); + newError.statusCode = error.statusCode; + newError.stack = newError.stack + error.stack; + throw newError; + } else { + throw error; + } + }); + }; + var convertName = function (loader, name) { + var pkg = utils.pkg.findByName(loader, name.split('/')[0]); + if (pkg) { + var parsed = utils.moduleName.parse(name, pkg.name); + parsed.version = pkg.version; + if (!parsed.modulePath) { + parsed.modulePath = utils.pkg.main(pkg); + } + return utils.moduleName.create(parsed); + } + return name; + }; + var configSpecial = { + map: function (map) { + var newMap = {}, val; + for (var name in map) { + val = map[name]; + newMap[convertName(this, name)] = typeof val === 'object' ? configSpecial.map(val) : convertName(this, val); + } + return newMap; + }, + meta: function (map) { + var newMap = {}; + for (var name in map) { + newMap[convertName(this, name)] = map[name]; + } + return newMap; + }, + paths: function (paths) { + var newPaths = {}; + for (var name in paths) { + newPaths[convertName(this, name)] = paths[name]; + } + return newPaths; + } + }; + var oldConfig = System.config; + System.config = function (cfg) { + var loader = this; + if (loader.npmContext) { + var context = loader.npmContext; + var pkg = context.versions.__default; + var conv = context.convert.steal(context, pkg, cfg, true); + context.convert.updateConfigOnPackageLoad(conv, false, true, context.applyBuildConfig); + oldConfig.apply(loader, arguments); + return; + } + for (var name in cfg) { + if (configSpecial[name]) { + cfg[name] = configSpecial[name].call(loader, cfg[name]); + } + } + oldConfig.apply(loader, arguments); + }; + var newLoader = System._newLoader || Function.prototype; + System._newLoader = function (loader) { + loader.npmContext = this.npmContext; + loader.npmParentMap = this.npmParentMap; + return newLoader.apply(this, arguments); + }; + steal.addNpmPackages = function (npmPackages) { + var packages = npmPackages || []; + var loader = this.loader; + for (var i = 0; i < packages.length; i += 1) { + var pkg = packages[i]; + var path = pkg && pkg.fileUrl; + if (path) { + loader.npmContext.paths[path] = pkg; + } + } + }; + steal.getNpmPackages = function () { + var context = this.loader.npmContext; + return context ? context.packages || [] : []; + }; + function retryFetch(load, type) { + var loader = this; + var moduleName = typeof type.name === 'function' ? type.name(loader, load) : load.name + type.name; + var local = utils.extend({}, load); + local.name = moduleName; + local.metadata = { dryRun: true }; + return Promise.resolve(loader.locate(local)).then(function (address) { + local.address = address; + return loader.fetch(local); + }).then(function (source) { + load.metadata.address = local.address; + loader.npmParentMap[load.name] = local.name; + var npmLoad = loader.npmContext && loader.npmContext.npmLoad; + if (npmLoad) { + npmLoad.saveLoadIfNeeded(loader.npmContext); + if (!isNode) { + utils.warnOnce('Some 404s were encountered ' + 'while loading. Don\'t panic! ' + 'These will only happen in dev ' + 'and are harmless.'); + } + } + return source; + }); + } + var retryTypes = [ + { + name: function (loader, load) { + var context = loader.npmContext; + if (context.forwardSlashMap[load.name]) { + var parts = load.name.split('/'); + parts.pop(); + return parts.concat(['index']).join('/'); + } + return load.name + '/index'; + }, + test: function () { + return true; + } + }, + { + name: '.json', + test: function (load) { + return utils.moduleName.isNpm(load.name) && utils.path.basename(load.address) === 'package.js'; + } + } + ]; + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*node_modules/steal-conditional/conditional*/ +define('node_modules/steal-conditional/conditional', [ + 'module', + 'exports', + '@loader' +], function (module, exports, System) { + exports.extensionBuilder = 'steal-conditional/slim'; + function addConditionals(loader) { + var conditionalRegEx = /#\{[^\}]+\}|#\?.+$/; + var isNode = typeof process === 'object' && {}.toString.call(process) === '[object process]'; + if (loader._extensions) { + loader._extensions.push(addConditionals); + } + loader.set('@@conditional-helpers', loader.newModule({ + isConditionalModuleName: function (moduleName) { + return conditionalRegEx.test(moduleName); + } + })); + var normalize = loader.normalize; + function readMemberExpression(p, value) { + var pParts = p.split('.'); + while (pParts.length) { + value = value[pParts.shift()]; + } + return value; + } + function includeInBuild(loader, name) { + var load = loader.getModuleLoad(name); + load.metadata.includeInBuild = true; + } + function getGlob() { + if (isNode) { + return loader.import('@node-require', { name: module.id }).then(function (nodeRequire) { + return nodeRequire('glob'); + }); + } + return Promise.resolve(); + } + function pushIfUnique(array, item) { + return array.indexOf(item) === -1 ? array.push(item) : array.length; + } + function getModuleName(nameWithConditional, variation) { + var modName; + var conditionIndex = nameWithConditional.search(conditionalRegEx); + var lastSlashIndex = nameWithConditional.indexOf('/', nameWithConditional.indexOf('}')); + if (lastSlashIndex !== -1) { + modName = nameWithConditional.substr(0, conditionIndex) + variation; + } else { + modName = nameWithConditional.replace(conditionalRegEx, variation); + } + return modName; + } + loader.normalize = function (name, parentName, parentAddress, pluginNormalize) { + var loader = this; + var conditionalMatch = name.match(conditionalRegEx); + if (conditionalMatch) { + var substitution = conditionalMatch[0][1] !== '?'; + var conditionModule = substitution ? conditionalMatch[0].substr(2, conditionalMatch[0].length - 3) : conditionalMatch[0].substr(2); + var conditionExport = 'default'; + var conditionExportParts = conditionModule.match(/^(?:\.\/|\.\.\/)+/); + var conditionExportIndex = conditionModule.indexOf('.', conditionExportParts && conditionExportParts[0].length); + if (conditionExportIndex !== -1) { + conditionExport = conditionModule.substr(conditionExportIndex + 1); + conditionModule = conditionModule.substr(0, conditionExportIndex); + } + var booleanNegation = !substitution && conditionModule[0] === '~'; + if (booleanNegation) { + conditionModule = conditionModule.substr(1); + } + var handleConditionalBuild = function () { + }; + var handleConditionalEval = function (m) { + var conditionValue = typeof m === 'object' ? readMemberExpression(conditionExport, m) : m; + if (substitution) { + if (typeof conditionValue !== 'string') { + throw new TypeError('The condition value for ' + conditionalMatch[0] + ' doesn\'t resolve to a string.'); + } + name = name.replace(conditionalRegEx, conditionValue); + } else { + if (typeof conditionValue !== 'boolean') { + throw new TypeError('The condition value for ' + conditionalMatch[0] + ' isn\'t resolving to a boolean.'); + } + if (booleanNegation) { + conditionValue = !conditionValue; + } + if (!conditionValue) { + name = '@empty'; + } else { + name = name.replace(conditionalRegEx, ''); + } + } + if (name === '@empty') { + return normalize.call(loader, name, parentName, parentAddress, pluginNormalize); + } else { + return loader.normalize.call(loader, name, parentName, parentAddress, pluginNormalize); + } + }; + var isBuild = (loader.env || '').indexOf('build') === 0; + var pluginLoader = isBuild ? loader : loader.pluginLoader || loader; + return pluginLoader['import'](conditionModule, { + name: parentName, + address: parentAddress + }).then(function (m) { + return pluginLoader.normalize(conditionModule, parentName, parentAddress, pluginNormalize).then(function (fullName) { + includeInBuild(pluginLoader, fullName); + return m; + }); + }).then(function (m) { + return isBuild ? handleConditionalBuild() : handleConditionalEval(m); + }); + } + return Promise.resolve(normalize.call(loader, name, parentName, parentAddress, pluginNormalize)); + }; + } + if (typeof System !== 'undefined') { + addConditionals(System); + } +}); +/*npm-load*/ +define('npm-load', [], function(){ return {}; }); +/*semver*/ +define('semver', [], function(){ return {}; }); +/*npm-crawl*/ +define('npm-crawl', [], function(){ return {}; }); +/*npm-convert*/ +define('npm-convert', [], function(){ return {}; }); +/*npm*/ +define('npm', [], function(){ return {}; }); +/*package.json!npm*/ +define('package.json!npm', [ + '@loader', + 'npm-extension', + 'module', + './node_modules/steal-conditional/conditional.js', + './node_modules/steal-conditional/conditional.js' +], function (loader, npmExtension, module) { + npmExtension.addExtension(loader); + if (!loader.main) { + loader.main = 'can@6.6.1#can'; + } + loader._npmExtensions = [].slice.call(arguments, 2); + (function (loader, packages, options) { + var g = loader.global; + if (!g.process) { + g.process = { + argv: [], + cwd: function () { + var baseURL = loader.baseURL; + return baseURL; + }, + browser: true, + env: { NODE_ENV: loader.env }, + version: '', + platform: navigator && navigator.userAgent && /Windows/.test(navigator.userAgent) ? 'win' : '' + }; + } + if (!loader.npm) { + loader.npm = {}; + loader.npmPaths = {}; + loader.globalBrowser = {}; + } + if (!loader.npmParentMap) { + loader.npmParentMap = options.npmParentMap || {}; + } + var rootPkg = loader.npmPaths.__default = packages[0]; + var rootConfig = rootPkg.steal || rootPkg.system; + var lib = rootConfig && rootConfig.directories && rootConfig.directories.lib; + var setGlobalBrowser = function (globals, pkg) { + for (var name in globals) { + loader.globalBrowser[name] = { + pkg: pkg, + moduleName: globals[name] + }; + } + }; + var setInNpm = function (name, pkg) { + if (!loader.npm[name]) { + loader.npm[name] = pkg; + } + loader.npm[name + '@' + pkg.version] = pkg; + }; + var forEach = function (arr, fn) { + var i = 0, len = arr.length; + for (; i < len; i++) { + res = fn.call(arr, arr[i], i); + if (res === false) + break; + } + }; + var setupLiveReload = function () { + if (loader.liveReloadInstalled) { + loader['import']('live-reload', { name: module.id }).then(function (reload) { + reload.dispose(function () { + var pkgInfo = loader.npmContext.pkgInfo; + delete pkgInfo[rootPkg.name + '@' + rootPkg.version]; + var idx = -1; + forEach(pkgInfo, function (pkg, i) { + if (pkg.name === rootPkg.name && pkg.version === rootPkg.version) { + idx = i; + return false; + } + }); + pkgInfo.splice(idx, 1); + }); + }); + } + }; + var ignoredConfig = [ + 'bundle', + 'configDependencies', + 'transpiler', + 'treeShaking' + ]; + packages.reverse(); + forEach(packages, function (pkg) { + var steal = pkg.steal || pkg.system; + if (steal) { + var main = steal.main; + delete steal.main; + var configDeps = steal.configDependencies; + if (pkg !== rootPkg) { + forEach(ignoredConfig, function (name) { + delete steal[name]; + }); + } + loader.config(steal); + if (pkg === rootPkg) { + steal.configDependencies = configDeps; + } + steal.main = main; + } + if (pkg.globalBrowser) { + var doNotApplyGlobalBrowser = pkg.name === 'steal' && rootConfig.builtins === false; + if (!doNotApplyGlobalBrowser) { + setGlobalBrowser(pkg.globalBrowser, pkg); + } + } + var systemName = steal && steal.name; + if (systemName) { + setInNpm(systemName, pkg); + } else { + setInNpm(pkg.name, pkg); + } + if (!loader.npm[pkg.name]) { + loader.npm[pkg.name] = pkg; + } + loader.npm[pkg.name + '@' + pkg.version] = pkg; + var pkgAddress = pkg.fileUrl.replace(/\/package\.json.*/, ''); + loader.npmPaths[pkgAddress] = pkg; + }); + setupLiveReload(); + forEach(loader._npmExtensions || [], function (ext) { + if (ext.systemConfig) { + loader.config(ext.systemConfig); + } + }); + }(loader, [ + { + 'name': 'can', + 'version': '6.6.1', + 'fileUrl': './package.json', + 'main': 'can.js', + 'steal': { + 'npmAlgorithm': 'flat', + 'npmIgnore': { + 'bit-docs': true, + 'testee': true, + 'async': true, + 'saucelabs': true, + 'test-saucelabs': true, + 'wd': true, + 'http-server': true + }, + 'meta': { + 'socket.io-client@2.4.0#dist/socket.io': { 'format': 'cjs' }, + 'socket.io-client/dist/socket.io': { 'format': 'cjs' } + }, + 'configDependencies': ['./node_modules/steal-conditional/conditional.js'], + 'plugins': ['steal-stache'], + 'main': 'can' + }, + 'resolutions': { + 'can': '6.6.1', + 'can-stache-element': '1.2.0', + 'can-observable-bindings': '1.3.3', + 'can-observable-object': '1.1.4', + 'can-observable-array': '1.1.4', + 'can-observable-mixin': '1.0.10', + 'can-type': '1.1.5', + 'can-query-logic': '1.2.2', + 'can-stache-bindings': '5.0.4', + 'can-bind': '1.5.1', + 'can-value': '1.1.2', + 'can-construct-super': '3.2.1', + 'can-assign': '1.3.3', + 'can-ajax': '2.4.6', + 'can-define-lazy-value': '1.1.1', + 'can-control': '5.0.1', + 'can-deparam': '1.2.3', + 'can-event-dom-enter': '2.2.1', + 'can-construct': '3.5.6', + 'can-dom-events': '1.3.11', + 'can-dom-mutate': '2.0.8', + 'can-event-dom-radiochange': '2.2.1', + 'can-event-queue': '1.1.8', + 'can-globals': '1.2.2', + 'can-key-tree': '1.2.2', + 'can-key': '1.2.1', + 'can-param': '1.1.3', + 'can-reflect-dependencies': '1.1.2', + 'can-parse-uri': '1.2.2', + 'can-queues': '1.3.2', + 'can-reflect-promise': '2.2.1', + 'can-simple-observable': '2.5.0', + 'can-stache-key': '1.4.3', + 'can-view-live': '5.0.4', + 'can-simple-dom': '1.7.1', + 'can-view-parser': '4.1.3', + 'can-stache-converters': '5.0.0', + 'can-validate-interface': '1.0.3', + 'can-component': '5.0.0', + 'can-view-model': '4.0.3', + 'can-define-realtime-rest-model': '2.0.0', + 'can-view-target': '5.0.0', + 'can-define-rest-model': '2.0.0', + 'can-view-scope': '4.13.6', + 'can-define': '2.8.0', + 'can-compute': '4.1.1', + 'can-map-define': '4.4.0', + 'can-fixture-socket': '2.0.3', + 'can-list': '4.2.2', + 'can-map': '4.3.12', + 'can-fixture': '3.1.7', + 'can-kefir': '1.1.4', + 'can-define-backup': '2.1.2', + 'can-define-stream-kefir': '1.1.1', + 'can-stream': '1.1.1', + 'can-validate-validatejs': '1.0.1', + 'can-view-autorender': '6.0.0', + 'can-validate': '1.2.1', + 'can-stream-kefir': '1.2.1', + 'can-ndjson-stream': '1.0.2', + 'can-define-stream': '1.1.1' + }, + 'system': { + 'npmAlgorithm': 'flat', + 'npmIgnore': { + 'bit-docs': true, + 'testee': true, + 'async': true, + 'saucelabs': true, + 'test-saucelabs': true, + 'wd': true, + 'http-server': true + }, + 'meta': { + 'socket.io-client@2.4.0#dist/socket.io': { 'format': 'cjs' }, + 'socket.io-client/dist/socket.io': { 'format': 'cjs' } + }, + 'configDependencies': ['./node_modules/steal-conditional/conditional.js'], + 'plugins': ['steal-stache'], + 'main': 'can' + } + }, + { + 'name': 'steal-stache', + 'version': '5.0.0', + 'fileUrl': './node_modules/steal-stache/package.json', + 'main': 'steal-stache.js', + 'steal': { + 'main': 'steal-stache', + 'configDependencies': ['live-reload'], + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmAlgorithm': 'flat', + 'ext': { 'stache': 'steal-stache' } + }, + 'resolutions': {} + }, + { + 'name': 'steal', + 'version': '2.2.4', + 'fileUrl': './node_modules/steal/package.json', + 'main': 'main', + 'steal': { + 'npmDependencies': { + 'console-browserify': true, + 'constants-browserify': true, + 'crypto-browserify': true, + 'http-browserify': true, + 'buffer': true, + 'os-browserify': true, + 'vm-browserify': true, + 'zlib-browserify': true, + 'assert': true, + 'domain-browser': true, + 'events': true, + 'https-browserify': true, + 'path-browserify': true, + 'string_decoder': true, + 'tty-browserify': true, + 'process': true, + 'punycode': true + } + }, + 'globalBrowser': { + 'console': 'console-browserify', + 'constants': 'constants-browserify', + 'crypto': 'crypto-browserify', + 'http': 'http-browserify', + 'buffer': 'buffer', + 'os': 'os-browserify', + 'vm': 'vm-browserify', + 'zlib': 'zlib-browserify', + 'assert': 'assert', + 'child_process': 'steal#ext/builtin/child_process', + 'cluster': 'steal#ext/builtin/cluster', + 'dgram': 'steal#ext/builtin/dgram', + 'dns': 'steal#ext/builtin/dns', + 'domain': 'domain-browser', + 'events': 'events', + 'fs': 'steal#ext/builtin/fs', + 'https': 'https-browserify', + 'module': 'steal#ext/builtin/module', + 'net': 'steal#ext/builtin/net', + 'path': 'path-browserify', + 'process': 'process', + 'querystring': 'steal#ext/builtin/querystring', + 'readline': 'steal#ext/builtin/readline', + 'repl': 'steal#ext/builtin/repl', + 'stream': 'steal#ext/builtin/stream', + 'string_decoder': 'string_decoder', + 'sys': 'steal#ext/builtin/sys', + 'timers': 'steal#ext/builtin/timers', + 'tls': 'steal#ext/builtin/tls', + 'tty': 'tty-browserify', + 'url': 'steal#ext/builtin/url', + 'util': 'steal#ext/builtin/util', + '_stream_readable': 'steal#ext/builtin/_stream_readable', + '_stream_writable': 'steal#ext/builtin/_stream_writable', + '_stream_duplex': 'steal#ext/builtin/_stream_duplex', + '_stream_transform': 'steal#ext/builtin/_stream_transform', + '_stream_passthrough': 'steal#ext/builtin/_stream_passthrough' + }, + 'resolutions': {} + }, + { + 'name': 'assert', + 'version': '1.4.1', + 'fileUrl': './node_modules/assert/package.json', + 'main': './assert.js', + 'resolutions': {} + }, + { + 'name': 'buffer', + 'version': '5.7.1', + 'fileUrl': './node_modules/buffer/package.json', + 'main': 'index.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'console-browserify', + 'version': '1.1.0', + 'fileUrl': './node_modules/console-browserify/package.json', + 'main': 'index', + 'resolutions': {} + }, + { + 'name': 'crypto-browserify', + 'version': '3.11.1', + 'fileUrl': './node_modules/crypto-browserify/package.json', + 'browser': { 'crypto': '@empty' }, + 'resolutions': {} + }, + { + 'name': 'domain-browser', + 'version': '1.1.7', + 'fileUrl': './node_modules/domain-browser/package.json', + 'main': './index.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'events', + 'version': '3.3.0', + 'fileUrl': './node_modules/events/package.json', + 'main': './events.js', + 'resolutions': {} + }, + { + 'name': 'http-browserify', + 'version': '1.7.0', + 'fileUrl': './node_modules/http-browserify/package.json', + 'main': 'index.js', + 'browser': 'index.js', + 'resolutions': {} + }, + { + 'name': 'https-browserify', + 'version': '1.0.0', + 'fileUrl': './node_modules/https-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'constants-browserify', + 'version': '1.0.0', + 'fileUrl': './node_modules/constants-browserify/package.json', + 'main': 'constants.json', + 'resolutions': {} + }, + { + 'name': 'path-browserify', + 'version': '0.0.1', + 'fileUrl': './node_modules/path-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'os-browserify', + 'version': '0.3.0', + 'fileUrl': './node_modules/os-browserify/package.json', + 'main': 'main.js', + 'browser': 'browser.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'process', + 'version': '0.11.10', + 'fileUrl': './node_modules/process/package.json', + 'main': './index.js', + 'browser': './browser.js', + 'resolutions': {} + }, + { + 'name': 'punycode', + 'version': '2.0.1', + 'fileUrl': './node_modules/punycode/package.json', + 'main': 'punycode.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'string_decoder', + 'version': '1.1.1', + 'fileUrl': './node_modules/string_decoder/package.json', + 'main': 'lib/string_decoder.js', + 'resolutions': {} + }, + { + 'name': 'tty-browserify', + 'version': '0.0.1', + 'fileUrl': './node_modules/tty-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'vm-browserify', + 'version': '0.0.4', + 'fileUrl': './node_modules/vm-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'zlib-browserify', + 'version': '0.0.3', + 'fileUrl': './node_modules/zlib-browserify/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'events', + 'version': '1.1.1', + 'fileUrl': './node_modules/steal/node_modules/events/package.json', + 'main': './events.js', + 'resolutions': {} + }, + { + 'name': 'string_decoder', + 'version': '1.0.3', + 'fileUrl': './node_modules/steal/node_modules/string_decoder/package.json', + 'main': 'lib/string_decoder.js', + 'resolutions': {} + }, + { + 'name': 'buffer', + 'version': '5.0.8', + 'fileUrl': './node_modules/steal/node_modules/buffer/package.json', + 'main': 'index.js', + 'jspm': {}, + 'resolutions': {} + }, + { + 'name': 'can-stache-element', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-stache-element/package.json', + 'main': 'dist/can-stache-element.js', + 'steal': { 'main': 'src/can-stache-element.js' }, + 'resolutions': { + 'can-stache-element': '1.2.0', + 'steal-qunit': '2.0.0', + 'can-type': '1.1.5', + 'can-view-scope': '4.13.6', + 'can-view-callbacks': '5.0.0', + 'can-stache-bindings': '5.0.4', + 'can-stache': '5.1.1', + 'can-simple-observable': '2.5.0', + 'can-reflect': '1.18.0', + 'can-test-helpers': '1.1.4', + 'can-value': '1.1.2', + 'can-observable-bindings': '1.3.3', + 'can-reflect-dependencies': '1.1.2', + 'can-observable-mixin': '1.0.10', + 'can-log': '1.0.2', + 'can-namespace': '1.0.0', + 'can-globals': '1.2.2', + 'can-dom-mutate': '2.0.8', + 'can-define-lazy-value': '1.1.1', + 'can-bind': '1.5.1' + } + }, + { + 'name': 'can-observable-bindings', + 'version': '1.3.3', + 'fileUrl': './node_modules/can-observable-bindings/package.json', + 'main': 'can-observable-bindings.js', + 'steal': { 'main': 'can-observable-bindings.js' }, + 'resolutions': { + 'can-observable-bindings': '1.3.3', + 'steal-qunit': '2.0.0', + 'can-type': '1.1.5', + 'can-test-helpers': '1.1.4', + 'can-value': '1.1.2', + 'can-bind': '1.5.1', + 'can-reflect': '1.18.0', + 'can-string': '1.1.0', + 'can-observation': '4.2.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-observable-object', + 'version': '1.1.4', + 'fileUrl': './node_modules/can-observable-object/package.json', + 'main': 'dist/can-observable-object.js', + 'steal': { 'main': 'src/can-observable-object.js' }, + 'resolutions': { + 'can-observable-object': '1.1.4', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'can-observable-mixin': '1.0.10' + } + }, + { + 'name': 'can-observable-array', + 'version': '1.1.4', + 'fileUrl': './node_modules/can-observable-array/package.json', + 'main': 'dist/can-observable-array.js', + 'steal': { 'main': 'src/can-observable-array.js' }, + 'resolutions': { + 'can-observable-array': '1.1.4', + 'steal-qunit': '2.0.0', + 'can-observable-object': '1.1.4', + 'can-type': '1.1.5', + 'can-reflect': '1.18.0', + 'can-observation': '4.2.0', + 'can-observable-mixin': '1.0.10', + 'can-namespace': '1.0.0', + 'can-queues': '1.3.2', + 'can-observation-recorder': '1.3.1', + 'can-event-queue': '1.1.8' + } + }, + { + 'name': 'can-observable-mixin', + 'version': '1.0.10', + 'fileUrl': './node_modules/can-observable-mixin/package.json', + 'main': 'dist/mixins.js', + 'steal': { 'main': 'src/mixins.js' }, + 'resolutions': { + 'can-observable-mixin': '1.0.10', + 'can-type': '1.1.5', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-observation-recorder': '1.3.1', + 'steal-qunit': '2.0.0', + 'can-test-helpers': '1.1.4', + 'can-reflect-tests': '1.0.0', + 'can-observation': '4.2.0', + 'can-simple-observable': '2.5.0', + 'can-event-queue': '1.1.8', + 'can-queues': '1.3.2', + 'can-assign': '1.3.3', + 'can-log': '1.0.2', + 'can-define-lazy-value': '1.1.1' + } + }, + { + 'name': 'can-type', + 'version': '1.1.5', + 'fileUrl': './node_modules/can-type/package.json', + 'main': 'can-type.js', + 'resolutions': { + 'can-type': '1.1.5', + 'can-query-logic': '1.2.2', + 'can-symbol': '1.6.5', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-test-helpers': '1.1.4', + 'can-namespace': '1.0.0', + 'can-string': '1.1.0' + } + }, + { + 'name': 'can-query-logic', + 'version': '1.2.2', + 'fileUrl': './node_modules/can-query-logic/package.json', + 'main': 'can-query-logic', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ] + }, + 'resolutions': { + 'can-query-logic': '1.2.2', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-assign': '1.3.3', + 'can-test-helpers': '1.1.4', + 'can-symbol': '1.6.5', + 'can-define-lazy-value': '1.1.1', + 'can-key': '1.2.1', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-stache-bindings', + 'version': '5.0.4', + 'fileUrl': './node_modules/can-stache-bindings/package.json', + 'main': 'can-stache-bindings', + 'steal': { 'main': 'can-stache-bindings' }, + 'resolutions': { + 'can-stache-bindings': '5.0.4', + 'can-simple-map': '4.3.3', + 'can-dom-mutate': '2.0.8', + 'can-globals': '1.2.2', + 'can-observable-object': '1.1.4', + 'steal-qunit': '2.0.0', + 'can-define': '2.8.0', + 'can-view-model': '4.0.3', + 'can-simple-observable': '2.5.0', + 'can-symbol': '1.6.5', + 'can-reflect': '1.18.0', + 'can-dom-events': '1.3.11', + 'can-attribute-encoder': '1.1.4', + 'can-test-helpers': '1.1.4', + 'can-queues': '1.3.2', + 'can-view-scope': '4.13.6', + 'can-event-dom-enter': '2.2.1', + 'can-reflect-dependencies': '1.1.2', + 'can-stache': '5.1.1', + 'can-view-callbacks': '5.0.0', + 'can-dom-data': '1.0.3', + 'can-bind': '1.5.1', + 'can-stache-key': '1.4.3', + 'can-observation-recorder': '1.3.1', + 'can-assign': '1.3.3', + 'can-log': '1.0.2', + 'can-event-queue': '1.1.8', + 'can-vdom': '4.4.2', + 'can-attribute-observable': '2.0.2' + } + }, + { + 'name': 'can-bind', + 'version': '1.5.1', + 'fileUrl': './node_modules/can-bind/package.json', + 'main': 'can-bind', + 'steal': { + 'npmIgnore': { + 'steal-tools': true, + 'testee': true + }, + 'main': 'can-bind' + }, + 'resolutions': { + 'can-bind': '1.5.1', + 'can-simple-map': '4.3.3', + 'can-simple-observable': '2.5.0', + 'can-value': '1.1.2', + 'can-reflect': '1.18.0', + 'can-reflect-dependencies': '1.1.2', + 'can-queues': '1.3.2', + 'can-observation': '4.2.0', + 'steal-qunit': '2.0.0', + 'can-test-helpers': '1.1.4', + 'can-symbol': '1.6.5', + 'can-namespace': '1.0.0', + 'can-assign': '1.3.3', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-value', + 'version': '1.1.2', + 'fileUrl': './node_modules/can-value/package.json', + 'main': 'can-value', + 'steal': { + 'npmIgnore': { + 'steal-tools': true, + 'testee': true + }, + 'main': 'can-value' + }, + 'resolutions': { + 'can-value': '1.1.2', + 'can-reflect-dependencies': '1.1.2', + 'can-reflect': '1.18.0', + 'can-simple-map': '4.3.3', + 'steal-qunit': '2.0.0', + 'can-key': '1.2.1', + 'can-simple-observable': '2.5.0', + 'can-namespace': '1.0.0', + 'can-observation': '4.2.0' + } + }, + { + 'name': 'can-construct-super', + 'version': '3.2.1', + 'fileUrl': './node_modules/can-construct-super/package.json', + 'main': 'can-construct-super', + 'steal': { + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-construct-super' + }, + 'resolutions': { + 'can-construct-super': '3.2.1', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-construct': '3.5.6' + } + }, + { + 'name': 'can-assign', + 'version': '1.3.3', + 'fileUrl': './node_modules/can-assign/package.json', + 'main': 'can-assign', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-assign': '1.3.3', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-ajax', + 'version': '2.4.6', + 'fileUrl': './node_modules/can-ajax/package.json', + 'main': 'can-ajax', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + }, + 'main': 'can-ajax' + }, + 'resolutions': { + 'can-ajax': '2.4.6', + 'can-globals': '1.2.2', + 'can-parse-uri': '1.2.2', + 'can-make-map': '1.2.2', + 'can-namespace': '1.0.0', + 'can-reflect': '1.18.0', + 'can-param': '1.1.3', + 'steal-qunit': '2.0.0', + 'qunit': '2.17.2' + } + }, + { + 'name': 'can-define-lazy-value', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-define-lazy-value/package.json', + 'main': 'define-lazy-value', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-define-lazy-value': '1.1.1', + 'steal-qunit': '2.0.0' + } + }, + { + 'name': 'can-control', + 'version': '5.0.1', + 'fileUrl': './node_modules/can-control/package.json', + 'main': 'can-control', + 'resolutions': { + 'can-control': '5.0.1', + 'can-dom-events': '1.3.11', + 'can-dom-mutate': '2.0.8', + 'can-globals': '1.2.2', + 'can-queues': '1.3.2', + 'can-define': '2.8.0', + 'can-simple-observable': '2.5.0', + 'can-simple-map': '4.3.3', + 'can-fragment': '1.3.1', + 'can-symbol': '1.6.5', + 'steal-qunit': '2.0.0', + 'can-log': '1.0.2', + 'can-construct': '3.5.6', + 'can-namespace': '1.0.0', + 'can-assign': '1.3.3', + 'can-stache-key': '1.4.3', + 'can-reflect': '1.18.0', + 'can-observation': '4.2.0', + 'can-event-queue': '1.1.8', + 'can-key': '1.2.1', + 'can-string': '1.1.0' + } + }, + { + 'name': 'can-deparam', + 'version': '1.2.3', + 'fileUrl': './node_modules/can-deparam/package.json', + 'main': 'can-deparam', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-deparam': '1.2.3', + 'can-string-to-any': '1.2.1', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-event-dom-enter', + 'version': '2.2.1', + 'fileUrl': './node_modules/can-event-dom-enter/package.json', + 'main': 'can-event-dom-enter', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + }, + 'main': 'can-event-dom-enter' + }, + 'resolutions': { + 'can-dom-events': '1.3.11', + 'can-event-dom-enter': '2.2.1', + 'can-namespace': '1.0.0', + 'steal-qunit': '2.0.0' + } + }, + { + 'name': 'can-construct', + 'version': '3.5.6', + 'fileUrl': './node_modules/can-construct/package.json', + 'main': 'can-construct', + 'steal': {}, + 'resolutions': { + 'can-construct': '3.5.6', + 'can-log': '1.0.2', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-namespace': '1.0.0', + 'can-symbol': '1.6.5', + 'can-string': '1.1.0' + } + }, + { + 'name': 'can-dom-events', + 'version': '1.3.11', + 'fileUrl': './node_modules/can-dom-events/package.json', + 'main': 'can-dom-events', + 'resolutions': { + 'can-dom-events': '1.3.11', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'jquery': '3.6.0', + 'can-key-tree': '1.2.2', + 'can-reflect': '1.18.0', + 'can-globals': '1.2.2' + } + }, + { + 'name': 'can-dom-mutate', + 'version': '2.0.8', + 'fileUrl': './node_modules/can-dom-mutate/package.json', + 'main': 'can-dom-mutate', + 'steal': { 'main': 'can-dom-mutate' }, + 'resolutions': { + 'can-dom-mutate': '2.0.8', + 'steal-qunit': '2.0.0', + 'can-globals': '1.2.2', + 'can-dom-events': '1.3.11', + 'can-namespace': '1.0.0', + 'can-vdom': '4.4.2' + } + }, + { + 'name': 'can-event-dom-radiochange', + 'version': '2.2.1', + 'fileUrl': './node_modules/can-event-dom-radiochange/package.json', + 'main': 'can-event-dom-radiochange', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + }, + 'main': 'can-event-dom-radiochange' + }, + 'resolutions': { + 'can-dom-events': '1.3.11', + 'can-event-dom-radiochange': '2.2.1', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'can-globals': '1.2.2' + } + }, + { + 'name': 'can-event-queue', + 'version': '1.1.8', + 'fileUrl': './node_modules/can-event-queue/package.json', + 'main': './can-event-queue.js', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ] + }, + 'resolutions': { + 'can-event-queue': '1.1.8', + 'can-symbol': '1.6.5', + 'can-queues': '1.3.2', + 'can-dom-events': '1.3.11', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-log': '1.0.2', + 'can-key-tree': '1.2.2', + 'can-define-lazy-value': '1.1.1' + } + }, + { + 'name': 'can-globals', + 'version': '1.2.2', + 'fileUrl': './node_modules/can-globals/package.json', + 'main': 'can-globals.js', + 'resolutions': { + 'can-globals': '1.2.2', + 'can-reflect': '1.18.0', + 'qunit': '2.17.2', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-key-tree', + 'version': '1.2.2', + 'fileUrl': './node_modules/can-key-tree/package.json', + 'main': 'can-key-tree', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ], + 'main': 'can-key-tree' + }, + 'resolutions': { + 'can-key-tree': '1.2.2', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'can-key', + 'version': '1.2.1', + 'fileUrl': './node_modules/can-key/package.json', + 'main': 'can-key', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ], + 'main': 'can-key' + }, + 'resolutions': { + 'can-key': '1.2.1', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-symbol': '1.6.5', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-param', + 'version': '1.1.3', + 'fileUrl': './node_modules/can-param/package.json', + 'main': 'can-param', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-param': '1.1.3', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-reflect-dependencies', + 'version': '1.1.2', + 'fileUrl': './node_modules/can-reflect-dependencies/package.json', + 'main': 'can-reflect-dependencies.js', + 'resolutions': { + 'can-simple-observable': '2.5.0', + 'can-reflect-dependencies': '1.1.2', + 'steal-qunit': '2.0.0', + 'can-simple-map': '4.3.3', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-assign': '1.3.3' + } + }, + { + 'name': 'can-parse-uri', + 'version': '1.2.2', + 'fileUrl': './node_modules/can-parse-uri/package.json', + 'main': 'can-parse-uri', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-parse-uri' + }, + 'resolutions': { + 'can-parse-uri': '1.2.2', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-queues', + 'version': '1.3.2', + 'fileUrl': './node_modules/can-queues/package.json', + 'main': './can-queues.js', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-queues' + }, + 'resolutions': { + 'can-queues': '1.3.2', + 'can-test-helpers': '1.1.4', + 'steal-qunit': '2.0.0', + 'can-log': '1.0.2', + 'can-namespace': '1.0.0', + 'can-symbol': '1.6.5', + 'can-assign': '1.3.3' + } + }, + { + 'name': 'can-reflect-promise', + 'version': '2.2.1', + 'fileUrl': './node_modules/can-reflect-promise/package.json', + 'main': 'can-reflect-promise', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': { + 'can-globals': '1.2.2', + 'can-reflect-promise': '2.2.1', + 'can-symbol': '1.6.5', + 'can-test-helpers': '1.1.4', + 'steal-qunit': '2.0.0', + 'can-observation-recorder': '1.3.1', + 'can-reflect': '1.18.0', + 'can-queues': '1.3.2', + 'can-key-tree': '1.2.2', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-simple-observable', + 'version': '2.5.0', + 'fileUrl': './node_modules/can-simple-observable/package.json', + 'main': 'can-simple-observable', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-simple-observable': '2.5.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-observation-recorder': '1.3.1', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'can-event-queue': '1.1.8', + 'can-observation': '4.2.0', + 'can-queues': '1.3.2', + 'can-key': '1.2.1', + 'can-reflect-dependencies': '1.1.2', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-stache-key', + 'version': '1.4.3', + 'fileUrl': './node_modules/can-stache-key/package.json', + 'main': 'can-stache-key', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-stache-key' + }, + 'resolutions': { + 'can-stache-key': '1.4.3', + 'can-event-queue': '1.1.8', + 'can-simple-observable': '2.5.0', + 'can-reflect': '1.18.0', + 'can-test-helpers': '1.1.4', + 'can-observation': '4.2.0', + 'steal-qunit': '2.0.0', + 'can-observation-recorder': '1.3.1', + 'can-simple-map': '4.3.3', + 'can-log': '1.0.2', + 'can-symbol': '1.6.5', + 'can-reflect-promise': '2.2.1' + } + }, + { + 'name': 'can-view-live', + 'version': '5.0.4', + 'fileUrl': './node_modules/can-view-live/package.json', + 'main': 'can-view-live', + 'steal': { + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-view-live' + }, + 'resolutions': { + 'can-view-live': '5.0.4', + 'can-define': '2.8.0', + 'can-symbol': '1.6.5', + 'can-simple-observable': '2.5.0', + 'can-observation': '4.2.0', + 'can-test-helpers': '1.1.4', + 'can-dom-mutate': '2.0.8', + 'can-reflect-dependencies': '1.1.2', + 'can-fragment': '1.3.1', + 'can-queues': '1.3.2', + 'can-globals': '1.2.2', + 'can-simple-map': '4.3.3', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-diff': '1.5.0', + 'can-view-callbacks': '5.0.0', + 'can-attribute-observable': '2.0.2', + 'can-view-parser': '4.1.3', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-simple-dom', + 'version': '1.7.1', + 'fileUrl': './node_modules/can-simple-dom/package.json', + 'main': 'can-simple-dom.js', + 'resolutions': { + 'can-simple-dom': '1.7.1', + 'steal-qunit': '2.0.0', + 'he': '1.2.0', + 'simple-html-tokenizer': '0.2.6', + 'can-child-nodes': '1.2.1', + 'micro-location': '0.1.5' + } + }, + { + 'name': 'can-view-parser', + 'version': '4.1.3', + 'fileUrl': './node_modules/can-view-parser/package.json', + 'main': 'can-view-parser', + 'resolutions': { + 'can-view-parser': '4.1.3', + 'can-test-helpers': '1.1.4', + 'can-attribute-encoder': '1.1.4', + 'steal-qunit': '2.0.0', + 'can-log': '1.0.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-stache-converters', + 'version': '5.0.0', + 'fileUrl': './node_modules/can-stache-converters/package.json', + 'main': 'can-stache-converters', + 'steal': { 'main': 'can-stache-converters' }, + 'resolutions': { + 'can-stache-converters': '5.0.0', + 'can-define': '2.8.0', + 'can-dom-events': '1.3.11', + 'can-reflect': '1.18.0', + 'can-compute': '4.1.1', + 'can-stache': '5.1.1', + 'steal-qunit': '2.0.0', + 'can-string-to-any': '1.2.1', + 'can-log': '1.0.2', + 'can-stache-bindings': '5.0.4', + 'can-stache-helpers': '1.2.0' + } + }, + { + 'name': 'can-validate-interface', + 'version': '1.0.3', + 'fileUrl': './node_modules/can-validate-interface/package.json', + 'main': 'index.js', + 'resolutions': { + 'can-validate-interface': '1.0.3', + 'steal-qunit': '2.0.0' + } + }, + { + 'name': 'can-component', + 'version': '5.0.0', + 'fileUrl': './node_modules/can-component/package.json', + 'main': 'can-component', + 'steal': {}, + 'resolutions': { + 'can-component': '5.0.0', + 'can-simple-map': '4.3.3', + 'can-view-model': '4.0.3', + 'can-define': '2.8.0', + 'can-view-scope': '4.13.6', + 'can-simple-observable': '2.5.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-dom-events': '1.3.11', + 'can-dom-mutate': '2.0.8', + 'can-construct': '3.5.6', + 'can-queues': '1.3.2', + 'can-fragment': '1.3.1', + 'can-log': '1.0.2', + 'can-test-helpers': '1.1.4', + 'can-value': '1.1.2', + 'can-globals': '1.2.2', + 'can-bind': '1.5.1', + 'steal-qunit': '2.0.0', + 'can-stache': '5.1.1', + 'can-observe': '2.3.2', + 'can-dom-data': '1.0.3', + 'can-view-callbacks': '5.0.0', + 'can-namespace': '1.0.0', + 'can-stache-bindings': '5.0.4', + 'can-assign': '1.3.3', + 'can-observation-recorder': '1.3.1', + 'can-string': '1.1.0', + 'can-vdom': '4.4.2', + 'can-child-nodes': '1.2.1', + 'can-control': '5.0.1' + } + }, + { + 'name': 'can-view-model', + 'version': '4.0.3', + 'fileUrl': './node_modules/can-view-model/package.json', + 'main': 'can-view-model', + 'resolutions': { + 'can-view-model': '4.0.3', + 'can-simple-map': '4.3.3', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'can-globals': '1.2.2', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-define-realtime-rest-model', + 'version': '2.0.0', + 'fileUrl': './node_modules/can-define-realtime-rest-model/package.json', + 'main': 'can-define-realtime-rest-model', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-fixture': '3.1.7', + 'can-define': '2.8.0', + 'can-define-realtime-rest-model': '2.0.0', + 'can-query-logic': '1.2.2', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'can-connect': '4.0.2' + } + }, + { + 'name': 'can-view-target', + 'version': '5.0.0', + 'fileUrl': './node_modules/can-view-target/package.json', + 'main': 'can-view-target', + 'resolutions': { + 'can-view-target': '5.0.0', + 'can-simple-dom': '1.7.1', + 'can-globals': '1.2.2', + 'steal-qunit': '2.0.0', + 'can-dom-mutate': '2.0.8', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-define-rest-model', + 'version': '2.0.0', + 'fileUrl': './node_modules/can-define-rest-model/package.json', + 'main': 'can-define-rest-model', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-define-rest-model': '2.0.0', + 'steal-qunit': '2.0.0', + 'can-fixture': '3.1.7', + 'can-define': '2.8.0', + 'can-reflect': '1.18.0', + 'can-namespace': '1.0.0', + 'can-connect': '4.0.2' + } + }, + { + 'name': 'can-view-scope', + 'version': '4.13.6', + 'fileUrl': './node_modules/can-view-scope/package.json', + 'main': 'can-view-scope', + 'resolutions': { + 'can-view-scope': '4.13.6', + 'can-stache-key': '1.4.3', + 'can-simple-observable': '2.5.0', + 'can-reflect-dependencies': '1.1.2', + 'can-reflect': '1.18.0', + 'can-simple-map': '4.3.3', + 'can-observation-recorder': '1.3.1', + 'can-observation': '4.2.0', + 'can-stache-helpers': '1.2.0', + 'can-symbol': '1.6.5', + 'steal-qunit': '2.0.0', + 'can-test-helpers': '1.1.4', + 'can-assign': '1.3.3', + 'can-namespace': '1.0.0', + 'can-log': '1.0.2', + 'can-define-lazy-value': '1.1.1', + 'can-event-queue': '1.1.8', + 'can-single-reference': '1.3.0' + } + }, + { + 'name': 'can-define', + 'version': '2.8.0', + 'fileUrl': './node_modules/can-define/package.json', + 'main': 'can-define.js', + 'resolutions': { + 'can-define': '2.8.0', + 'can-reflect': '1.18.0', + 'can-observation': '4.2.0', + 'can-queues': '1.3.2', + 'can-symbol': '1.6.5', + 'can-simple-observable': '2.5.0', + 'can-test-helpers': '1.1.4', + 'can-observation-recorder': '1.3.1', + 'can-log': '1.0.2', + 'can-assign': '1.3.3', + 'can-reflect-tests': '1.0.0', + 'steal-qunit': '2.0.0', + 'can-data-types': '1.2.1', + 'can-construct': '3.5.6', + 'can-namespace': '1.0.0', + 'can-event-queue': '1.1.8', + 'can-string-to-any': '1.2.1', + 'can-define-lazy-value': '1.1.1', + 'can-single-reference': '1.3.0', + 'can-diff': '1.5.0' + } + }, + { + 'name': 'can-compute', + 'version': '4.1.1', + 'fileUrl': './node_modules/can-compute/package.json', + 'main': 'can-compute', + 'resolutions': { + 'can-compute': '4.1.1', + 'can-event-queue': '1.1.8', + 'can-queues': '1.3.2', + 'can-dom-events': '1.3.11', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-observation-recorder': '1.3.1', + 'can-symbol': '1.6.5', + 'can-namespace': '1.0.0', + 'can-single-reference': '1.3.0', + 'can-observation': '4.2.0', + 'can-stache-key': '1.4.3', + 'can-key': '1.2.1', + 'can-assign': '1.3.3' + } + }, + { + 'name': 'can-map-define', + 'version': '4.4.0', + 'fileUrl': './node_modules/can-map-define/package.json', + 'main': 'can-map-define', + 'steal': { 'main': 'can-map-define' }, + 'resolutions': { + 'can-key': '1.2.1', + 'can-map': '4.3.12', + 'can-list': '4.2.2', + 'can-compute': '4.1.1', + 'can-map-define': '4.4.0', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-reflect-tests': '1.0.0', + 'can-log': '1.0.2', + 'can-assign': '1.3.3', + 'can-event-queue': '1.1.8', + 'can-queues': '1.3.2', + 'can-observation-recorder': '1.3.1', + 'can-simple-observable': '2.5.0', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-fixture-socket', + 'version': '2.0.3', + 'fileUrl': './node_modules/can-fixture-socket/package.json', + 'main': 'can-fixture-socket', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'paths': { '@feathersjs/commons*lib/lib': 'node_modules/@feathersjs/commons/lib/index.js' }, + 'main': 'can-fixture-socket' + }, + 'resolutions': { + 'can-fixture-socket': '2.0.3', + 'can-fixture': '3.1.7', + 'can-set-legacy': '1.0.1', + '@feathersjs/feathers': '3.3.1', + '@feathersjs/socketio-client': '1.2.1', + 'es6-promise-polyfill': '1.2.0', + 'socket.io-client': '2.4.0', + 'object-assign': '4.1.1', + 'steal-qunit': '2.0.0', + 'can-assign': '1.3.3' + } + }, + { + 'name': 'can-list', + 'version': '4.2.2', + 'fileUrl': './node_modules/can-list/package.json', + 'main': 'can-list', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': { + 'can-list': '4.2.2', + 'can-map': '4.3.12', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'steal-qunit': '2.0.0', + 'can-observation': '4.2.0', + 'can-namespace': '1.0.0', + 'can-queues': '1.3.2', + 'can-event-queue': '1.1.8', + 'can-observation-recorder': '1.3.1', + 'can-assign': '1.3.3', + 'can-cid': '1.3.1', + 'can-types': '1.4.0' + } + }, + { + 'name': 'can-map', + 'version': '4.3.12', + 'fileUrl': './node_modules/can-map/package.json', + 'main': 'can-map', + 'steal': {}, + 'resolutions': { + 'can-map': '4.3.12', + 'can-compute': '4.1.1', + 'can-construct': '3.5.6', + 'can-stache-key': '1.4.3', + 'can-queues': '1.3.2', + 'can-observation-recorder': '1.3.1', + 'can-reflect-tests': '1.0.0', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-test-helpers': '1.1.4', + 'can-event-queue': '1.1.8', + 'can-observation': '4.2.0', + 'can-namespace': '1.0.0', + 'can-log': '1.0.2', + 'can-assign': '1.3.3', + 'can-cid': '1.3.1', + 'can-types': '1.4.0', + 'can-single-reference': '1.3.0' + } + }, + { + 'name': 'can-fixture', + 'version': '3.1.7', + 'fileUrl': './node_modules/can-fixture/package.json', + 'main': 'fixture.js', + 'resolutions': { + 'can-fixture': '3.1.7', + 'can-query-logic': '1.2.2', + 'can-define': '2.8.0', + 'can-reflect': '1.18.0', + 'can-test-helpers': '1.1.4', + 'jquery': '3.6.0', + 'steal-qunit': '2.0.0', + 'can-set-legacy': '1.0.1', + 'can-log': '1.0.2', + 'can-namespace': '1.0.0', + 'can-key': '1.2.1', + 'can-deparam': '1.2.3', + 'can-memory-store': '1.0.3' + } + }, + { + 'name': 'can-kefir', + 'version': '1.1.4', + 'fileUrl': './node_modules/can-kefir/package.json', + 'main': 'can-kefir', + 'browser': {}, + 'resolutions': { + 'can-kefir': '1.1.4', + 'can-queues': '1.3.2', + 'can-reflect': '1.18.0', + 'steal-qunit': '2.0.0', + 'can-symbol': '1.6.5', + 'can-event-queue': '1.1.8', + 'can-observation-recorder': '1.3.1', + 'kefir': '3.8.8' + } + }, + { + 'name': 'can-define-backup', + 'version': '2.1.2', + 'fileUrl': './node_modules/can-define-backup/package.json', + 'main': 'can-define-backup', + 'resolutions': { + 'can-define': '2.8.0', + 'can-define-backup': '2.1.2', + 'can-reflect': '1.18.0', + 'can-observation': '4.2.0', + 'steal-qunit': '2.0.0', + 'can-simple-observable': '2.5.0', + 'can-diff': '1.5.0' + } + }, + { + 'name': 'can-define-stream-kefir', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-define-stream-kefir/package.json', + 'main': 'can-define-stream-kefir', + 'steal': {}, + 'resolutions': { + 'can-define': '2.8.0', + 'can-define-stream-kefir': '1.1.1', + 'can-symbol': '1.6.5', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0', + 'can-define-stream': '1.1.1', + 'can-stream-kefir': '1.2.1' + } + }, + { + 'name': 'can-stream', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-stream/package.json', + 'main': 'can-stream', + 'steal': {}, + 'resolutions': { + 'can-compute': '4.1.1', + 'can-define': '2.8.0', + 'can-stream': '1.1.1', + 'steal-qunit': '2.0.0', + 'can-assign': '1.3.3', + 'can-reflect': '1.18.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-validate-validatejs', + 'version': '1.0.1', + 'fileUrl': './node_modules/can-validate-validatejs/package.json', + 'main': 'can-validate-validatejs.js', + 'steal': { + 'ignoreBrowser': true, + 'npmIgnore': { + 'bit-docs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmDependencies': { 'steal-qunit': true }, + 'paths': { 'validate.js@0.11.1#validate': './node_modules/validate.js/validate.js' } + }, + 'resolutions': { + 'can-validate-validatejs': '1.0.1', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'validate.js': '0.11.1' + }, + 'system': { + 'ignoreBrowser': true, + 'npmIgnore': { + 'bit-docs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmDependencies': { 'steal-qunit': true }, + 'paths': { 'validate.js@0.11.1#validate': './node_modules/validate.js/validate.js' } + } + }, + { + 'name': 'can-view-autorender', + 'version': '6.0.0', + 'fileUrl': './node_modules/can-view-autorender/package.json', + 'main': 'can-view-autorender', + 'resolutions': { + 'can-view-autorender': '6.0.0', + 'steal-qunit': '2.0.0' + } + }, + { + 'name': 'can-validate', + 'version': '1.2.1', + 'fileUrl': './node_modules/can-validate/package.json', + 'main': 'can-validate.js', + 'steal': { + 'ignoreBrowser': true, + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'steal-tools': true + }, + 'npmDependencies': { 'steal-qunit': true } + }, + 'browser': {}, + 'resolutions': { + 'can-validate': '1.2.1', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'can-stream-kefir', + 'version': '1.2.1', + 'fileUrl': './node_modules/can-stream-kefir/package.json', + 'main': 'can-stream-kefir', + 'steal': {}, + 'resolutions': { + 'can-stream-kefir': '1.2.1', + 'can-compute': '4.1.1', + 'can-define': '2.8.0', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-kefir': '1.1.4', + 'can-stream': '1.1.1', + 'can-symbol': '1.6.5', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-ndjson-stream', + 'version': '1.0.2', + 'fileUrl': './node_modules/can-ndjson-stream/package.json', + 'main': 'can-ndjson-stream', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-ndjson-stream' + }, + 'resolutions': { + 'can-ndjson-stream': '1.0.2', + 'steal-qunit': '2.0.0', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-define-stream', + 'version': '1.1.1', + 'fileUrl': './node_modules/can-define-stream/package.json', + 'main': 'can-define-stream', + 'steal': {}, + 'resolutions': { + 'can-define': '2.8.0', + 'can-define-stream': '1.1.1', + 'can-compute': '4.1.1', + 'can-stream': '1.1.1', + 'steal-qunit': '2.0.0', + 'can-symbol': '1.6.5', + 'can-assign': '1.3.3', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'steal-qunit', + 'version': '2.0.0', + 'fileUrl': './node_modules/steal-qunit/package.json', + 'main': 'steal-qunit', + 'steal': { + 'plugins': ['steal-css'], + 'meta': { + 'qunit@2.17.2#qunit/qunit': { + 'format': 'global', + 'exports': 'QUnit', + 'deps': ['steal-qunit/add-dom'] + } + } + }, + 'resolutions': { + 'qunit': '2.17.2', + 'steal-css': '1.3.2' + }, + 'system': { + 'plugins': ['steal-css'], + 'meta': { + 'qunit@2.17.2#qunit/qunit': { + 'format': 'global', + 'exports': 'QUnit', + 'deps': ['steal-qunit/add-dom'] + } + } + } + }, + { + 'name': 'can-reflect', + 'version': '1.18.0', + 'fileUrl': './node_modules/can-reflect/package.json', + 'main': 'can-reflect', + 'resolutions': { + 'can-reflect': '1.18.0', + 'can-namespace': '1.0.0', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-simple-map', + 'version': '4.3.3', + 'fileUrl': './node_modules/can-simple-map/package.json', + 'main': 'can-simple-map', + 'steal': { + 'npmIgnore': { + 'documentjs': true, + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-simple-map' + }, + 'resolutions': { + 'can-construct': '3.5.6', + 'can-event-queue': '1.1.8', + 'can-queues': '1.3.2', + 'can-observation-recorder': '1.3.1', + 'can-reflect': '1.18.0', + 'can-log': '1.0.2', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-make-map', + 'version': '1.2.2', + 'fileUrl': './node_modules/can-make-map/package.json', + 'main': 'can-make-map', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-make-map' + }, + 'resolutions': {} + }, + { + 'name': 'can-namespace', + 'version': '1.0.0', + 'fileUrl': './node_modules/can-namespace/package.json', + 'main': 'can-namespace', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': {} + }, + { + 'name': 'can-log', + 'version': '1.0.2', + 'fileUrl': './node_modules/can-log/package.json', + 'main': 'can-log', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-log' + }, + 'resolutions': { 'can-log': '1.0.2' } + }, + { + 'name': 'can-fragment', + 'version': '1.3.1', + 'fileUrl': './node_modules/can-fragment/package.json', + 'main': 'can-fragment', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-globals': '1.2.2', + 'can-namespace': '1.0.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-child-nodes': '1.2.1' + } + }, + { + 'name': 'can-string-to-any', + 'version': '1.2.1', + 'fileUrl': './node_modules/can-string-to-any/package.json', + 'main': 'can-string-to-any', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-string-to-any' + }, + 'resolutions': {} + }, + { + 'name': 'can-symbol', + 'version': '1.6.5', + 'fileUrl': './node_modules/can-symbol/package.json', + 'main': 'can-symbol', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-symbol' + }, + 'resolutions': { 'can-namespace': '1.0.0' } + }, + { + 'name': 'can-test-helpers', + 'version': '1.1.4', + 'fileUrl': './node_modules/can-test-helpers/package.json', + 'main': 'can-test-helpers.js', + 'resolutions': { + 'can-test-helpers': '1.1.4', + 'can-log': '1.0.2', + 'can-reflect': '1.18.0', + 'can-global': '1.0.1' + } + }, + { + 'name': 'can-observation-recorder', + 'version': '1.3.1', + 'fileUrl': './node_modules/can-observation-recorder/package.json', + 'main': './can-observation-recorder.js', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-observation', + 'version': '4.2.0', + 'fileUrl': './node_modules/can-observation/package.json', + 'main': 'can-observation', + 'steal': { 'npmAlgorithm': 'flat' }, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-reflect': '1.18.0', + 'can-queues': '1.3.2', + 'can-observation-recorder': '1.3.1', + 'can-symbol': '1.6.5', + 'can-log': '1.0.2', + 'can-event-queue': '1.1.8', + 'can-observation': '4.2.0' + } + }, + { + 'name': 'can-attribute-encoder', + 'version': '1.1.4', + 'fileUrl': './node_modules/can-attribute-encoder/package.json', + 'main': 'can-attribute-encoder', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'steal-tools': true + }, + 'main': 'can-attribute-encoder' + }, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-log': '1.0.2' + } + }, + { + 'name': 'can-reflect-tests', + 'version': '1.0.0', + 'fileUrl': './node_modules/can-reflect-tests/package.json', + 'main': 'can-reflect-tests', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ], + 'main': 'can-reflect-tests' + }, + 'resolutions': { + 'can-reflect-tests': '1.0.0', + 'steal-qunit': '2.0.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5' + } + }, + { + 'name': 'can-set-legacy', + 'version': '1.0.1', + 'fileUrl': './node_modules/can-set-legacy/package.json', + 'main': 'can-set-legacy', + 'resolutions': { + 'can-query-logic': '1.2.2', + 'can-reflect': '1.18.0', + 'can-key': '1.2.1' + } + }, + { + 'name': 'can-stache-helpers', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-stache-helpers/package.json', + 'main': 'can-stache-helpers', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { 'can-namespace': '1.0.0' } + }, + { + 'name': '@feathersjs/feathers', + 'version': '3.3.1', + 'fileUrl': './node_modules/@feathersjs/feathers/package.json', + 'main': 'lib/index.js', + 'resolutions': { + '@feathersjs/feathers': '3.3.1', + '@feathersjs/commons': '4.5.11', + 'uberproto': '2.0.6', + 'debug': '4.3.2' + } + }, + { + 'name': '@feathersjs/socketio-client', + 'version': '1.2.1', + 'fileUrl': './node_modules/@feathersjs/socketio-client/package.json', + 'main': 'lib/index.js', + 'resolutions': { '@feathersjs/transport-commons': '4.5.11' } + }, + { + 'name': 'es6-promise-polyfill', + 'version': '1.2.0', + 'fileUrl': './node_modules/es6-promise-polyfill/package.json', + 'main': 'promise.js', + 'resolutions': {} + }, + { + 'name': 'socket.io-client', + 'version': '2.4.0', + 'fileUrl': './node_modules/socket.io-client/package.json', + 'main': './lib/index', + 'resolutions': { + 'socket.io-client': '2.4.0', + 'socket.io-parser': '3.3.2', + 'debug': '3.1.0', + 'engine.io-client': '3.5.2', + 'parseuri': '0.0.6', + 'indexof': '0.0.1', + 'component-bind': '1.0.0', + 'backo2': '1.0.2', + 'component-emitter': '1.3.0', + 'to-array': '0.1.4', + 'has-binary2': '1.0.3', + 'parseqs': '0.0.6' + } + }, + { + 'name': 'jquery', + 'version': '3.6.0', + 'fileUrl': './node_modules/jquery/package.json', + 'main': 'dist/jquery.js', + 'resolutions': {} + }, + { + 'name': 'object-assign', + 'version': '4.1.1', + 'fileUrl': './node_modules/object-assign/package.json', + 'resolutions': {} + }, + { + 'name': 'steal-css', + 'version': '1.3.2', + 'fileUrl': './node_modules/steal-css/package.json', + 'main': 'css.js', + 'steal': { + 'ext': { 'css': 'steal-css' }, + 'map': { '$css': 'steal-css@1.3.2#css' } + }, + 'resolutions': {} + }, + { + 'name': 'can-stache', + 'version': '5.1.1', + 'fileUrl': './node_modules/can-stache/package.json', + 'main': 'can-stache', + 'resolutions': { + 'can-view-parser': '4.1.3', + 'can-view-callbacks': '5.0.0', + 'can-stache': '5.1.1', + 'can-attribute-encoder': '1.1.4', + 'can-log': '1.0.2', + 'can-namespace': '1.0.0', + 'can-globals': '1.2.2', + 'can-assign': '1.3.3', + 'can-reflect': '1.18.0', + 'can-view-scope': '4.13.6', + 'can-observation-recorder': '1.3.1', + 'can-symbol': '1.6.5', + 'can-view-target': '5.0.0', + 'can-stache-ast': '1.1.0', + 'can-import-module': '1.2.0', + 'can-view-live': '5.0.4', + 'can-dom-mutate': '2.0.8', + 'can-observation': '4.2.0', + 'can-fragment': '1.3.1', + 'can-define-lazy-value': '1.1.1', + 'can-stache-key': '1.4.3', + 'can-stache-helpers': '1.2.0', + 'can-dom-data': '1.0.3', + 'can-simple-observable': '2.5.0', + 'can-join-uris': '1.2.0' + } + }, + { + 'name': 'qunit', + 'version': '2.17.2', + 'fileUrl': './node_modules/qunit/package.json', + 'main': 'qunit/qunit.js', + 'resolutions': { 'steal-qunit': '2.0.0' } + }, + { + 'name': 'can-observe', + 'version': '2.3.2', + 'fileUrl': './node_modules/can-observe/package.json', + 'main': 'can-observe.js', + 'resolutions': { + 'can-observe': '2.3.2', + 'can-reflect': '1.18.0', + 'can-observation-recorder': '1.3.1', + 'can-event-queue': '1.1.8', + 'can-globals': '1.2.2', + 'can-symbol': '1.6.5', + 'can-observation': '4.2.0', + 'can-simple-observable': '2.5.0', + 'can-queues': '1.3.2' + } + }, + { + 'name': 'can-data-types', + 'version': '1.2.1', + 'fileUrl': './node_modules/can-data-types/package.json', + 'main': 'can-data-types', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-data-types' + }, + 'resolutions': { 'can-reflect': '1.18.0' } + }, + { + 'name': 'can-dom-data', + 'version': '1.0.3', + 'fileUrl': './node_modules/can-dom-data/package.json', + 'main': 'can-dom-data.js', + 'steal': { + 'npmIgnore': { + 'steal-tools': true, + 'testee': true + }, + 'main': 'can-dom-data' + }, + 'resolutions': { 'can-namespace': '1.0.0' } + }, + { + 'name': 'can-view-callbacks', + 'version': '5.0.0', + 'fileUrl': './node_modules/can-view-callbacks/package.json', + 'main': 'can-view-callbacks', + 'resolutions': { + 'can-observation-recorder': '1.3.1', + 'can-log': '1.0.2', + 'can-globals': '1.2.2', + 'can-dom-mutate': '2.0.8', + 'can-namespace': '1.0.0', + 'can-fragment': '1.3.1', + 'can-symbol': '1.6.5', + 'can-reflect': '1.18.0' + } + }, + { + 'name': 'can-string', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-string/package.json', + 'main': 'can-string', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ] + }, + 'resolutions': {} + }, + { + 'name': 'can-vdom', + 'version': '4.4.2', + 'fileUrl': './node_modules/can-vdom/package.json', + 'main': 'can-vdom.js', + 'steal': { + 'map': { 'can-vdom@4.4.2#assert': 'chai/chai' }, + 'meta': { + 'chai/chai': { + 'format': 'global', + 'exports': 'chai.assert' + } + }, + 'plugins': ['chai'], + 'main': 'can-vdom' + }, + 'resolutions': { + 'can-simple-dom': '1.7.1', + 'can-vdom': '4.4.2', + 'can-view-parser': '4.1.3' + } + }, + { + 'name': 'can-child-nodes', + 'version': '1.2.1', + 'fileUrl': './node_modules/can-child-nodes/package.json', + 'main': 'can-child-nodes', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { 'can-namespace': '1.0.0' } + }, + { + 'name': 'can-connect', + 'version': '4.0.2', + 'fileUrl': './node_modules/can-connect/package.json', + 'main': 'can-connect.js', + 'steal': { + 'plugins': [ + 'steal-stache', + 'steal-css' + ] + }, + 'resolutions': { + 'can-connect': '4.0.2', + 'can-namespace': '1.0.0', + 'can-event-queue': '1.1.8', + 'can-reflect': '1.18.0', + 'can-diff': '1.5.0', + 'can-queues': '1.3.2', + 'can-symbol': '1.6.5', + 'can-query-logic': '1.2.2', + 'can-log': '1.0.2', + 'can-key': '1.2.1', + 'can-ajax': '2.4.6', + 'can-validate-interface': '1.0.3', + 'can-make-rest': '0.1.4' + } + }, + { + 'name': 'can-single-reference', + 'version': '1.3.0', + 'fileUrl': './node_modules/can-single-reference/package.json', + 'main': 'can-single-reference', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + } + }, + 'resolutions': { 'can-cid': '1.3.1' } + }, + { + 'name': 'can-diff', + 'version': '1.5.0', + 'fileUrl': './node_modules/can-diff/package.json', + 'main': 'can-diff', + 'steal': { 'main': 'can-diff' }, + 'resolutions': { + 'can-reflect': '1.18.0', + 'can-diff': '1.5.0', + 'can-key-tree': '1.2.2', + 'can-symbol': '1.6.5', + 'can-queues': '1.3.2' + } + }, + { + 'name': 'can-cid', + 'version': '1.3.1', + 'fileUrl': './node_modules/can-cid/package.json', + 'main': 'can-cid', + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-cid': '1.3.1' + } + }, + { + 'name': 'can-types', + 'version': '1.4.0', + 'fileUrl': './node_modules/can-types/package.json', + 'main': 'can-types', + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-reflect': '1.18.0', + 'can-symbol': '1.6.5', + 'can-log': '1.0.2' + } + }, + { + 'name': '@feathersjs/commons', + 'version': '4.5.11', + 'fileUrl': './node_modules/@feathersjs/commons/package.json', + 'main': 'lib/', + 'resolutions': { '@feathersjs/commons': '4.5.11' } + }, + { + 'name': '@feathersjs/transport-commons', + 'version': '4.5.11', + 'fileUrl': './node_modules/@feathersjs/transport-commons/package.json', + 'main': 'lib/', + 'resolutions': { + '@feathersjs/transport-commons': '4.5.11', + 'debug': '4.3.2', + '@feathersjs/errors': '4.5.11' + } + }, + { + 'name': 'uberproto', + 'version': '2.0.6', + 'fileUrl': './node_modules/uberproto/package.json', + 'main': 'lib/proto', + 'resolutions': {} + }, + { + 'name': 'socket.io-parser', + 'version': '3.3.2', + 'fileUrl': './node_modules/socket.io-parser/package.json', + 'resolutions': { + 'debug': '3.1.0', + 'socket.io-parser': '3.3.2', + 'component-emitter': '1.3.0', + 'isarray': '2.0.1' + } + }, + { + 'name': 'kefir', + 'version': '3.8.8', + 'fileUrl': './node_modules/kefir/package.json', + 'main': 'dist/kefir.js', + 'resolutions': {} + }, + { + 'name': 'validate.js', + 'version': '0.11.1', + 'fileUrl': './node_modules/validate.js/package.json', + 'main': 'validate.js', + 'resolutions': {} + }, + { + 'name': 'he', + 'version': '1.2.0', + 'fileUrl': './node_modules/he/package.json', + 'main': 'he.js', + 'resolutions': {} + }, + { + 'name': 'simple-html-tokenizer', + 'version': '0.2.6', + 'fileUrl': './node_modules/simple-html-tokenizer/package.json', + 'main': 'dist/simple-html-tokenizer.js', + 'resolutions': { 'simple-html-tokenizer': '0.2.6' } + }, + { + 'name': 'can-global', + 'version': '1.0.1', + 'fileUrl': './node_modules/can-global/package.json', + 'main': 'dist/cjs/can-global', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'main': 'can-global' + }, + 'resolutions': {} + }, + { + 'name': 'can-attribute-observable', + 'version': '2.0.2', + 'fileUrl': './node_modules/can-attribute-observable/package.json', + 'main': 'can-attribute-observable', + 'resolutions': { + 'can-globals': '1.2.2', + 'can-dom-data': '1.0.3', + 'can-log': '1.0.2', + 'can-dom-events': '1.3.11', + 'can-dom-mutate': '2.0.8', + 'can-diff': '1.5.0', + 'can-queues': '1.3.2', + 'can-attribute-observable': '2.0.2', + 'can-reflect': '1.18.0', + 'can-observation': '4.2.0', + 'can-reflect-dependencies': '1.1.2', + 'can-observation-recorder': '1.3.1', + 'can-simple-observable': '2.5.0', + 'can-assign': '1.3.3', + 'can-symbol': '1.6.5', + 'can-event-dom-radiochange': '2.2.1' + } + }, + { + 'name': 'can-stache-ast', + 'version': '1.1.0', + 'fileUrl': './node_modules/can-stache-ast/package.json', + 'main': 'can-stache-ast.js', + 'resolutions': { + 'can-stache-ast': '1.1.0', + 'can-view-parser': '4.1.3' + } + }, + { + 'name': 'can-import-module', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-import-module/package.json', + 'main': 'can-import-module.js', + 'resolutions': { + 'can-globals': '1.2.2', + 'can-namespace': '1.0.0' + } + }, + { + 'name': 'can-memory-store', + 'version': '1.0.3', + 'fileUrl': './node_modules/can-memory-store/package.json', + 'main': 'can-memory-store', + 'resolutions': { + 'can-reflect': '1.18.0', + 'can-namespace': '1.0.0', + 'can-memory-store': '1.0.3' + } + }, + { + 'name': 'debug', + 'version': '4.3.2', + 'fileUrl': './node_modules/debug/package.json', + 'main': './src/index.js', + 'browser': './src/browser.js', + 'resolutions': { + 'debug': '4.3.2', + 'ms': '2.1.2' + } + }, + { + 'name': 'debug', + 'version': '3.1.0', + 'fileUrl': './node_modules/socket.io-client/node_modules/debug/package.json', + 'main': './src/index.js', + 'browser': './src/browser.js', + 'resolutions': { + 'debug': '3.1.0', + 'ms': '2.0.0' + } + }, + { + 'name': 'micro-location', + 'version': '0.1.5', + 'fileUrl': './node_modules/micro-location/package.json', + 'main': 'lib/micro-location.js', + 'resolutions': {} + }, + { + 'name': 'can-make-rest', + 'version': '0.1.4', + 'fileUrl': './node_modules/can-make-rest/package.json', + 'main': './can-make-rest.js', + 'steal': { + 'npmIgnore': { + 'testee': true, + 'generator-donejs': true, + 'donejs-cli': true, + 'steal-tools': true + }, + 'plugins': [ + 'steal-less', + 'steal-stache' + ], + 'main': 'can-make-rest' + }, + 'browser': {}, + 'resolutions': { 'can-reflect': '1.18.0' } + }, + { + 'name': 'can-join-uris', + 'version': '1.2.0', + 'fileUrl': './node_modules/can-join-uris/package.json', + 'main': 'can-join-uris', + 'steal': {}, + 'resolutions': { + 'can-namespace': '1.0.0', + 'can-parse-uri': '1.2.2' + } + }, + { + 'name': 'component-emitter', + 'version': '1.3.0', + 'fileUrl': './node_modules/component-emitter/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': '@feathersjs/errors', + 'version': '4.5.11', + 'fileUrl': './node_modules/@feathersjs/errors/package.json', + 'main': 'lib/index', + 'resolutions': { 'debug': '4.3.2' } + }, + { + 'name': 'engine.io-client', + 'version': '3.5.2', + 'fileUrl': './node_modules/engine.io-client/package.json', + 'main': 'lib/index.js', + 'browser': { + 'ws': '@empty', + 'xmlhttprequest-ssl': 'engine.io-client#lib/xmlhttprequest', + 'engine.io-client#lib/globalThis': 'engine.io-client#lib/globalThis.browser' + }, + 'resolutions': { + 'engine.io-client': '3.5.2', + 'engine.io-parser': '2.2.1', + 'component-emitter': '1.3.0', + 'debug': '3.1.0', + 'indexof': '0.0.1', + 'parseuri': '0.0.6', + 'parseqs': '0.0.6', + 'has-cors': '1.1.0', + 'component-inherit': '0.0.3', + 'yeast': '0.1.2' + } + }, + { + 'name': 'parseuri', + 'version': '0.0.6', + 'fileUrl': './node_modules/parseuri/package.json', + 'resolutions': {} + }, + { + 'name': 'indexof', + 'version': '0.0.1', + 'fileUrl': './node_modules/indexof/package.json', + 'resolutions': {} + }, + { + 'name': 'component-bind', + 'version': '1.0.0', + 'fileUrl': './node_modules/component-bind/package.json', + 'resolutions': {} + }, + { + 'name': 'backo2', + 'version': '1.0.2', + 'fileUrl': './node_modules/backo2/package.json', + 'resolutions': {} + }, + { + 'name': 'to-array', + 'version': '0.1.4', + 'fileUrl': './node_modules/to-array/package.json', + 'main': 'index', + 'resolutions': {} + }, + { + 'name': 'has-binary2', + 'version': '1.0.3', + 'fileUrl': './node_modules/has-binary2/package.json', + 'resolutions': { 'isarray': '2.0.1' } + }, + { + 'name': 'parseqs', + 'version': '0.0.6', + 'fileUrl': './node_modules/parseqs/package.json', + 'resolutions': {} + }, + { + 'name': 'isarray', + 'version': '2.0.1', + 'fileUrl': './node_modules/socket.io-parser/node_modules/isarray/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'ms', + 'version': '2.1.2', + 'fileUrl': './node_modules/ms/package.json', + 'main': './index', + 'resolutions': {} + }, + { + 'name': 'engine.io-parser', + 'version': '2.2.1', + 'fileUrl': './node_modules/engine.io-parser/package.json', + 'main': 'lib/index.js', + 'browser': './lib/browser.js', + 'resolutions': { + 'engine.io-parser': '2.2.1', + 'has-binary2': '1.0.3', + 'after': '0.8.2', + 'arraybuffer.slice': '0.0.7', + 'base64-arraybuffer': '0.1.4', + 'blob': '0.0.5' + } + }, + { + 'name': 'ms', + 'version': '2.0.0', + 'fileUrl': './node_modules/socket.io-client/node_modules/ms/package.json', + 'main': './index', + 'resolutions': {} + }, + { + 'name': 'after', + 'version': '0.8.2', + 'fileUrl': './node_modules/after/package.json', + 'resolutions': {} + }, + { + 'name': 'arraybuffer.slice', + 'version': '0.0.7', + 'fileUrl': './node_modules/arraybuffer.slice/package.json', + 'resolutions': {} + }, + { + 'name': 'base64-arraybuffer', + 'version': '0.1.4', + 'fileUrl': './node_modules/base64-arraybuffer/package.json', + 'main': 'lib/base64-arraybuffer', + 'resolutions': {} + }, + { + 'name': 'blob', + 'version': '0.0.5', + 'fileUrl': './node_modules/blob/package.json', + 'resolutions': {} + }, + { + 'name': 'has-cors', + 'version': '1.1.0', + 'fileUrl': './node_modules/has-cors/package.json', + 'main': 'index.js', + 'resolutions': {} + }, + { + 'name': 'component-inherit', + 'version': '0.0.3', + 'fileUrl': './node_modules/component-inherit/package.json', + 'resolutions': {} + }, + { + 'name': 'yeast', + 'version': '0.1.2', + 'fileUrl': './node_modules/yeast/package.json', + 'main': 'index.js', + 'resolutions': {} + } + ], { 'npmParentMap': { '@feathersjs/feathers@3.3.1#lib/hooks': '@feathersjs/feathers@3.3.1#lib/hooks/index' } })); +}); +/*steal-qunit@2.0.0#add-dom*/ +define('steal-qunit@2.0.0#add-dom', function (require, exports, module) { + 'format cjs'; + if (!document.getElementById('qunit')) { + var qunit = document.createElement('div'); + qunit.id = 'qunit'; + (document.body || document.documentElement).appendChild(qunit); + } +}); +/*qunit@2.17.2#qunit/qunit*/ +define('qunit@2.17.2#qunit/qunit', [ + 'module', + '@loader', + 'require', + 'steal-qunit/add-dom' +], function (module, loader, require) { + loader.get('@@global-helpers').prepareGlobal({ + require: require, + name: module.id, + deps: ['steal-qunit/add-dom'], + exports: 'QUnit' + }); + var define = loader.global.define; + var require = loader.global.require; + var source = '/*!\n * QUnit 2.17.2\n * https://qunitjs.com/\n *\n * Copyright OpenJS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n */\n(function () {\n \'use strict\';\n\n // Support IE 9-10, Safari 7, PhantomJS: Partial Map fallback.\n // Used by html.js (via fuzzysort.js), and test.js.\n //\n // FIXME: This check is broken. This file is embedded in the qunit.js closure,\n // thus the Map var is hoisted in that scope, and starts undefined (not a function).\n var Map = typeof Map === "function" ? Map : function StringMap() {\n \tvar store = Object.create( null );\n \tvar hasOwn = Object.prototype.hasOwnProperty;\n \tthis.get = function( strKey ) {\n \t\treturn store[ strKey ];\n \t};\n \tthis.set = function( strKey, val ) {\n \t\tif ( !hasOwn.call( store, strKey ) ) {\n \t\t\tthis.size++;\n \t\t}\n \t\tstore[ strKey ] = val;\n \t\treturn this;\n \t};\n \tthis.delete = function( strKey ) {\n \t\tif ( hasOwn.call( store, strKey ) ) {\n \t\t\tdelete store[ strKey ];\n \t\t\tthis.size--;\n \t\t}\n \t};\n \tthis.forEach = function( callback ) {\n \t\tfor ( var strKey in store ) {\n \t\t\tcallback( store[ strKey ], strKey );\n \t\t}\n \t};\n \tthis.clear = function() {\n \t\tstore = Object.create( null );\n \t\tthis.size = 0;\n \t};\n \tthis.size = 0;\n };\n\n function _typeof(obj) {\n "@babel/helpers - typeof";\n\n if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {\n _typeof = function (obj) {\n return typeof obj;\n };\n } else {\n _typeof = function (obj) {\n return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;\n };\n }\n\n return _typeof(obj);\n }\n\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError("Cannot call a class as a function");\n }\n }\n\n function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if ("value" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n }\n\n function _slicedToArray(arr, i) {\n return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n }\n\n function _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n }\n\n function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n }\n\n function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n }\n\n function _iterableToArray(iter) {\n if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);\n }\n\n function _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i["return"] != null) _i["return"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n }\n\n function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === "string") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === "Object" && o.constructor) n = o.constructor.name;\n if (n === "Map" || n === "Set") return Array.from(o);\n if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n }\n\n function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n return arr2;\n }\n\n function _nonIterableSpread() {\n throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n }\n\n function _nonIterableRest() {\n throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n }\n\n function _createForOfIteratorHelper(o, allowArrayLike) {\n var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];\n\n if (!it) {\n if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {\n if (it) o = it;\n var i = 0;\n\n var F = function () {};\n\n return {\n s: F,\n n: function () {\n if (i >= o.length) return {\n done: true\n };\n return {\n done: false,\n value: o[i++]\n };\n },\n e: function (e) {\n throw e;\n },\n f: F\n };\n }\n\n throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n }\n\n var normalCompletion = true,\n didErr = false,\n err;\n return {\n s: function () {\n it = it.call(o);\n },\n n: function () {\n var step = it.next();\n normalCompletion = step.done;\n return step;\n },\n e: function (e) {\n didErr = true;\n err = e;\n },\n f: function () {\n try {\n if (!normalCompletion && it.return != null) it.return();\n } finally {\n if (didErr) throw err;\n }\n }\n };\n }\n\n /*\n https://github.com/ungap/global-this/blob/v0.4.4/esm/index.js\n\n Copyright (c) 2020, Andrea Giammarchi, @WebReflection\n\n Permission to use, copy, modify, and/or distribute this software for any\n purpose with or without fee is hereby granted, provided that the above\n copyright notice and this permission notice appear in all copies.\n\n THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\n REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\n AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\n INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\n LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE\n OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n PERFORMANCE OF THIS SOFTWARE.\n\n -------\n\n Patches for use in QUnit:\n\n - 2021-02-25: Export as module only, don\'t change global scope as QUnit must not\n affect the host context (e.g. people may test their application intentionally\n with different or no polyfills and we must not affect that).\n\n */\n var foundGlobalThis;\n\n (function (Object) {\n if ((typeof globalThis === "undefined" ? "undefined" : _typeof(globalThis)) === "object") {\n foundGlobalThis = globalThis;\n } else {\n var get = function get() {\n foundGlobalThis = this || self;\n delete Object.prototype._T_;\n };\n\n this ? get() : (Object.defineProperty(Object.prototype, "_T_", {\n configurable: true,\n get: get\n }), _T_);\n }\n })(Object);\n\n var globalThis$1 = foundGlobalThis;\n\n var window$1 = globalThis$1.window;\n var self$1 = globalThis$1.self;\n var console$1 = globalThis$1.console;\n var setTimeout$1 = globalThis$1.setTimeout;\n var clearTimeout = globalThis$1.clearTimeout;\n var document = window$1 && window$1.document;\n var navigator = window$1 && window$1.navigator;\n var localSessionStorage = function () {\n var x = "qunit-test-string";\n\n try {\n globalThis$1.sessionStorage.setItem(x, x);\n globalThis$1.sessionStorage.removeItem(x);\n return globalThis$1.sessionStorage;\n } catch (e) {\n return undefined;\n }\n }();\n\n // Detect if the console object exists and no-op otherwise.\n // This allows support for IE 9, which doesn\'t have a console\n // object if the developer tools are not open.\n // Support: IE 9\n // Function#bind is supported, but no console.log.bind().\n // Support: SpiderMonkey (mozjs 68+)\n // The console object has a log method, but no warn method.\n\n var Logger = {\n warn: console$1 ? Function.prototype.bind.call(console$1.warn || console$1.log, console$1) : function () {}\n };\n\n var toString = Object.prototype.toString;\n var hasOwn$1 = Object.prototype.hasOwnProperty;\n var now = Date.now || function () {\n return new Date().getTime();\n };\n var nativePerf = getNativePerf();\n\n function getNativePerf() {\n if (window$1 && typeof window$1.performance !== "undefined" && typeof window$1.performance.mark === "function" && typeof window$1.performance.measure === "function") {\n return window$1.performance;\n } else {\n return undefined;\n }\n }\n\n var performance = {\n now: nativePerf ? nativePerf.now.bind(nativePerf) : now,\n measure: nativePerf ? function (comment, startMark, endMark) {\n // `performance.measure` may fail if the mark could not be found.\n // reasons a specific mark could not be found include: outside code invoking `performance.clearMarks()`\n try {\n nativePerf.measure(comment, startMark, endMark);\n } catch (ex) {\n Logger.warn("performance.measure could not be executed because of ", ex.message);\n }\n } : function () {},\n mark: nativePerf ? nativePerf.mark.bind(nativePerf) : function () {}\n }; // Returns a new Array with the elements that are in a but not in b\n\n function diff(a, b) {\n var result = a.slice();\n\n for (var i = 0; i < result.length; i++) {\n for (var j = 0; j < b.length; j++) {\n if (result[i] === b[j]) {\n result.splice(i, 1);\n i--;\n break;\n }\n }\n }\n\n return result;\n }\n /**\n * Determines whether an element exists in a given array or not.\n *\n * @method inArray\n * @param {any} elem\n * @param {Array} array\n * @return {boolean}\n */\n\n function inArray(elem, array) {\n return array.indexOf(elem) !== -1;\n }\n /**\n * Makes a clone of an object using only Array or Object as base,\n * and copies over the own enumerable properties.\n *\n * @param {Object} obj\n * @return {Object} New object with only the own properties (recursively).\n */\n\n function objectValues(obj) {\n var vals = is("array", obj) ? [] : {};\n\n for (var key in obj) {\n if (hasOwn$1.call(obj, key)) {\n var val = obj[key];\n vals[key] = val === Object(val) ? objectValues(val) : val;\n }\n }\n\n return vals;\n }\n function extend(a, b, undefOnly) {\n for (var prop in b) {\n if (hasOwn$1.call(b, prop)) {\n if (b[prop] === undefined) {\n delete a[prop];\n } else if (!(undefOnly && typeof a[prop] !== "undefined")) {\n a[prop] = b[prop];\n }\n }\n }\n\n return a;\n }\n function objectType(obj) {\n if (typeof obj === "undefined") {\n return "undefined";\n } // Consider: typeof null === object\n\n\n if (obj === null) {\n return "null";\n }\n\n var match = toString.call(obj).match(/^\\[object\\s(.*)\\]$/);\n var type = match && match[1];\n\n switch (type) {\n case "Number":\n if (isNaN(obj)) {\n return "nan";\n }\n\n return "number";\n\n case "String":\n case "Boolean":\n case "Array":\n case "Set":\n case "Map":\n case "Date":\n case "RegExp":\n case "Function":\n case "Symbol":\n return type.toLowerCase();\n\n default:\n return _typeof(obj);\n }\n } // Safe object type checking\n\n function is(type, obj) {\n return objectType(obj) === type;\n } // Based on Java\'s String.hashCode, a simple but not\n // rigorously collision resistant hashing function\n\n function generateHash(module, testName) {\n var str = module + "\\x1C" + testName;\n var hash = 0;\n\n for (var i = 0; i < str.length; i++) {\n hash = (hash << 5) - hash + str.charCodeAt(i);\n hash |= 0;\n } // Convert the possibly negative integer hash code into an 8 character hex string, which isn\'t\n // strictly necessary but increases user understanding that the id is a SHA-like hash\n\n\n var hex = (0x100000000 + hash).toString(16);\n\n if (hex.length < 8) {\n hex = "0000000" + hex;\n }\n\n return hex.slice(-8);\n }\n /**\n * Converts an error into a simple string for comparisons.\n *\n * @param {Error|any} error\n * @return {string}\n */\n\n function errorString(error) {\n // Use String() instead of toString() to handle non-object values like undefined or null.\n var resultErrorString = String(error); // If the error wasn\'t a subclass of Error but something like\n // an object literal with name and message properties...\n\n if (resultErrorString.slice(0, 7) === "[object") {\n // Based on https://es5.github.io/#x15.11.4.4\n return (error.name || "Error") + (error.message ? ": ".concat(error.message) : "");\n } else {\n return resultErrorString;\n }\n }\n\n // Authors: Philippe Rathé , David Chan \n\n var equiv = (function () {\n // Value pairs queued for comparison. Used for breadth-first processing order, recursion\n // detection and avoiding repeated comparison (see below for details).\n // Elements are { a: val, b: val }.\n var pairs = [];\n\n var getProto = Object.getPrototypeOf || function (obj) {\n return obj.__proto__;\n };\n\n function useStrictEquality(a, b) {\n // This only gets called if a and b are not strict equal, and is used to compare on\n // the primitive values inside object wrappers. For example:\n // `var i = 1;`\n // `var j = new Number(1);`\n // Neither a nor b can be null, as a !== b and they have the same type.\n if (_typeof(a) === "object") {\n a = a.valueOf();\n }\n\n if (_typeof(b) === "object") {\n b = b.valueOf();\n }\n\n return a === b;\n }\n\n function compareConstructors(a, b) {\n var protoA = getProto(a);\n var protoB = getProto(b); // Comparing constructors is more strict than using `instanceof`\n\n if (a.constructor === b.constructor) {\n return true;\n } // Ref #851\n // If the obj prototype descends from a null constructor, treat it\n // as a null prototype.\n\n\n if (protoA && protoA.constructor === null) {\n protoA = null;\n }\n\n if (protoB && protoB.constructor === null) {\n protoB = null;\n } // Allow objects with no prototype to be equivalent to\n // objects with Object as their constructor.\n\n\n if (protoA === null && protoB === Object.prototype || protoB === null && protoA === Object.prototype) {\n return true;\n }\n\n return false;\n }\n\n function getRegExpFlags(regexp) {\n return "flags" in regexp ? regexp.flags : regexp.toString().match(/[gimuy]*$/)[0];\n }\n\n function isContainer(val) {\n return ["object", "array", "map", "set"].indexOf(objectType(val)) !== -1;\n }\n\n function breadthFirstCompareChild(a, b) {\n // If a is a container not reference-equal to b, postpone the comparison to the\n // end of the pairs queue -- unless (a, b) has been seen before, in which case skip\n // over the pair.\n if (a === b) {\n return true;\n }\n\n if (!isContainer(a)) {\n return typeEquiv(a, b);\n }\n\n if (pairs.every(function (pair) {\n return pair.a !== a || pair.b !== b;\n })) {\n // Not yet started comparing this pair\n pairs.push({\n a: a,\n b: b\n });\n }\n\n return true;\n }\n\n var callbacks = {\n "string": useStrictEquality,\n "boolean": useStrictEquality,\n "number": useStrictEquality,\n "null": useStrictEquality,\n "undefined": useStrictEquality,\n "symbol": useStrictEquality,\n "date": useStrictEquality,\n "nan": function nan() {\n return true;\n },\n "regexp": function regexp(a, b) {\n return a.source === b.source && // Include flags in the comparison\n getRegExpFlags(a) === getRegExpFlags(b);\n },\n // abort (identical references / instance methods were skipped earlier)\n "function": function _function() {\n return false;\n },\n "array": function array(a, b) {\n var len = a.length;\n\n if (len !== b.length) {\n // Safe and faster\n return false;\n }\n\n for (var i = 0; i < len; i++) {\n // Compare non-containers; queue non-reference-equal containers\n if (!breadthFirstCompareChild(a[i], b[i])) {\n return false;\n }\n }\n\n return true;\n },\n // Define sets a and b to be equivalent if for each element aVal in a, there\n // is some element bVal in b such that aVal and bVal are equivalent. Element\n // repetitions are not counted, so these are equivalent:\n // a = new Set( [ {}, [], [] ] );\n // b = new Set( [ {}, {}, [] ] );\n "set": function set(a, b) {\n if (a.size !== b.size) {\n // This optimization has certain quirks because of the lack of\n // repetition counting. For instance, adding the same\n // (reference-identical) element to two equivalent sets can\n // make them non-equivalent.\n return false;\n }\n\n var outerEq = true;\n a.forEach(function (aVal) {\n // Short-circuit if the result is already known. (Using for...of\n // with a break clause would be cleaner here, but it would cause\n // a syntax error on older JavaScript implementations even if\n // Set is unused)\n if (!outerEq) {\n return;\n }\n\n var innerEq = false;\n b.forEach(function (bVal) {\n // Likewise, short-circuit if the result is already known\n if (innerEq) {\n return;\n } // Swap out the global pairs list, as the nested call to\n // innerEquiv will clobber its contents\n\n\n var parentPairs = pairs;\n\n if (innerEquiv(bVal, aVal)) {\n innerEq = true;\n } // Replace the global pairs list\n\n\n pairs = parentPairs;\n });\n\n if (!innerEq) {\n outerEq = false;\n }\n });\n return outerEq;\n },\n // Define maps a and b to be equivalent if for each key-value pair (aKey, aVal)\n // in a, there is some key-value pair (bKey, bVal) in b such that\n // [ aKey, aVal ] and [ bKey, bVal ] are equivalent. Key repetitions are not\n // counted, so these are equivalent:\n // a = new Map( [ [ {}, 1 ], [ {}, 1 ], [ [], 1 ] ] );\n // b = new Map( [ [ {}, 1 ], [ [], 1 ], [ [], 1 ] ] );\n "map": function map(a, b) {\n if (a.size !== b.size) {\n // This optimization has certain quirks because of the lack of\n // repetition counting. For instance, adding the same\n // (reference-identical) key-value pair to two equivalent maps\n // can make them non-equivalent.\n return false;\n }\n\n var outerEq = true;\n a.forEach(function (aVal, aKey) {\n // Short-circuit if the result is already known. (Using for...of\n // with a break clause would be cleaner here, but it would cause\n // a syntax error on older JavaScript implementations even if\n // Map is unused)\n if (!outerEq) {\n return;\n }\n\n var innerEq = false;\n b.forEach(function (bVal, bKey) {\n // Likewise, short-circuit if the result is already known\n if (innerEq) {\n return;\n } // Swap out the global pairs list, as the nested call to\n // innerEquiv will clobber its contents\n\n\n var parentPairs = pairs;\n\n if (innerEquiv([bVal, bKey], [aVal, aKey])) {\n innerEq = true;\n } // Replace the global pairs list\n\n\n pairs = parentPairs;\n });\n\n if (!innerEq) {\n outerEq = false;\n }\n });\n return outerEq;\n },\n "object": function object(a, b) {\n if (compareConstructors(a, b) === false) {\n return false;\n }\n\n var aProperties = [];\n var bProperties = []; // Be strict: don\'t ensure hasOwnProperty and go deep\n\n for (var i in a) {\n // Collect a\'s properties\n aProperties.push(i); // Skip OOP methods that look the same\n\n if (a.constructor !== Object && typeof a.constructor !== "undefined" && typeof a[i] === "function" && typeof b[i] === "function" && a[i].toString() === b[i].toString()) {\n continue;\n } // Compare non-containers; queue non-reference-equal containers\n\n\n if (!breadthFirstCompareChild(a[i], b[i])) {\n return false;\n }\n }\n\n for (var _i in b) {\n // Collect b\'s properties\n bProperties.push(_i);\n } // Ensures identical properties name\n\n\n return typeEquiv(aProperties.sort(), bProperties.sort());\n }\n };\n\n function typeEquiv(a, b) {\n var type = objectType(a); // Callbacks for containers will append to the pairs queue to achieve breadth-first\n // search order. The pairs queue is also used to avoid reprocessing any pair of\n // containers that are reference-equal to a previously visited pair (a special case\n // this being recursion detection).\n //\n // Because of this approach, once typeEquiv returns a false value, it should not be\n // called again without clearing the pair queue else it may wrongly report a visited\n // pair as being equivalent.\n\n return objectType(b) === type && callbacks[type](a, b);\n }\n\n function innerEquiv(a, b) {\n // We\'re done when there\'s nothing more to compare\n if (arguments.length < 2) {\n return true;\n } // Clear the global pair queue and add the top-level values being compared\n\n\n pairs = [{\n a: a,\n b: b\n }];\n\n for (var i = 0; i < pairs.length; i++) {\n var pair = pairs[i]; // Perform type-specific comparison on any pairs that are not strictly\n // equal. For container types, that comparison will postpone comparison\n // of any sub-container pair to the end of the pair queue. This gives\n // breadth-first search order. It also avoids the reprocessing of\n // reference-equal siblings, cousins etc, which can have a significant speed\n // impact when comparing a container of small objects each of which has a\n // reference to the same (singleton) large object.\n\n if (pair.a !== pair.b && !typeEquiv(pair.a, pair.b)) {\n return false;\n }\n } // ...across all consecutive argument pairs\n\n\n return arguments.length === 2 || innerEquiv.apply(this, [].slice.call(arguments, 1));\n }\n\n return function () {\n var result = innerEquiv.apply(void 0, arguments); // Release any retained objects\n\n pairs.length = 0;\n return result;\n };\n })();\n\n /**\n * Config object: Maintain internal state\n * Later exposed as QUnit.config\n * `config` initialized at top of scope\n */\n\n var config = {\n // The queue of tests to run\n queue: [],\n stats: {\n all: 0,\n bad: 0,\n testCount: 0\n },\n // Block until document ready\n blocking: true,\n // whether or not to fail when there are zero tests\n // defaults to `true`\n failOnZeroTests: true,\n // By default, run previously failed tests first\n // very useful in combination with "Hide passed tests" checked\n reorder: true,\n // By default, modify document.title when suite is done\n altertitle: true,\n // HTML Reporter: collapse every test except the first failing test\n // If false, all failing tests will be expanded\n collapse: true,\n // By default, scroll to top of the page when suite is done\n scrolltop: true,\n // Depth up-to which object will be dumped\n maxDepth: 5,\n // When enabled, all tests must call expect()\n requireExpects: false,\n // Placeholder for user-configurable form-exposed URL parameters\n urlConfig: [],\n // Set of all modules.\n modules: [],\n // The first unnamed module\n currentModule: {\n name: "",\n tests: [],\n childModules: [],\n testsRun: 0,\n testsIgnored: 0,\n hooks: {\n before: [],\n beforeEach: [],\n afterEach: [],\n after: []\n }\n },\n callbacks: {},\n // The storage module to use for reordering tests\n storage: localSessionStorage\n }; // take a predefined QUnit.config and extend the defaults\n\n var globalConfig = window$1 && window$1.QUnit && window$1.QUnit.config; // only extend the global config if there is no QUnit overload\n\n if (window$1 && window$1.QUnit && !window$1.QUnit.version) {\n extend(config, globalConfig);\n } // Push a loose unnamed module to the modules collection\n\n\n config.modules.push(config.currentModule);\n\n var dump = (function () {\n function quote(str) {\n return "\\"" + str.toString().replace(/\\\\/g, "\\\\\\\\").replace(/"/g, "\\\\\\"") + "\\"";\n }\n\n function literal(o) {\n return o + "";\n }\n\n function join(pre, arr, post) {\n var s = dump.separator();\n var inner = dump.indent(1);\n\n if (arr.join) {\n arr = arr.join("," + s + inner);\n }\n\n if (!arr) {\n return pre + post;\n }\n\n var base = dump.indent();\n return [pre, inner + arr, base + post].join(s);\n }\n\n function array(arr, stack) {\n if (dump.maxDepth && dump.depth > dump.maxDepth) {\n return "[object Array]";\n }\n\n this.up();\n var i = arr.length;\n var ret = new Array(i);\n\n while (i--) {\n ret[i] = this.parse(arr[i], undefined, stack);\n }\n\n this.down();\n return join("[", ret, "]");\n }\n\n function isArray(obj) {\n return (//Native Arrays\n toString.call(obj) === "[object Array]" || // NodeList objects\n typeof obj.length === "number" && obj.item !== undefined && (obj.length ? obj.item(0) === obj[0] : obj.item(0) === null && obj[0] === undefined)\n );\n }\n\n var reName = /^function (\\w+)/;\n var dump = {\n // The objType is used mostly internally, you can fix a (custom) type in advance\n parse: function parse(obj, objType, stack) {\n stack = stack || [];\n var objIndex = stack.indexOf(obj);\n\n if (objIndex !== -1) {\n return "recursion(".concat(objIndex - stack.length, ")");\n }\n\n objType = objType || this.typeOf(obj);\n var parser = this.parsers[objType];\n\n var parserType = _typeof(parser);\n\n if (parserType === "function") {\n stack.push(obj);\n var res = parser.call(this, obj, stack);\n stack.pop();\n return res;\n }\n\n if (parserType === "string") {\n return parser;\n }\n\n return "[ERROR: Missing QUnit.dump formatter for type " + objType + "]";\n },\n typeOf: function typeOf(obj) {\n var type;\n\n if (obj === null) {\n type = "null";\n } else if (typeof obj === "undefined") {\n type = "undefined";\n } else if (is("regexp", obj)) {\n type = "regexp";\n } else if (is("date", obj)) {\n type = "date";\n } else if (is("function", obj)) {\n type = "function";\n } else if (obj.setInterval !== undefined && obj.document !== undefined && obj.nodeType === undefined) {\n type = "window";\n } else if (obj.nodeType === 9) {\n type = "document";\n } else if (obj.nodeType) {\n type = "node";\n } else if (isArray(obj)) {\n type = "array";\n } else if (obj.constructor === Error.prototype.constructor) {\n type = "error";\n } else {\n type = _typeof(obj);\n }\n\n return type;\n },\n separator: function separator() {\n if (this.multiline) {\n return this.HTML ? "
" : "\\n";\n } else {\n return this.HTML ? " " : " ";\n }\n },\n // Extra can be a number, shortcut for increasing-calling-decreasing\n indent: function indent(extra) {\n if (!this.multiline) {\n return "";\n }\n\n var chr = this.indentChar;\n\n if (this.HTML) {\n chr = chr.replace(/\\t/g, " ").replace(/ /g, " ");\n }\n\n return new Array(this.depth + (extra || 0)).join(chr);\n },\n up: function up(a) {\n this.depth += a || 1;\n },\n down: function down(a) {\n this.depth -= a || 1;\n },\n setParser: function setParser(name, parser) {\n this.parsers[name] = parser;\n },\n // The next 3 are exposed so you can use them\n quote: quote,\n literal: literal,\n join: join,\n depth: 1,\n maxDepth: config.maxDepth,\n // This is the list of parsers, to modify them, use dump.setParser\n parsers: {\n window: "[Window]",\n document: "[Document]",\n error: function error(_error) {\n return "Error(\\"" + _error.message + "\\")";\n },\n // This has been unused since QUnit 1.0.0.\n // @todo Deprecate and remove.\n unknown: "[Unknown]",\n "null": "null",\n "undefined": "undefined",\n "function": function _function(fn) {\n var ret = "function"; // Functions never have name in IE\n\n var name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];\n\n if (name) {\n ret += " " + name;\n }\n\n ret += "(";\n ret = [ret, dump.parse(fn, "functionArgs"), "){"].join("");\n return join(ret, dump.parse(fn, "functionCode"), "}");\n },\n array: array,\n nodelist: array,\n "arguments": array,\n object: function object(map, stack) {\n var ret = [];\n\n if (dump.maxDepth && dump.depth > dump.maxDepth) {\n return "[object Object]";\n }\n\n dump.up();\n var keys = [];\n\n for (var key in map) {\n keys.push(key);\n } // Some properties are not always enumerable on Error objects.\n\n\n var nonEnumerableProperties = ["message", "name"];\n\n for (var i in nonEnumerableProperties) {\n var _key = nonEnumerableProperties[i];\n\n if (_key in map && !inArray(_key, keys)) {\n keys.push(_key);\n }\n }\n\n keys.sort();\n\n for (var _i = 0; _i < keys.length; _i++) {\n var _key2 = keys[_i];\n var val = map[_key2];\n ret.push(dump.parse(_key2, "key") + ": " + dump.parse(val, undefined, stack));\n }\n\n dump.down();\n return join("{", ret, "}");\n },\n node: function node(_node) {\n var open = dump.HTML ? "<" : "<";\n var close = dump.HTML ? ">" : ">";\n\n var tag = _node.nodeName.toLowerCase();\n\n var ret = open + tag;\n var attrs = _node.attributes;\n\n if (attrs) {\n for (var i = 0, len = attrs.length; i < len; i++) {\n var val = attrs[i].nodeValue; // IE6 includes all attributes in .attributes, even ones not explicitly\n // set. Those have values like undefined, null, 0, false, "" or\n // "inherit".\n\n if (val && val !== "inherit") {\n ret += " " + attrs[i].nodeName + "=" + dump.parse(val, "attribute");\n }\n }\n }\n\n ret += close; // Show content of TextNode or CDATASection\n\n if (_node.nodeType === 3 || _node.nodeType === 4) {\n ret += _node.nodeValue;\n }\n\n return ret + open + "/" + tag + close;\n },\n // Function calls it internally, it\'s the arguments part of the function\n functionArgs: function functionArgs(fn) {\n var l = fn.length;\n\n if (!l) {\n return "";\n }\n\n var args = new Array(l);\n\n while (l--) {\n // 97 is \'a\'\n args[l] = String.fromCharCode(97 + l);\n }\n\n return " " + args.join(", ") + " ";\n },\n // Object calls it internally, the key part of an item in a map\n key: quote,\n // Function calls it internally, it\'s the content of the function\n functionCode: "[code]",\n // Node calls it internally, it\'s a html attribute value\n attribute: quote,\n string: quote,\n date: quote,\n regexp: literal,\n number: literal,\n "boolean": literal,\n symbol: function symbol(sym) {\n return sym.toString();\n }\n },\n // If true, entities are escaped ( <, >, \\t, space and \\n )\n HTML: false,\n // Indentation unit\n indentChar: " ",\n // If true, items in a collection, are separated by a \\n, else just a space.\n multiline: true\n };\n return dump;\n })();\n\n var SuiteReport = /*#__PURE__*/function () {\n function SuiteReport(name, parentSuite) {\n _classCallCheck(this, SuiteReport);\n\n this.name = name;\n this.fullName = parentSuite ? parentSuite.fullName.concat(name) : []; // When an "error" event is emitted from onUncaughtException(), the\n // "runEnd" event should report the status as failed.\n // The "runEnd" event data is made by this class (as "globalSuite").\n\n this.globalFailureCount = 0;\n this.tests = [];\n this.childSuites = [];\n\n if (parentSuite) {\n parentSuite.pushChildSuite(this);\n }\n }\n\n _createClass(SuiteReport, [{\n key: "start",\n value: function start(recordTime) {\n if (recordTime) {\n this._startTime = performance.now();\n var suiteLevel = this.fullName.length;\n performance.mark("qunit_suite_".concat(suiteLevel, "_start"));\n }\n\n return {\n name: this.name,\n fullName: this.fullName.slice(),\n tests: this.tests.map(function (test) {\n return test.start();\n }),\n childSuites: this.childSuites.map(function (suite) {\n return suite.start();\n }),\n testCounts: {\n total: this.getTestCounts().total\n }\n };\n }\n }, {\n key: "end",\n value: function end(recordTime) {\n if (recordTime) {\n this._endTime = performance.now();\n var suiteLevel = this.fullName.length;\n var suiteName = this.fullName.join(" \u2013 ");\n performance.mark("qunit_suite_".concat(suiteLevel, "_end"));\n performance.measure(suiteLevel === 0 ? "QUnit Test Run" : "QUnit Test Suite: ".concat(suiteName), "qunit_suite_".concat(suiteLevel, "_start"), "qunit_suite_".concat(suiteLevel, "_end"));\n }\n\n return {\n name: this.name,\n fullName: this.fullName.slice(),\n tests: this.tests.map(function (test) {\n return test.end();\n }),\n childSuites: this.childSuites.map(function (suite) {\n return suite.end();\n }),\n testCounts: this.getTestCounts(),\n runtime: this.getRuntime(),\n status: this.getStatus()\n };\n }\n }, {\n key: "pushChildSuite",\n value: function pushChildSuite(suite) {\n this.childSuites.push(suite);\n }\n }, {\n key: "pushTest",\n value: function pushTest(test) {\n this.tests.push(test);\n }\n }, {\n key: "getRuntime",\n value: function getRuntime() {\n return this._endTime - this._startTime;\n }\n }, {\n key: "getTestCounts",\n value: function getTestCounts() {\n var counts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {\n passed: 0,\n failed: 0,\n skipped: 0,\n todo: 0,\n total: 0\n };\n counts.failed += this.globalFailureCount;\n counts.total += this.globalFailureCount;\n counts = this.tests.reduce(function (counts, test) {\n if (test.valid) {\n counts[test.getStatus()]++;\n counts.total++;\n }\n\n return counts;\n }, counts);\n return this.childSuites.reduce(function (counts, suite) {\n return suite.getTestCounts(counts);\n }, counts);\n }\n }, {\n key: "getStatus",\n value: function getStatus() {\n var _this$getTestCounts = this.getTestCounts(),\n total = _this$getTestCounts.total,\n failed = _this$getTestCounts.failed,\n skipped = _this$getTestCounts.skipped,\n todo = _this$getTestCounts.todo;\n\n if (failed) {\n return "failed";\n } else {\n if (skipped === total) {\n return "skipped";\n } else if (todo === total) {\n return "todo";\n } else {\n return "passed";\n }\n }\n }\n }]);\n\n return SuiteReport;\n }();\n\n var moduleStack = [];\n\n function isParentModuleInQueue() {\n var modulesInQueue = config.modules.filter(function (module) {\n return !module.ignored;\n }).map(function (module) {\n return module.moduleId;\n });\n return moduleStack.some(function (module) {\n return modulesInQueue.includes(module.moduleId);\n });\n }\n\n function createModule(name, testEnvironment, modifiers) {\n var parentModule = moduleStack.length ? moduleStack.slice(-1)[0] : null;\n var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;\n var parentSuite = parentModule ? parentModule.suiteReport : globalSuite;\n var skip = parentModule !== null && parentModule.skip || modifiers.skip;\n var todo = parentModule !== null && parentModule.todo || modifiers.todo;\n var module = {\n name: moduleName,\n parentModule: parentModule,\n tests: [],\n moduleId: generateHash(moduleName),\n testsRun: 0,\n testsIgnored: 0,\n childModules: [],\n suiteReport: new SuiteReport(name, parentSuite),\n // Pass along `skip` and `todo` properties from parent module, in case\n // there is one, to childs. And use own otherwise.\n // This property will be used to mark own tests and tests of child suites\n // as either `skipped` or `todo`.\n skip: skip,\n todo: skip ? false : todo,\n ignored: modifiers.ignored || false\n };\n var env = {};\n\n if (parentModule) {\n parentModule.childModules.push(module);\n extend(env, parentModule.testEnvironment);\n }\n\n extend(env, testEnvironment);\n module.testEnvironment = env;\n config.modules.push(module);\n return module;\n }\n\n function processModule(name, options, executeNow) {\n var modifiers = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};\n\n if (objectType(options) === "function") {\n executeNow = options;\n options = undefined;\n }\n\n var module = createModule(name, options, modifiers); // Move any hooks to a \'hooks\' object\n\n var testEnvironment = module.testEnvironment;\n var hooks = module.hooks = {};\n setHookFromEnvironment(hooks, testEnvironment, "before");\n setHookFromEnvironment(hooks, testEnvironment, "beforeEach");\n setHookFromEnvironment(hooks, testEnvironment, "afterEach");\n setHookFromEnvironment(hooks, testEnvironment, "after");\n var moduleFns = {\n before: setHookFunction(module, "before"),\n beforeEach: setHookFunction(module, "beforeEach"),\n afterEach: setHookFunction(module, "afterEach"),\n after: setHookFunction(module, "after")\n };\n var prevModule = config.currentModule;\n config.currentModule = module;\n\n if (objectType(executeNow) === "function") {\n moduleStack.push(module);\n\n try {\n var cbReturnValue = executeNow.call(module.testEnvironment, moduleFns);\n\n if (cbReturnValue != null && objectType(cbReturnValue.then) === "function") {\n Logger.warn("Returning a promise from a module callback is not supported. " + "Instead, use hooks for async behavior. " + "This will become an error in QUnit 3.0.");\n }\n } finally {\n // If the module closure threw an uncaught error during the load phase,\n // we let this bubble up to global error handlers. But, not until after\n // we teardown internal state to ensure correct module nesting.\n // Ref https://github.com/qunitjs/qunit/issues/1478.\n moduleStack.pop();\n config.currentModule = module.parentModule || prevModule;\n }\n }\n\n function setHookFromEnvironment(hooks, environment, name) {\n var potentialHook = environment[name];\n hooks[name] = typeof potentialHook === "function" ? [potentialHook] : [];\n delete environment[name];\n }\n\n function setHookFunction(module, hookName) {\n return function setHook(callback) {\n if (config.currentModule !== module) {\n Logger.warn("The `" + hookName + "` hook was called inside the wrong module (`" + config.currentModule.name + "`). " + "Instead, use hooks provided by the callback to the containing module (`" + module.name + "`). " + "This will become an error in QUnit 3.0.");\n }\n\n module.hooks[hookName].push(callback);\n };\n }\n }\n\n var focused$1 = false; // indicates that the "only" filter was used\n\n function module$1(name, options, executeNow) {\n var ignored = focused$1 && !isParentModuleInQueue();\n processModule(name, options, executeNow, {\n ignored: ignored\n });\n }\n\n module$1.only = function () {\n if (!focused$1) {\n // Upon the first module.only() call,\n // delete any and all previously registered modules and tests.\n config.modules.length = 0;\n config.queue.length = 0; // Ignore any tests declared after this block within the same\n // module parent. https://github.com/qunitjs/qunit/issues/1645\n\n config.currentModule.ignored = true;\n }\n\n focused$1 = true;\n processModule.apply(void 0, arguments);\n };\n\n module$1.skip = function (name, options, executeNow) {\n if (focused$1) {\n return;\n }\n\n processModule(name, options, executeNow, {\n skip: true\n });\n };\n\n module$1.todo = function (name, options, executeNow) {\n if (focused$1) {\n return;\n }\n\n processModule(name, options, executeNow, {\n todo: true\n });\n };\n\n var LISTENERS = Object.create(null);\n var SUPPORTED_EVENTS = ["error", "runStart", "suiteStart", "testStart", "assertion", "testEnd", "suiteEnd", "runEnd"];\n /**\n * Emits an event with the specified data to all currently registered listeners.\n * Callbacks will fire in the order in which they are registered (FIFO). This\n * function is not exposed publicly; it is used by QUnit internals to emit\n * logging events.\n *\n * @private\n * @method emit\n * @param {string} eventName\n * @param {Object} data\n * @return {void}\n */\n\n function emit(eventName, data) {\n if (objectType(eventName) !== "string") {\n throw new TypeError("eventName must be a string when emitting an event");\n } // Clone the callbacks in case one of them registers a new callback\n\n\n var originalCallbacks = LISTENERS[eventName];\n var callbacks = originalCallbacks ? _toConsumableArray(originalCallbacks) : [];\n\n for (var i = 0; i < callbacks.length; i++) {\n callbacks[i](data);\n }\n }\n /**\n * Registers a callback as a listener to the specified event.\n *\n * @public\n * @method on\n * @param {string} eventName\n * @param {Function} callback\n * @return {void}\n */\n\n function on(eventName, callback) {\n if (objectType(eventName) !== "string") {\n throw new TypeError("eventName must be a string when registering a listener");\n } else if (!inArray(eventName, SUPPORTED_EVENTS)) {\n var events = SUPPORTED_EVENTS.join(", ");\n throw new Error("\\"".concat(eventName, "\\" is not a valid event; must be one of: ").concat(events, "."));\n } else if (objectType(callback) !== "function") {\n throw new TypeError("callback must be a function when registering a listener");\n }\n\n if (!LISTENERS[eventName]) {\n LISTENERS[eventName] = [];\n } // Don\'t register the same callback more than once\n\n\n if (!inArray(callback, LISTENERS[eventName])) {\n LISTENERS[eventName].push(callback);\n }\n }\n\n var commonjsGlobal = typeof globalThis !== \'undefined\' ? globalThis : typeof window !== \'undefined\' ? window : typeof global !== \'undefined\' ? global : typeof self !== \'undefined\' ? self : {};\n\n function commonjsRequire (path) {\n \tthrow new Error(\'Could not dynamically require "\' + path + \'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.\');\n }\n\n var promisePolyfill = {exports: {}};\n\n (function () {\n /** @suppress {undefinedVars} */\n\n var globalNS = function () {\n // the only reliable means to get the global object is\n // `Function(\'return this\')()`\n // However, this causes CSP violations in Chrome apps.\n if (typeof globalThis !== \'undefined\') {\n return globalThis;\n }\n\n if (typeof self !== \'undefined\') {\n return self;\n }\n\n if (typeof window !== \'undefined\') {\n return window;\n }\n\n if (typeof commonjsGlobal !== \'undefined\') {\n return commonjsGlobal;\n }\n\n throw new Error(\'unable to locate global object\');\n }(); // Expose the polyfill if Promise is undefined or set to a\n // non-function value. The latter can be due to a named HTMLElement\n // being exposed by browsers for legacy reasons.\n // https://github.com/taylorhakes/promise-polyfill/issues/114\n\n\n if (typeof globalNS[\'Promise\'] === \'function\') {\n promisePolyfill.exports = globalNS[\'Promise\'];\n return;\n }\n /**\n * @this {Promise}\n */\n\n\n function finallyConstructor(callback) {\n var constructor = this.constructor;\n return this.then(function (value) {\n // @ts-ignore\n return constructor.resolve(callback()).then(function () {\n return value;\n });\n }, function (reason) {\n // @ts-ignore\n return constructor.resolve(callback()).then(function () {\n // @ts-ignore\n return constructor.reject(reason);\n });\n });\n }\n\n function allSettled(arr) {\n var P = this;\n return new P(function (resolve, reject) {\n if (!(arr && typeof arr.length !== \'undefined\')) {\n return reject(new TypeError(_typeof(arr) + \' \' + arr + \' is not iterable(cannot read property Symbol(Symbol.iterator))\'));\n }\n\n var args = Array.prototype.slice.call(arr);\n if (args.length === 0) return resolve([]);\n var remaining = args.length;\n\n function res(i, val) {\n if (val && (_typeof(val) === \'object\' || typeof val === \'function\')) {\n var then = val.then;\n\n if (typeof then === \'function\') {\n then.call(val, function (val) {\n res(i, val);\n }, function (e) {\n args[i] = {\n status: \'rejected\',\n reason: e\n };\n\n if (--remaining === 0) {\n resolve(args);\n }\n });\n return;\n }\n }\n\n args[i] = {\n status: \'fulfilled\',\n value: val\n };\n\n if (--remaining === 0) {\n resolve(args);\n }\n }\n\n for (var i = 0; i < args.length; i++) {\n res(i, args[i]);\n }\n });\n } // Store setTimeout reference so promise-polyfill will be unaffected by\n // other code modifying setTimeout (like sinon.useFakeTimers())\n\n\n var setTimeoutFunc = setTimeout;\n\n function isArray(x) {\n return Boolean(x && typeof x.length !== \'undefined\');\n }\n\n function noop() {} // Polyfill for Function.prototype.bind\n\n\n function bind(fn, thisArg) {\n return function () {\n fn.apply(thisArg, arguments);\n };\n }\n /**\n * @constructor\n * @param {Function} fn\n */\n\n\n function Promise(fn) {\n if (!(this instanceof Promise)) throw new TypeError(\'Promises must be constructed via new\');\n if (typeof fn !== \'function\') throw new TypeError(\'not a function\');\n /** @type {!number} */\n\n this._state = 0;\n /** @type {!boolean} */\n\n this._handled = false;\n /** @type {Promise|undefined} */\n\n this._value = undefined;\n /** @type {!Array} */\n\n this._deferreds = [];\n doResolve(fn, this);\n }\n\n function handle(self, deferred) {\n while (self._state === 3) {\n self = self._value;\n }\n\n if (self._state === 0) {\n self._deferreds.push(deferred);\n\n return;\n }\n\n self._handled = true;\n\n Promise._immediateFn(function () {\n var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;\n\n if (cb === null) {\n (self._state === 1 ? resolve : reject)(deferred.promise, self._value);\n return;\n }\n\n var ret;\n\n try {\n ret = cb(self._value);\n } catch (e) {\n reject(deferred.promise, e);\n return;\n }\n\n resolve(deferred.promise, ret);\n });\n }\n\n function resolve(self, newValue) {\n try {\n // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure\n if (newValue === self) throw new TypeError(\'A promise cannot be resolved with itself.\');\n\n if (newValue && (_typeof(newValue) === \'object\' || typeof newValue === \'function\')) {\n var then = newValue.then;\n\n if (newValue instanceof Promise) {\n self._state = 3;\n self._value = newValue;\n finale(self);\n return;\n } else if (typeof then === \'function\') {\n doResolve(bind(then, newValue), self);\n return;\n }\n }\n\n self._state = 1;\n self._value = newValue;\n finale(self);\n } catch (e) {\n reject(self, e);\n }\n }\n\n function reject(self, newValue) {\n self._state = 2;\n self._value = newValue;\n finale(self);\n }\n\n function finale(self) {\n if (self._state === 2 && self._deferreds.length === 0) {\n Promise._immediateFn(function () {\n if (!self._handled) {\n Promise._unhandledRejectionFn(self._value);\n }\n });\n }\n\n for (var i = 0, len = self._deferreds.length; i < len; i++) {\n handle(self, self._deferreds[i]);\n }\n\n self._deferreds = null;\n }\n /**\n * @constructor\n */\n\n\n function Handler(onFulfilled, onRejected, promise) {\n this.onFulfilled = typeof onFulfilled === \'function\' ? onFulfilled : null;\n this.onRejected = typeof onRejected === \'function\' ? onRejected : null;\n this.promise = promise;\n }\n /**\n * Take a potentially misbehaving resolver function and make sure\n * onFulfilled and onRejected are only called once.\n *\n * Makes no guarantees about asynchrony.\n */\n\n\n function doResolve(fn, self) {\n var done = false;\n\n try {\n fn(function (value) {\n if (done) return;\n done = true;\n resolve(self, value);\n }, function (reason) {\n if (done) return;\n done = true;\n reject(self, reason);\n });\n } catch (ex) {\n if (done) return;\n done = true;\n reject(self, ex);\n }\n }\n\n Promise.prototype[\'catch\'] = function (onRejected) {\n return this.then(null, onRejected);\n };\n\n Promise.prototype.then = function (onFulfilled, onRejected) {\n // @ts-ignore\n var prom = new this.constructor(noop);\n handle(this, new Handler(onFulfilled, onRejected, prom));\n return prom;\n };\n\n Promise.prototype[\'finally\'] = finallyConstructor;\n\n Promise.all = function (arr) {\n return new Promise(function (resolve, reject) {\n if (!isArray(arr)) {\n return reject(new TypeError(\'Promise.all accepts an array\'));\n }\n\n var args = Array.prototype.slice.call(arr);\n if (args.length === 0) return resolve([]);\n var remaining = args.length;\n\n function res(i, val) {\n try {\n if (val && (_typeof(val) === \'object\' || typeof val === \'function\')) {\n var then = val.then;\n\n if (typeof then === \'function\') {\n then.call(val, function (val) {\n res(i, val);\n }, reject);\n return;\n }\n }\n\n args[i] = val;\n\n if (--remaining === 0) {\n resolve(args);\n }\n } catch (ex) {\n reject(ex);\n }\n }\n\n for (var i = 0; i < args.length; i++) {\n res(i, args[i]);\n }\n });\n };\n\n Promise.allSettled = allSettled;\n\n Promise.resolve = function (value) {\n if (value && _typeof(value) === \'object\' && value.constructor === Promise) {\n return value;\n }\n\n return new Promise(function (resolve) {\n resolve(value);\n });\n };\n\n Promise.reject = function (value) {\n return new Promise(function (resolve, reject) {\n reject(value);\n });\n };\n\n Promise.race = function (arr) {\n return new Promise(function (resolve, reject) {\n if (!isArray(arr)) {\n return reject(new TypeError(\'Promise.race accepts an array\'));\n }\n\n for (var i = 0, len = arr.length; i < len; i++) {\n Promise.resolve(arr[i]).then(resolve, reject);\n }\n });\n }; // Use polyfill for setImmediate for performance gains\n\n\n Promise._immediateFn = // @ts-ignore\n typeof setImmediate === \'function\' && function (fn) {\n // @ts-ignore\n setImmediate(fn);\n } || function (fn) {\n setTimeoutFunc(fn, 0);\n };\n\n Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {\n if (typeof console !== \'undefined\' && console) {\n console.warn(\'Possible Unhandled Promise Rejection:\', err); // eslint-disable-line no-console\n }\n };\n\n promisePolyfill.exports = Promise;\n })();\n\n var _Promise = promisePolyfill.exports;\n\n function registerLoggingCallbacks(obj) {\n var callbackNames = ["begin", "done", "log", "testStart", "testDone", "moduleStart", "moduleDone"];\n\n function registerLoggingCallback(key) {\n var loggingCallback = function loggingCallback(callback) {\n if (objectType(callback) !== "function") {\n throw new Error("QUnit logging methods require a callback function as their first parameters.");\n }\n\n config.callbacks[key].push(callback);\n };\n\n return loggingCallback;\n }\n\n for (var i = 0, l = callbackNames.length; i < l; i++) {\n var key = callbackNames[i]; // Initialize key collection of logging callback\n\n if (objectType(config.callbacks[key]) === "undefined") {\n config.callbacks[key] = [];\n }\n\n obj[key] = registerLoggingCallback(key);\n }\n }\n function runLoggingCallbacks(key, args) {\n var callbacks = config.callbacks[key]; // Handling \'log\' callbacks separately. Unlike the other callbacks,\n // the log callback is not controlled by the processing queue,\n // but rather used by asserts. Hence to promisfy the \'log\' callback\n // would mean promisfying each step of a test\n\n if (key === "log") {\n callbacks.map(function (callback) {\n return callback(args);\n });\n return;\n } // ensure that each callback is executed serially\n\n\n return callbacks.reduce(function (promiseChain, callback) {\n return promiseChain.then(function () {\n return _Promise.resolve(callback(args));\n });\n }, _Promise.resolve([]));\n }\n\n // Doesn\'t support IE9, it will return undefined on these browsers\n // See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack\n var fileName = (sourceFromStacktrace(0) || "").replace(/(:\\d+)+\\)?/, "").replace(/.+\\//, "");\n function extractStacktrace(e, offset) {\n offset = offset === undefined ? 4 : offset;\n\n if (e && e.stack) {\n var stack = e.stack.split("\\n");\n\n if (/^error$/i.test(stack[0])) {\n stack.shift();\n }\n\n if (fileName) {\n var include = [];\n\n for (var i = offset; i < stack.length; i++) {\n if (stack[i].indexOf(fileName) !== -1) {\n break;\n }\n\n include.push(stack[i]);\n }\n\n if (include.length) {\n return include.join("\\n");\n }\n }\n\n return stack[offset];\n }\n }\n function sourceFromStacktrace(offset) {\n var error = new Error(); // Support: Safari <=7 only, IE <=10 - 11 only\n // Not all browsers generate the `stack` property for `new Error()`, see also #636\n\n if (!error.stack) {\n try {\n throw error;\n } catch (err) {\n error = err;\n }\n }\n\n return extractStacktrace(error, offset);\n }\n\n var priorityCount = 0;\n var unitSampler; // This is a queue of functions that are tasks within a single test.\n // After tests are dequeued from config.queue they are expanded into\n // a set of tasks in this queue.\n\n var taskQueue = [];\n /**\n * Advances the taskQueue to the next task. If the taskQueue is empty,\n * process the testQueue\n */\n\n function advance() {\n advanceTaskQueue();\n\n if (!taskQueue.length && !config.blocking && !config.current) {\n advanceTestQueue();\n }\n }\n /**\n * Advances the taskQueue with an increased depth\n */\n\n\n function advanceTaskQueue() {\n var start = now();\n config.depth = (config.depth || 0) + 1;\n processTaskQueue(start);\n config.depth--;\n }\n /**\n * Process the first task on the taskQueue as a promise.\n * Each task is a function added by Test#queue() in /src/test.js\n */\n\n\n function processTaskQueue(start) {\n if (taskQueue.length && !config.blocking) {\n var elapsedTime = now() - start;\n\n if (!setTimeout$1 || config.updateRate <= 0 || elapsedTime < config.updateRate) {\n var task = taskQueue.shift();\n _Promise.resolve(task()).then(function () {\n if (!taskQueue.length) {\n advance();\n } else {\n processTaskQueue(start);\n }\n });\n } else {\n setTimeout$1(advance);\n }\n }\n }\n /**\n * Advance the testQueue to the next test to process. Call done() if testQueue completes.\n */\n\n\n function advanceTestQueue() {\n if (!config.blocking && !config.queue.length && config.depth === 0) {\n done();\n return;\n }\n\n var testTasks = config.queue.shift();\n addToTaskQueue(testTasks());\n\n if (priorityCount > 0) {\n priorityCount--;\n }\n\n advance();\n }\n /**\n * Enqueue the tasks for a test into the task queue.\n * @param {Array} tasksArray\n */\n\n\n function addToTaskQueue(tasksArray) {\n taskQueue.push.apply(taskQueue, _toConsumableArray(tasksArray));\n }\n /**\n * Return the number of tasks remaining in the task queue to be processed.\n * @return {number}\n */\n\n\n function taskQueueLength() {\n return taskQueue.length;\n }\n /**\n * Adds a test to the TestQueue for execution.\n * @param {Function} testTasksFunc\n * @param {boolean} prioritize\n * @param {string} seed\n */\n\n\n function addToTestQueue(testTasksFunc, prioritize, seed) {\n if (prioritize) {\n config.queue.splice(priorityCount++, 0, testTasksFunc);\n } else if (seed) {\n if (!unitSampler) {\n unitSampler = unitSamplerGenerator(seed);\n } // Insert into a random position after all prioritized items\n\n\n var index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1));\n config.queue.splice(priorityCount + index, 0, testTasksFunc);\n } else {\n config.queue.push(testTasksFunc);\n }\n }\n /**\n * Creates a seeded "sample" generator which is used for randomizing tests.\n */\n\n\n function unitSamplerGenerator(seed) {\n // 32-bit xorshift, requires only a nonzero seed\n // https://excamera.com/sphinx/article-xorshift.html\n var sample = parseInt(generateHash(seed), 16) || -1;\n return function () {\n sample ^= sample << 13;\n sample ^= sample >>> 17;\n sample ^= sample << 5; // ECMAScript has no unsigned number type\n\n if (sample < 0) {\n sample += 0x100000000;\n }\n\n return sample / 0x100000000;\n };\n }\n /**\n * This function is called when the ProcessingQueue is done processing all\n * items. It handles emitting the final run events.\n */\n\n\n function done() {\n // We have reached the end of the processing queue and are about to emit the\n // "runEnd" event after which reporters typically stop listening and exit\n // the process. First, check if we need to emit one final test.\n if (config.stats.testCount === 0 && config.failOnZeroTests === true) {\n var error;\n\n if (config.filter && config.filter.length) {\n error = new Error("No tests matched the filter \\"".concat(config.filter, "\\"."));\n } else if (config.module && config.module.length) {\n error = new Error("No tests matched the module \\"".concat(config.module, "\\"."));\n } else if (config.moduleId && config.moduleId.length) {\n error = new Error("No tests matched the moduleId \\"".concat(config.moduleId, "\\"."));\n } else if (config.testId && config.testId.length) {\n error = new Error("No tests matched the testId \\"".concat(config.testId, "\\"."));\n } else {\n error = new Error("No tests were run.");\n }\n\n test("global failure", extend(function (assert) {\n assert.pushResult({\n result: false,\n message: error.message,\n source: error.stack\n });\n }, {\n validTest: true\n })); // We do need to call `advance()` in order to resume the processing queue.\n // Once this new test is finished processing, we\'ll reach `done` again, and\n // that time the above condition will evaluate to false.\n\n advance();\n return;\n }\n\n var storage = config.storage;\n var runtime = now() - config.started;\n var passed = config.stats.all - config.stats.bad;\n ProcessingQueue.finished = true;\n emit("runEnd", globalSuite.end(true));\n runLoggingCallbacks("done", {\n passed: passed,\n failed: config.stats.bad,\n total: config.stats.all,\n runtime: runtime\n }).then(function () {\n // Clear own storage items if all tests passed\n if (storage && config.stats.bad === 0) {\n for (var i = storage.length - 1; i >= 0; i--) {\n var key = storage.key(i);\n\n if (key.indexOf("qunit-test-") === 0) {\n storage.removeItem(key);\n }\n }\n }\n });\n }\n\n var ProcessingQueue = {\n finished: false,\n add: addToTestQueue,\n advance: advance,\n taskCount: taskQueueLength\n };\n\n var TestReport = /*#__PURE__*/function () {\n function TestReport(name, suite, options) {\n _classCallCheck(this, TestReport);\n\n this.name = name;\n this.suiteName = suite.name;\n this.fullName = suite.fullName.concat(name);\n this.runtime = 0;\n this.assertions = [];\n this.skipped = !!options.skip;\n this.todo = !!options.todo;\n this.valid = options.valid;\n this._startTime = 0;\n this._endTime = 0;\n suite.pushTest(this);\n }\n\n _createClass(TestReport, [{\n key: "start",\n value: function start(recordTime) {\n if (recordTime) {\n this._startTime = performance.now();\n performance.mark("qunit_test_start");\n }\n\n return {\n name: this.name,\n suiteName: this.suiteName,\n fullName: this.fullName.slice()\n };\n }\n }, {\n key: "end",\n value: function end(recordTime) {\n if (recordTime) {\n this._endTime = performance.now();\n\n if (performance) {\n performance.mark("qunit_test_end");\n var testName = this.fullName.join(" \u2013 ");\n performance.measure("QUnit Test: ".concat(testName), "qunit_test_start", "qunit_test_end");\n }\n }\n\n return extend(this.start(), {\n runtime: this.getRuntime(),\n status: this.getStatus(),\n errors: this.getFailedAssertions(),\n assertions: this.getAssertions()\n });\n }\n }, {\n key: "pushAssertion",\n value: function pushAssertion(assertion) {\n this.assertions.push(assertion);\n }\n }, {\n key: "getRuntime",\n value: function getRuntime() {\n return this._endTime - this._startTime;\n }\n }, {\n key: "getStatus",\n value: function getStatus() {\n if (this.skipped) {\n return "skipped";\n }\n\n var testPassed = this.getFailedAssertions().length > 0 ? this.todo : !this.todo;\n\n if (!testPassed) {\n return "failed";\n } else if (this.todo) {\n return "todo";\n } else {\n return "passed";\n }\n }\n }, {\n key: "getFailedAssertions",\n value: function getFailedAssertions() {\n return this.assertions.filter(function (assertion) {\n return !assertion.passed;\n });\n }\n }, {\n key: "getAssertions",\n value: function getAssertions() {\n return this.assertions.slice();\n } // Remove actual and expected values from assertions. This is to prevent\n // leaking memory throughout a test suite.\n\n }, {\n key: "slimAssertions",\n value: function slimAssertions() {\n this.assertions = this.assertions.map(function (assertion) {\n delete assertion.actual;\n delete assertion.expected;\n return assertion;\n });\n }\n }]);\n\n return TestReport;\n }();\n\n function Test(settings) {\n this.expected = null;\n this.assertions = [];\n this.module = config.currentModule;\n this.steps = [];\n this.timeout = undefined;\n this.data = undefined;\n this.withData = false;\n this.pauses = new Map();\n this.nextPauseId = 1;\n extend(this, settings); // If a module is skipped, all its tests and the tests of the child suites\n // should be treated as skipped even if they are defined as `only` or `todo`.\n // As for `todo` module, all its tests will be treated as `todo` except for\n // tests defined as `skip` which will be left intact.\n //\n // So, if a test is defined as `todo` and is inside a skipped module, we should\n // then treat that test as if was defined as `skip`.\n\n if (this.module.skip) {\n this.skip = true;\n this.todo = false; // Skipped tests should be left intact\n } else if (this.module.todo && !this.skip) {\n this.todo = true;\n } // Queuing a late test after the run has ended is not allowed.\n // This was once supported for internal use by QUnit.onError().\n // Ref https://github.com/qunitjs/qunit/issues/1377\n\n\n if (ProcessingQueue.finished) {\n // Using this for anything other than onError(), such as testing in QUnit.done(),\n // is unstable and will likely result in the added tests being ignored by CI.\n // (Meaning the CI passes irregardless of the added tests).\n //\n // TODO: Make this an error in QUnit 3.0\n // throw new Error( "Unexpected new test after the run already ended" );\n Logger.warn("Unexpected test after runEnd. This is unstable and will fail in QUnit 3.0.");\n return;\n }\n\n if (!this.skip && typeof this.callback !== "function") {\n var method = this.todo ? "QUnit.todo" : "QUnit.test";\n throw new TypeError("You must provide a callback to ".concat(method, "(\\"").concat(this.testName, "\\")"));\n } // No validation after this. Beyond this point, failures must be recorded as\n // a completed test with errors, instead of early bail out.\n // Otherwise, internals may be left in an inconsistent state.\n // Ref https://github.com/qunitjs/qunit/issues/1514\n\n\n ++Test.count;\n this.errorForStack = new Error();\n\n if (this.callback && this.callback.validTest) {\n // Omit the test-level trace for the internal "No tests" test failure,\n // There is already an assertion-level trace, and that\'s noisy enough\n // as it is.\n this.errorForStack.stack = undefined;\n }\n\n this.testReport = new TestReport(this.testName, this.module.suiteReport, {\n todo: this.todo,\n skip: this.skip,\n valid: this.valid()\n }); // Register unique strings\n\n for (var i = 0, l = this.module.tests; i < l.length; i++) {\n if (this.module.tests[i].name === this.testName) {\n this.testName += " ";\n }\n }\n\n this.testId = generateHash(this.module.name, this.testName);\n this.module.tests.push({\n name: this.testName,\n testId: this.testId,\n skip: !!this.skip\n });\n\n if (this.skip) {\n // Skipped tests will fully ignore any sent callback\n this.callback = function () {};\n\n this.async = false;\n this.expected = 0;\n } else {\n this.assert = new Assert(this);\n }\n }\n Test.count = 0;\n\n function getNotStartedModules(startModule) {\n var module = startModule;\n var modules = [];\n\n while (module && module.testsRun === 0) {\n modules.push(module);\n module = module.parentModule;\n } // The above push modules from the child to the parent\n // return a reversed order with the top being the top most parent module\n\n\n return modules.reverse();\n }\n\n Test.prototype = {\n // generating a stack trace can be expensive, so using a getter defers this until we need it\n get stack() {\n return extractStacktrace(this.errorForStack, 2);\n },\n\n before: function before() {\n var _this = this;\n\n var module = this.module;\n var notStartedModules = getNotStartedModules(module); // ensure the callbacks are executed serially for each module\n\n var callbackPromises = notStartedModules.reduce(function (promiseChain, startModule) {\n return promiseChain.then(function () {\n startModule.stats = {\n all: 0,\n bad: 0,\n started: now()\n };\n emit("suiteStart", startModule.suiteReport.start(true));\n return runLoggingCallbacks("moduleStart", {\n name: startModule.name,\n tests: startModule.tests\n });\n });\n }, _Promise.resolve([]));\n return callbackPromises.then(function () {\n config.current = _this;\n _this.testEnvironment = extend({}, module.testEnvironment);\n _this.started = now();\n emit("testStart", _this.testReport.start(true));\n return runLoggingCallbacks("testStart", {\n name: _this.testName,\n module: module.name,\n testId: _this.testId,\n previousFailure: _this.previousFailure\n }).then(function () {\n if (!config.pollution) {\n saveGlobal();\n }\n });\n });\n },\n run: function run() {\n config.current = this;\n this.callbackStarted = now();\n\n if (config.notrycatch) {\n runTest(this);\n return;\n }\n\n try {\n runTest(this);\n } catch (e) {\n this.pushFailure("Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + (e.message || e), extractStacktrace(e, 0)); // Else next test will carry the responsibility\n\n saveGlobal(); // Restart the tests if they\'re blocking\n\n if (config.blocking) {\n internalRecover(this);\n }\n }\n\n function runTest(test) {\n var promise;\n\n if (test.withData) {\n promise = test.callback.call(test.testEnvironment, test.assert, test.data);\n } else {\n promise = test.callback.call(test.testEnvironment, test.assert);\n }\n\n test.resolvePromise(promise); // If the test has an async "pause" on it, but the timeout is 0, then we push a\n // failure as the test should be synchronous.\n\n if (test.timeout === 0 && test.pauses.size > 0) {\n pushFailure("Test did not finish synchronously even though assert.timeout( 0 ) was used.", sourceFromStacktrace(2));\n }\n }\n },\n after: function after() {\n checkPollution();\n },\n queueHook: function queueHook(hook, hookName, hookOwner) {\n var _this2 = this;\n\n var callHook = function callHook() {\n var promise = hook.call(_this2.testEnvironment, _this2.assert);\n\n _this2.resolvePromise(promise, hookName);\n };\n\n var runHook = function runHook() {\n if (hookName === "before") {\n if (hookOwner.testsRun !== 0) {\n return;\n }\n\n _this2.preserveEnvironment = true;\n } // The \'after\' hook should only execute when there are not tests left and\n // when the \'after\' and \'finish\' tasks are the only tasks left to process\n\n\n if (hookName === "after" && !lastTestWithinModuleExecuted(hookOwner) && (config.queue.length > 0 || ProcessingQueue.taskCount() > 2)) {\n return;\n }\n\n config.current = _this2;\n\n if (config.notrycatch) {\n callHook();\n return;\n }\n\n try {\n callHook();\n } catch (error) {\n _this2.pushFailure(hookName + " failed on " + _this2.testName + ": " + (error.message || error), extractStacktrace(error, 0));\n }\n };\n\n return runHook;\n },\n // Currently only used for module level hooks, can be used to add global level ones\n hooks: function hooks(handler) {\n var hooks = [];\n\n function processHooks(test, module) {\n if (module.parentModule) {\n processHooks(test, module.parentModule);\n }\n\n if (module.hooks[handler].length) {\n for (var i = 0; i < module.hooks[handler].length; i++) {\n hooks.push(test.queueHook(module.hooks[handler][i], handler, module));\n }\n }\n } // Hooks are ignored on skipped tests\n\n\n if (!this.skip) {\n processHooks(this, this.module);\n }\n\n return hooks;\n },\n finish: function finish() {\n config.current = this; // Release the test callback to ensure that anything referenced has been\n // released to be garbage collected.\n\n this.callback = undefined;\n\n if (this.steps.length) {\n var stepsList = this.steps.join(", ");\n this.pushFailure("Expected assert.verifySteps() to be called before end of test " + "after using assert.step(). Unverified steps: ".concat(stepsList), this.stack);\n }\n\n if (config.requireExpects && this.expected === null) {\n this.pushFailure("Expected number of assertions to be defined, but expect() was " + "not called.", this.stack);\n } else if (this.expected !== null && this.expected !== this.assertions.length) {\n this.pushFailure("Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack);\n } else if (this.expected === null && !this.assertions.length) {\n this.pushFailure("Expected at least one assertion, but none were run - call " + "expect(0) to accept zero assertions.", this.stack);\n }\n\n var module = this.module;\n var moduleName = module.name;\n var testName = this.testName;\n var skipped = !!this.skip;\n var todo = !!this.todo;\n var bad = 0;\n var storage = config.storage;\n this.runtime = now() - this.started;\n config.stats.all += this.assertions.length;\n config.stats.testCount += 1;\n module.stats.all += this.assertions.length;\n\n for (var i = 0; i < this.assertions.length; i++) {\n // A failing assertion will counts toward the HTML Reporter\'s\n // "X assertions, Y failed" line even if it was inside a todo.\n // Inverting this would be similarly confusing since all but the last\n // passing assertion inside a todo test should be considered as good.\n // These stats don\'t decide the outcome of anything, so counting them\n // as failing seems the most intuitive.\n if (!this.assertions[i].result) {\n bad++;\n config.stats.bad++;\n module.stats.bad++;\n }\n }\n\n if (skipped) {\n incrementTestsIgnored(module);\n } else {\n incrementTestsRun(module);\n } // Store result when possible.\n // Note that this also marks todo tests as bad, thus they get hoisted,\n // and always run first on refresh.\n\n\n if (storage) {\n if (bad) {\n storage.setItem("qunit-test-" + moduleName + "-" + testName, bad);\n } else {\n storage.removeItem("qunit-test-" + moduleName + "-" + testName);\n }\n } // After emitting the js-reporters event we cleanup the assertion data to\n // avoid leaking it. It is not used by the legacy testDone callbacks.\n\n\n emit("testEnd", this.testReport.end(true));\n this.testReport.slimAssertions();\n var test = this;\n return runLoggingCallbacks("testDone", {\n name: testName,\n module: moduleName,\n skipped: skipped,\n todo: todo,\n failed: bad,\n passed: this.assertions.length - bad,\n total: this.assertions.length,\n runtime: skipped ? 0 : this.runtime,\n // HTML Reporter use\n assertions: this.assertions,\n testId: this.testId,\n\n // Source of Test\n // generating stack trace is expensive, so using a getter will help defer this until we need it\n get source() {\n return test.stack;\n }\n\n }).then(function () {\n if (allTestsExecuted(module)) {\n var completedModules = [module]; // Check if the parent modules, iteratively, are done. If that the case,\n // we emit the `suiteEnd` event and trigger `moduleDone` callback.\n\n var parent = module.parentModule;\n\n while (parent && allTestsExecuted(parent)) {\n completedModules.push(parent);\n parent = parent.parentModule;\n }\n\n return completedModules.reduce(function (promiseChain, completedModule) {\n return promiseChain.then(function () {\n return logSuiteEnd(completedModule);\n });\n }, _Promise.resolve([]));\n }\n }).then(function () {\n config.current = undefined;\n });\n\n function logSuiteEnd(module) {\n // Reset `module.hooks` to ensure that anything referenced in these hooks\n // has been released to be garbage collected. Descendant modules that were\n // entirely skipped, e.g. due to filtering, will never have this method\n // called for them, but might have hooks with references pinning data in\n // memory (even if the hooks weren\'t actually executed), so we reset the\n // hooks on all descendant modules here as well. This is safe because we\n // will never call this as long as any descendant modules still have tests\n // to run. This also means that in multi-tiered nesting scenarios we might\n // reset the hooks multiple times on some modules, but that\'s harmless.\n var modules = [module];\n\n while (modules.length) {\n var nextModule = modules.shift();\n nextModule.hooks = {};\n modules.push.apply(modules, _toConsumableArray(nextModule.childModules));\n }\n\n emit("suiteEnd", module.suiteReport.end(true));\n return runLoggingCallbacks("moduleDone", {\n name: module.name,\n tests: module.tests,\n failed: module.stats.bad,\n passed: module.stats.all - module.stats.bad,\n total: module.stats.all,\n runtime: now() - module.stats.started\n });\n }\n },\n preserveTestEnvironment: function preserveTestEnvironment() {\n if (this.preserveEnvironment) {\n this.module.testEnvironment = this.testEnvironment;\n this.testEnvironment = extend({}, this.module.testEnvironment);\n }\n },\n queue: function queue() {\n var test = this;\n\n if (!this.valid()) {\n incrementTestsIgnored(this.module);\n return;\n }\n\n function runTest() {\n return [function () {\n return test.before();\n }].concat(_toConsumableArray(test.hooks("before")), [function () {\n test.preserveTestEnvironment();\n }], _toConsumableArray(test.hooks("beforeEach")), [function () {\n test.run();\n }], _toConsumableArray(test.hooks("afterEach").reverse()), _toConsumableArray(test.hooks("after").reverse()), [function () {\n test.after();\n }, function () {\n return test.finish();\n }]);\n }\n\n var previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName); // Prioritize previously failed tests, detected from storage\n\n var prioritize = config.reorder && !!previousFailCount;\n this.previousFailure = !!previousFailCount;\n ProcessingQueue.add(runTest, prioritize, config.seed);\n },\n pushResult: function pushResult(resultInfo) {\n if (this !== config.current) {\n var message = resultInfo && resultInfo.message || "";\n var testName = this && this.testName || "";\n var error = "Assertion occurred after test finished.\\n" + "> Test: " + testName + "\\n" + "> Message: " + message + "\\n";\n throw new Error(error);\n } // Destructure of resultInfo = { result, actual, expected, message, negative }\n\n\n var details = {\n module: this.module.name,\n name: this.testName,\n result: resultInfo.result,\n message: resultInfo.message,\n actual: resultInfo.actual,\n testId: this.testId,\n negative: resultInfo.negative || false,\n runtime: now() - this.started,\n todo: !!this.todo\n };\n\n if (hasOwn$1.call(resultInfo, "expected")) {\n details.expected = resultInfo.expected;\n }\n\n if (!resultInfo.result) {\n var source = resultInfo.source || sourceFromStacktrace();\n\n if (source) {\n details.source = source;\n }\n }\n\n this.logAssertion(details);\n this.assertions.push({\n result: !!resultInfo.result,\n message: resultInfo.message\n });\n },\n pushFailure: function pushFailure(message, source, actual) {\n if (!(this instanceof Test)) {\n throw new Error("pushFailure() assertion outside test context, was " + sourceFromStacktrace(2));\n }\n\n this.pushResult({\n result: false,\n message: message || "error",\n actual: actual || null,\n source: source\n });\n },\n\n /**\n * Log assertion details using both the old QUnit.log interface and\n * QUnit.on( "assertion" ) interface.\n *\n * @private\n */\n logAssertion: function logAssertion(details) {\n runLoggingCallbacks("log", details);\n var assertion = {\n passed: details.result,\n actual: details.actual,\n expected: details.expected,\n message: details.message,\n stack: details.source,\n todo: details.todo\n };\n this.testReport.pushAssertion(assertion);\n emit("assertion", assertion);\n },\n resolvePromise: function resolvePromise(promise, phase) {\n if (promise != null) {\n var _test = this;\n\n var then = promise.then;\n\n if (objectType(then) === "function") {\n var resume = internalStop(_test);\n\n var resolve = function resolve() {\n resume();\n };\n\n if (config.notrycatch) {\n then.call(promise, resolve);\n } else {\n var reject = function reject(error) {\n var message = "Promise rejected " + (!phase ? "during" : phase.replace(/Each$/, "")) + " \\"" + _test.testName + "\\": " + (error && error.message || error);\n\n _test.pushFailure(message, extractStacktrace(error, 0)); // Else next test will carry the responsibility\n\n\n saveGlobal(); // Unblock\n\n internalRecover(_test);\n };\n\n then.call(promise, resolve, reject);\n }\n }\n }\n },\n valid: function valid() {\n var filter = config.filter;\n var regexFilter = /^(!?)\\/([\\w\\W]*)\\/(i?$)/.exec(filter);\n var module = config.module && config.module.toLowerCase();\n var fullName = this.module.name + ": " + this.testName;\n\n function moduleChainNameMatch(testModule) {\n var testModuleName = testModule.name ? testModule.name.toLowerCase() : null;\n\n if (testModuleName === module) {\n return true;\n } else if (testModule.parentModule) {\n return moduleChainNameMatch(testModule.parentModule);\n } else {\n return false;\n }\n }\n\n function moduleChainIdMatch(testModule) {\n return inArray(testModule.moduleId, config.moduleId) || testModule.parentModule && moduleChainIdMatch(testModule.parentModule);\n } // Internally-generated tests are always valid\n\n\n if (this.callback && this.callback.validTest) {\n return true;\n }\n\n if (config.moduleId && config.moduleId.length > 0 && !moduleChainIdMatch(this.module)) {\n return false;\n }\n\n if (config.testId && config.testId.length > 0 && !inArray(this.testId, config.testId)) {\n return false;\n }\n\n if (module && !moduleChainNameMatch(this.module)) {\n return false;\n }\n\n if (!filter) {\n return true;\n }\n\n return regexFilter ? this.regexFilter(!!regexFilter[1], regexFilter[2], regexFilter[3], fullName) : this.stringFilter(filter, fullName);\n },\n regexFilter: function regexFilter(exclude, pattern, flags, fullName) {\n var regex = new RegExp(pattern, flags);\n var match = regex.test(fullName);\n return match !== exclude;\n },\n stringFilter: function stringFilter(filter, fullName) {\n filter = filter.toLowerCase();\n fullName = fullName.toLowerCase();\n var include = filter.charAt(0) !== "!";\n\n if (!include) {\n filter = filter.slice(1);\n } // If the filter matches, we need to honour include\n\n\n if (fullName.indexOf(filter) !== -1) {\n return include;\n } // Otherwise, do the opposite\n\n\n return !include;\n }\n };\n function pushFailure() {\n if (!config.current) {\n throw new Error("pushFailure() assertion outside test context, in " + sourceFromStacktrace(2));\n } // Gets current test obj\n\n\n var currentTest = config.current;\n return currentTest.pushFailure.apply(currentTest, arguments);\n }\n\n function saveGlobal() {\n config.pollution = [];\n\n if (config.noglobals) {\n for (var key in globalThis$1) {\n if (hasOwn$1.call(globalThis$1, key)) {\n // In Opera sometimes DOM element ids show up here, ignore them\n if (/^qunit-test-output/.test(key)) {\n continue;\n }\n\n config.pollution.push(key);\n }\n }\n }\n }\n\n function checkPollution() {\n var old = config.pollution;\n saveGlobal();\n var newGlobals = diff(config.pollution, old);\n\n if (newGlobals.length > 0) {\n pushFailure("Introduced global variable(s): " + newGlobals.join(", "));\n }\n\n var deletedGlobals = diff(old, config.pollution);\n\n if (deletedGlobals.length > 0) {\n pushFailure("Deleted global variable(s): " + deletedGlobals.join(", "));\n }\n }\n\n var focused = false; // indicates that the "only" filter was used\n\n function addTest(settings) {\n if (focused || config.currentModule.ignored) {\n return;\n }\n\n var newTest = new Test(settings);\n newTest.queue();\n }\n\n function addOnlyTest(settings) {\n if (config.currentModule.ignored) {\n return;\n }\n\n if (!focused) {\n config.queue.length = 0;\n focused = true;\n }\n\n var newTest = new Test(settings);\n newTest.queue();\n } // Will be exposed as QUnit.test\n\n\n function test(testName, callback) {\n addTest({\n testName: testName,\n callback: callback\n });\n }\n\n function makeEachTestName(testName, argument) {\n return "".concat(testName, " [").concat(argument, "]");\n }\n\n function runEach(data, eachFn) {\n if (Array.isArray(data)) {\n data.forEach(eachFn);\n } else if (_typeof(data) === "object" && data !== null) {\n var keys = Object.keys(data);\n keys.forEach(function (key) {\n eachFn(data[key], key);\n });\n } else {\n throw new Error("test.each() expects an array or object as input, but\\nfound ".concat(_typeof(data), " instead."));\n }\n }\n\n extend(test, {\n todo: function todo(testName, callback) {\n addTest({\n testName: testName,\n callback: callback,\n todo: true\n });\n },\n skip: function skip(testName) {\n addTest({\n testName: testName,\n skip: true\n });\n },\n only: function only(testName, callback) {\n addOnlyTest({\n testName: testName,\n callback: callback\n });\n },\n each: function each(testName, dataset, callback) {\n runEach(dataset, function (data, testKey) {\n addTest({\n testName: makeEachTestName(testName, testKey),\n callback: callback,\n withData: true,\n data: data\n });\n });\n }\n });\n\n test.todo.each = function (testName, dataset, callback) {\n runEach(dataset, function (data, testKey) {\n addTest({\n testName: makeEachTestName(testName, testKey),\n callback: callback,\n todo: true,\n withData: true,\n data: data\n });\n });\n };\n\n test.skip.each = function (testName, dataset) {\n runEach(dataset, function (_, testKey) {\n addTest({\n testName: makeEachTestName(testName, testKey),\n skip: true\n });\n });\n };\n\n test.only.each = function (testName, dataset, callback) {\n runEach(dataset, function (data, testKey) {\n addOnlyTest({\n testName: makeEachTestName(testName, testKey),\n callback: callback,\n withData: true,\n data: data\n });\n });\n }; // Resets config.timeout with a new timeout duration.\n\n\n function resetTestTimeout(timeoutDuration) {\n clearTimeout(config.timeout);\n config.timeout = setTimeout$1(config.timeoutHandler(timeoutDuration), timeoutDuration);\n } // Create a new async pause and return a new function that can release the pause.\n //\n // This mechanism is internally used by:\n //\n // * explicit async pauses, created by calling `assert.async()`,\n // * implicit async pauses, created when `QUnit.test()` or module hook callbacks\n // use async-await or otherwise return a Promise.\n //\n // Happy scenario:\n //\n // * Pause is created by calling internalStop().\n //\n // Pause is released normally by invoking release() during the same test.\n //\n // The release() callback lets internal processing resume.\n //\n // Failure scenarios:\n //\n // * The test fails due to an uncaught exception.\n //\n // In this case, Test.run() will call internalRecover() which empties the clears all\n // async pauses and sets the cancelled flag, which means we silently ignore any\n // late calls to the resume() callback, as we will have moved on to a different\n // test by then, and we don\'t want to cause an extra "release during a different test"\n // errors that the developer isn\'t really responsible for. This can happen when a test\n // correctly schedules a call to release(), but also causes an uncaught error. The\n // uncaught error means we will no longer wait for the release (as it might not arrive).\n //\n // * Pause is never released, or called an insufficient number of times.\n //\n // Our timeout handler will kill the pause and resume test processing, basically\n // like internalRecover(), but for one pause instead of any/all.\n //\n // Here, too, any late calls to resume() will be silently ignored to avoid\n // extra errors. We tolerate this since the original test will have already been\n // marked as failure.\n //\n // TODO: QUnit 3 will enable timeouts by default ,\n // but right now a test will hang indefinitely if async pauses are not released,\n // unless QUnit.config.testTimeout or assert.timeout() is used.\n //\n // * Pause is spontaneously released during a different test,\n // or when no test is currently running.\n //\n // This is close to impossible because this error only happens if the original test\n // succesfully finished first (since other failure scenarios kill pauses and ignore\n // late calls). It can happen if a test ended exactly as expected, but has some\n // external or shared state continuing to hold a reference to the release callback,\n // and either the same test scheduled another call to it in the future, or a later test\n // causes it to be called through some shared state.\n //\n // * Pause release() is called too often, during the same test.\n //\n // This simply throws an error, after which uncaught error handling picks it up\n // and processing resumes.\n\n function internalStop(test) {\n var requiredCalls = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n config.blocking = true;\n var pauseId = test.nextPauseId++;\n var pause = {\n cancelled: false,\n remaining: requiredCalls\n };\n test.pauses.set(pauseId, pause);\n\n function release() {\n if (pause.cancelled) {\n return;\n }\n\n if (config.current === undefined) {\n throw new Error("Unexpected release of async pause after tests finished.\\n" + "> Test: ".concat(test.testName, " [async #").concat(pauseId, "]"));\n }\n\n if (config.current !== test) {\n throw new Error("Unexpected release of async pause during a different test.\\n" + "> Test: ".concat(test.testName, " [async #").concat(pauseId, "]"));\n }\n\n if (pause.remaining <= 0) {\n throw new Error("Tried to release async pause that was already released.\\n" + "> Test: ".concat(test.testName, " [async #").concat(pauseId, "]"));\n } // The `requiredCalls` parameter exists to support `assert.async(count)`\n\n\n pause.remaining--;\n\n if (pause.remaining === 0) {\n test.pauses.delete(pauseId);\n }\n\n internalStart(test);\n } // Set a recovery timeout, if so configured.\n\n\n if (setTimeout$1) {\n var timeoutDuration;\n\n if (typeof test.timeout === "number") {\n timeoutDuration = test.timeout;\n } else if (typeof config.testTimeout === "number") {\n timeoutDuration = config.testTimeout;\n }\n\n if (typeof timeoutDuration === "number" && timeoutDuration > 0) {\n config.timeoutHandler = function (timeout) {\n return function () {\n config.timeout = null;\n pause.cancelled = true;\n test.pauses.delete(pauseId);\n test.pushFailure("Test took longer than ".concat(timeout, "ms; test timed out."), sourceFromStacktrace(2));\n internalStart(test);\n };\n };\n\n clearTimeout(config.timeout);\n config.timeout = setTimeout$1(config.timeoutHandler(timeoutDuration), timeoutDuration);\n }\n }\n\n return release;\n } // Forcefully release all processing holds.\n\n function internalRecover(test) {\n test.pauses.forEach(function (pause) {\n pause.cancelled = true;\n });\n test.pauses.clear();\n internalStart(test);\n } // Release a processing hold, scheduling a resumption attempt if no holds remain.\n\n\n function internalStart(test) {\n // Ignore if other async pauses still exist.\n if (test.pauses.size > 0) {\n return;\n } // Add a slight delay to allow more assertions etc.\n\n\n if (setTimeout$1) {\n clearTimeout(config.timeout);\n config.timeout = setTimeout$1(function () {\n if (test.pauses.size > 0) {\n return;\n }\n\n clearTimeout(config.timeout);\n config.timeout = null;\n begin();\n });\n } else {\n begin();\n }\n }\n\n function collectTests(module) {\n var tests = [].concat(module.tests);\n\n var modules = _toConsumableArray(module.childModules); // Do a breadth-first traversal of the child modules\n\n\n while (modules.length) {\n var nextModule = modules.shift();\n tests.push.apply(tests, nextModule.tests);\n modules.push.apply(modules, _toConsumableArray(nextModule.childModules));\n }\n\n return tests;\n } // This returns true after all executable and skippable tests\n // in a module have been proccessed, and informs \'suiteEnd\'\n // and moduleDone().\n\n\n function allTestsExecuted(module) {\n return module.testsRun + module.testsIgnored === collectTests(module).length;\n } // This returns true during the last executable non-skipped test\n // within a module, and informs the running of the \'after\' hook\n // for a given module. This runs only once for a given module,\n // but must run during the last non-skipped test. When it runs,\n // there may be non-zero skipped tests left.\n\n\n function lastTestWithinModuleExecuted(module) {\n return module.testsRun === collectTests(module).filter(function (test) {\n return !test.skip;\n }).length - 1;\n }\n\n function incrementTestsRun(module) {\n module.testsRun++;\n\n while (module = module.parentModule) {\n module.testsRun++;\n }\n }\n\n function incrementTestsIgnored(module) {\n module.testsIgnored++;\n\n while (module = module.parentModule) {\n module.testsIgnored++;\n }\n }\n\n var Assert = /*#__PURE__*/function () {\n function Assert(testContext) {\n _classCallCheck(this, Assert);\n\n this.test = testContext;\n } // Assert helpers\n\n\n _createClass(Assert, [{\n key: "timeout",\n value: function timeout(duration) {\n if (typeof duration !== "number") {\n throw new Error("You must pass a number as the duration to assert.timeout");\n }\n\n this.test.timeout = duration; // If a timeout has been set, clear it and reset with the new duration\n\n if (config.timeout) {\n clearTimeout(config.timeout);\n config.timeout = null;\n\n if (config.timeoutHandler && this.test.timeout > 0) {\n resetTestTimeout(this.test.timeout);\n }\n }\n } // Documents a "step", which is a string value, in a test as a passing assertion\n\n }, {\n key: "step",\n value: function step(message) {\n var assertionMessage = message;\n var result = !!message;\n this.test.steps.push(message);\n\n if (objectType(message) === "undefined" || message === "") {\n assertionMessage = "You must provide a message to assert.step";\n } else if (objectType(message) !== "string") {\n assertionMessage = "You must provide a string value to assert.step";\n result = false;\n }\n\n this.pushResult({\n result: result,\n message: assertionMessage\n });\n } // Verifies the steps in a test match a given array of string values\n\n }, {\n key: "verifySteps",\n value: function verifySteps(steps, message) {\n // Since the steps array is just string values, we can clone with slice\n var actualStepsClone = this.test.steps.slice();\n this.deepEqual(actualStepsClone, steps, message);\n this.test.steps.length = 0;\n } // Specify the number of expected assertions to guarantee that failed test\n // (no assertions are run at all) don\'t slip through.\n\n }, {\n key: "expect",\n value: function expect(asserts) {\n if (arguments.length === 1) {\n this.test.expected = asserts;\n } else {\n return this.test.expected;\n }\n } // Create a new async pause and return a new function that can release the pause.\n\n }, {\n key: "async",\n value: function async(count) {\n var requiredCalls = count === undefined ? 1 : count;\n return internalStop(this.test, requiredCalls);\n } // Exports test.push() to the user API\n // Alias of pushResult.\n\n }, {\n key: "push",\n value: function push(result, actual, expected, message, negative) {\n Logger.warn("assert.push is deprecated and will be removed in QUnit 3.0." + " Please use assert.pushResult instead (https://api.qunitjs.com/assert/pushResult).");\n var currentAssert = this instanceof Assert ? this : config.current.assert;\n return currentAssert.pushResult({\n result: result,\n actual: actual,\n expected: expected,\n message: message,\n negative: negative\n });\n }\n }, {\n key: "pushResult",\n value: function pushResult(resultInfo) {\n // Destructure of resultInfo = { result, actual, expected, message, negative }\n var assert = this;\n var currentTest = assert instanceof Assert && assert.test || config.current; // Backwards compatibility fix.\n // Allows the direct use of global exported assertions and QUnit.assert.*\n // Although, it\'s use is not recommended as it can leak assertions\n // to other tests from async tests, because we only get a reference to the current test,\n // not exactly the test where assertion were intended to be called.\n\n if (!currentTest) {\n throw new Error("assertion outside test context, in " + sourceFromStacktrace(2));\n }\n\n if (!(assert instanceof Assert)) {\n assert = currentTest.assert;\n }\n\n return assert.test.pushResult(resultInfo);\n }\n }, {\n key: "ok",\n value: function ok(result, message) {\n if (!message) {\n message = result ? "okay" : "failed, expected argument to be truthy, was: ".concat(dump.parse(result));\n }\n\n this.pushResult({\n result: !!result,\n actual: result,\n expected: true,\n message: message\n });\n }\n }, {\n key: "notOk",\n value: function notOk(result, message) {\n if (!message) {\n message = !result ? "okay" : "failed, expected argument to be falsy, was: ".concat(dump.parse(result));\n }\n\n this.pushResult({\n result: !result,\n actual: result,\n expected: false,\n message: message\n });\n }\n }, {\n key: "true",\n value: function _true(result, message) {\n this.pushResult({\n result: result === true,\n actual: result,\n expected: true,\n message: message\n });\n }\n }, {\n key: "false",\n value: function _false(result, message) {\n this.pushResult({\n result: result === false,\n actual: result,\n expected: false,\n message: message\n });\n }\n }, {\n key: "equal",\n value: function equal(actual, expected, message) {\n // eslint-disable-next-line eqeqeq\n var result = expected == actual;\n this.pushResult({\n result: result,\n actual: actual,\n expected: expected,\n message: message\n });\n }\n }, {\n key: "notEqual",\n value: function notEqual(actual, expected, message) {\n // eslint-disable-next-line eqeqeq\n var result = expected != actual;\n this.pushResult({\n result: result,\n actual: actual,\n expected: expected,\n message: message,\n negative: true\n });\n }\n }, {\n key: "propEqual",\n value: function propEqual(actual, expected, message) {\n actual = objectValues(actual);\n expected = objectValues(expected);\n this.pushResult({\n result: equiv(actual, expected),\n actual: actual,\n expected: expected,\n message: message\n });\n }\n }, {\n key: "notPropEqual",\n value: function notPropEqual(actual, expected, message) {\n actual = objectValues(actual);\n expected = objectValues(expected);\n this.pushResult({\n result: !equiv(actual, expected),\n actual: actual,\n expected: expected,\n message: message,\n negative: true\n });\n }\n }, {\n key: "deepEqual",\n value: function deepEqual(actual, expected, message) {\n this.pushResult({\n result: equiv(actual, expected),\n actual: actual,\n expected: expected,\n message: message\n });\n }\n }, {\n key: "notDeepEqual",\n value: function notDeepEqual(actual, expected, message) {\n this.pushResult({\n result: !equiv(actual, expected),\n actual: actual,\n expected: expected,\n message: message,\n negative: true\n });\n }\n }, {\n key: "strictEqual",\n value: function strictEqual(actual, expected, message) {\n this.pushResult({\n result: expected === actual,\n actual: actual,\n expected: expected,\n message: message\n });\n }\n }, {\n key: "notStrictEqual",\n value: function notStrictEqual(actual, expected, message) {\n this.pushResult({\n result: expected !== actual,\n actual: actual,\n expected: expected,\n message: message,\n negative: true\n });\n }\n }, {\n key: "throws",\n value: function throws(block, expected, message) {\n var _validateExpectedExce = validateExpectedExceptionArgs(expected, message, "throws");\n\n var _validateExpectedExce2 = _slicedToArray(_validateExpectedExce, 2);\n\n expected = _validateExpectedExce2[0];\n message = _validateExpectedExce2[1];\n var currentTest = this instanceof Assert && this.test || config.current;\n\n if (objectType(block) !== "function") {\n var _message = "The value provided to `assert.throws` in " + "\\"" + currentTest.testName + "\\" was not a function.";\n\n currentTest.assert.pushResult({\n result: false,\n actual: block,\n message: _message\n });\n return;\n }\n\n var actual;\n var result = false;\n currentTest.ignoreGlobalErrors = true;\n\n try {\n block.call(currentTest.testEnvironment);\n } catch (e) {\n actual = e;\n }\n\n currentTest.ignoreGlobalErrors = false;\n\n if (actual) {\n var _validateException = validateException(actual, expected, message);\n\n var _validateException2 = _slicedToArray(_validateException, 3);\n\n result = _validateException2[0];\n expected = _validateException2[1];\n message = _validateException2[2];\n }\n\n currentTest.assert.pushResult({\n result: result,\n // undefined if it didn\'t throw\n actual: actual && errorString(actual),\n expected: expected,\n message: message\n });\n }\n }, {\n key: "rejects",\n value: function rejects(promise, expected, message) {\n var _validateExpectedExce3 = validateExpectedExceptionArgs(expected, message, "rejects");\n\n var _validateExpectedExce4 = _slicedToArray(_validateExpectedExce3, 2);\n\n expected = _validateExpectedExce4[0];\n message = _validateExpectedExce4[1];\n var currentTest = this instanceof Assert && this.test || config.current;\n var then = promise && promise.then;\n\n if (objectType(then) !== "function") {\n var _message2 = "The value provided to `assert.rejects` in " + "\\"" + currentTest.testName + "\\" was not a promise.";\n\n currentTest.assert.pushResult({\n result: false,\n message: _message2,\n actual: promise\n });\n return;\n }\n\n var done = this.async();\n return then.call(promise, function handleFulfillment() {\n var message = "The promise returned by the `assert.rejects` callback in " + "\\"" + currentTest.testName + "\\" did not reject.";\n currentTest.assert.pushResult({\n result: false,\n message: message,\n actual: promise\n });\n done();\n }, function handleRejection(actual) {\n var result;\n\n var _validateException3 = validateException(actual, expected, message);\n\n var _validateException4 = _slicedToArray(_validateException3, 3);\n\n result = _validateException4[0];\n expected = _validateException4[1];\n message = _validateException4[2];\n currentTest.assert.pushResult({\n result: result,\n // leave rejection value of undefined as-is\n actual: actual && errorString(actual),\n expected: expected,\n message: message\n });\n done();\n });\n }\n }]);\n\n return Assert;\n }();\n\n function validateExpectedExceptionArgs(expected, message, assertionMethod) {\n var expectedType = objectType(expected); // \'expected\' is optional unless doing string comparison\n\n if (expectedType === "string") {\n if (message === undefined) {\n message = expected;\n expected = undefined;\n return [expected, message];\n } else {\n throw new Error("assert." + assertionMethod + " does not accept a string value for the expected argument.\\n" + "Use a non-string object value (e.g. RegExp or validator function) " + "instead if necessary.");\n }\n }\n\n var valid = !expected || // TODO: be more explicit here\n expectedType === "regexp" || expectedType === "function" || expectedType === "object";\n\n if (!valid) {\n var _message3 = "Invalid expected value type (" + expectedType + ") " + "provided to assert." + assertionMethod + ".";\n\n throw new Error(_message3);\n }\n\n return [expected, message];\n }\n\n function validateException(actual, expected, message) {\n var result = false;\n var expectedType = objectType(expected); // These branches should be exhaustive, based on validation done in validateExpectedException\n // We don\'t want to validate\n\n if (!expected) {\n result = true; // Expected is a regexp\n } else if (expectedType === "regexp") {\n result = expected.test(errorString(actual)); // Log the string form of the regexp\n\n expected = String(expected); // Expected is a constructor, maybe an Error constructor.\n // Note the extra check on its prototype - this is an implicit\n // requirement of "instanceof", else it will throw a TypeError.\n } else if (expectedType === "function" && expected.prototype !== undefined && actual instanceof expected) {\n result = true; // Expected is an Error object\n } else if (expectedType === "object") {\n result = actual instanceof expected.constructor && actual.name === expected.name && actual.message === expected.message; // Log the string form of the Error object\n\n expected = errorString(expected); // Expected is a validation function which returns true if validation passed\n } else if (expectedType === "function") {\n // protect against accidental semantics which could hard error in the test\n try {\n result = expected.call({}, actual) === true;\n expected = null;\n } catch (e) {\n // assign the "expected" to a nice error string to communicate the local failure to the user\n expected = errorString(e);\n }\n }\n\n return [result, expected, message];\n } // Provide an alternative to assert.throws(), for environments that consider throws a reserved word\n // Known to us are: Closure Compiler, Narwhal\n // eslint-disable-next-line dot-notation\n\n\n Assert.prototype.raises = Assert.prototype["throws"];\n\n /* global module, exports, define */\n function exportQUnit(QUnit) {\n var exportedModule = false;\n\n if (window$1 && document) {\n // QUnit may be defined when it is preconfigured but then only QUnit and QUnit.config may be defined.\n if (window$1.QUnit && window$1.QUnit.version) {\n throw new Error("QUnit has already been defined.");\n }\n\n window$1.QUnit = QUnit;\n exportedModule = true;\n } // For Node.js\n\n\n if (typeof module !== "undefined" && module && module.exports) {\n module.exports = QUnit; // For consistency with CommonJS environments\' exports\n\n module.exports.QUnit = QUnit;\n exportedModule = true;\n } // For CommonJS with exports, but without module.exports, like Rhino\n\n\n if (typeof exports !== "undefined" && exports) {\n exports.QUnit = QUnit;\n exportedModule = true;\n } // For AMD\n\n\n if (typeof define === "function" && define.amd) {\n define(function () {\n return QUnit;\n });\n QUnit.config.autostart = false;\n exportedModule = true;\n } // For Web/Service Workers\n\n\n if (self$1 && self$1.WorkerGlobalScope && self$1 instanceof self$1.WorkerGlobalScope) {\n self$1.QUnit = QUnit;\n exportedModule = true;\n } // For other environments, such as SpiderMonkey (mozjs) and other\n // embedded JavaScript engines\n\n\n if (!exportedModule) {\n globalThis$1.QUnit = QUnit;\n }\n }\n\n var ConsoleReporter = /*#__PURE__*/function () {\n function ConsoleReporter(runner) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n _classCallCheck(this, ConsoleReporter);\n\n // Cache references to console methods to ensure we can report failures\n // from tests tests that mock the console object itself.\n // https://github.com/qunitjs/qunit/issues/1340\n // Support IE 9: Function#bind is supported, but no console.log.bind().\n this.log = options.log || Function.prototype.bind.call(console$1.log, console$1);\n runner.on("error", this.onError.bind(this));\n runner.on("runStart", this.onRunStart.bind(this));\n runner.on("testStart", this.onTestStart.bind(this));\n runner.on("testEnd", this.onTestEnd.bind(this));\n runner.on("runEnd", this.onRunEnd.bind(this));\n }\n\n _createClass(ConsoleReporter, [{\n key: "onError",\n value: function onError(error) {\n this.log("error", error);\n }\n }, {\n key: "onRunStart",\n value: function onRunStart(runStart) {\n this.log("runStart", runStart);\n }\n }, {\n key: "onTestStart",\n value: function onTestStart(test) {\n this.log("testStart", test);\n }\n }, {\n key: "onTestEnd",\n value: function onTestEnd(test) {\n this.log("testEnd", test);\n }\n }, {\n key: "onRunEnd",\n value: function onRunEnd(runEnd) {\n this.log("runEnd", runEnd);\n }\n }], [{\n key: "init",\n value: function init(runner, options) {\n return new ConsoleReporter(runner, options);\n }\n }]);\n\n return ConsoleReporter;\n }();\n\n var FORCE_COLOR,\n NODE_DISABLE_COLORS,\n NO_COLOR,\n TERM,\n isTTY = true;\n\n if (typeof process !== \'undefined\') {\n var _process$env = process.env;\n FORCE_COLOR = _process$env.FORCE_COLOR;\n NODE_DISABLE_COLORS = _process$env.NODE_DISABLE_COLORS;\n NO_COLOR = _process$env.NO_COLOR;\n TERM = _process$env.TERM;\n isTTY = process.stdout && process.stdout.isTTY;\n }\n\n var $ = {\n enabled: !NODE_DISABLE_COLORS && NO_COLOR == null && TERM !== \'dumb\' && (FORCE_COLOR != null && FORCE_COLOR !== \'0\' || isTTY),\n // modifiers\n reset: init(0, 0),\n bold: init(1, 22),\n dim: init(2, 22),\n italic: init(3, 23),\n underline: init(4, 24),\n inverse: init(7, 27),\n hidden: init(8, 28),\n strikethrough: init(9, 29),\n // colors\n black: init(30, 39),\n red: init(31, 39),\n green: init(32, 39),\n yellow: init(33, 39),\n blue: init(34, 39),\n magenta: init(35, 39),\n cyan: init(36, 39),\n white: init(37, 39),\n gray: init(90, 39),\n grey: init(90, 39),\n // background colors\n bgBlack: init(40, 49),\n bgRed: init(41, 49),\n bgGreen: init(42, 49),\n bgYellow: init(43, 49),\n bgBlue: init(44, 49),\n bgMagenta: init(45, 49),\n bgCyan: init(46, 49),\n bgWhite: init(47, 49)\n };\n\n function run(arr, str) {\n var i = 0,\n tmp,\n beg = \'\',\n end = \'\';\n\n for (; i < arr.length; i++) {\n tmp = arr[i];\n beg += tmp.open;\n end += tmp.close;\n\n if (!!~str.indexOf(tmp.close)) {\n str = str.replace(tmp.rgx, tmp.close + tmp.open);\n }\n }\n\n return beg + str + end;\n }\n\n function chain(has, keys) {\n var ctx = {\n has: has,\n keys: keys\n };\n ctx.reset = $.reset.bind(ctx);\n ctx.bold = $.bold.bind(ctx);\n ctx.dim = $.dim.bind(ctx);\n ctx.italic = $.italic.bind(ctx);\n ctx.underline = $.underline.bind(ctx);\n ctx.inverse = $.inverse.bind(ctx);\n ctx.hidden = $.hidden.bind(ctx);\n ctx.strikethrough = $.strikethrough.bind(ctx);\n ctx.black = $.black.bind(ctx);\n ctx.red = $.red.bind(ctx);\n ctx.green = $.green.bind(ctx);\n ctx.yellow = $.yellow.bind(ctx);\n ctx.blue = $.blue.bind(ctx);\n ctx.magenta = $.magenta.bind(ctx);\n ctx.cyan = $.cyan.bind(ctx);\n ctx.white = $.white.bind(ctx);\n ctx.gray = $.gray.bind(ctx);\n ctx.grey = $.grey.bind(ctx);\n ctx.bgBlack = $.bgBlack.bind(ctx);\n ctx.bgRed = $.bgRed.bind(ctx);\n ctx.bgGreen = $.bgGreen.bind(ctx);\n ctx.bgYellow = $.bgYellow.bind(ctx);\n ctx.bgBlue = $.bgBlue.bind(ctx);\n ctx.bgMagenta = $.bgMagenta.bind(ctx);\n ctx.bgCyan = $.bgCyan.bind(ctx);\n ctx.bgWhite = $.bgWhite.bind(ctx);\n return ctx;\n }\n\n function init(open, close) {\n var blk = {\n open: "\\x1B[".concat(open, "m"),\n close: "\\x1B[".concat(close, "m"),\n rgx: new RegExp("\\\\x1b\\\\[".concat(close, "m"), \'g\')\n };\n return function (txt) {\n if (this !== void 0 && this.has !== void 0) {\n !!~this.has.indexOf(open) || (this.has.push(open), this.keys.push(blk));\n return txt === void 0 ? this : $.enabled ? run(this.keys, txt + \'\') : txt + \'\';\n }\n\n return txt === void 0 ? chain([open], [blk]) : $.enabled ? run([blk], txt + \'\') : txt + \'\';\n };\n }\n\n var hasOwn = Object.prototype.hasOwnProperty;\n /**\n * Format a given value into YAML.\n *\n * YAML is a superset of JSON that supports all the same data\n * types and syntax, and more. As such, it is always possible\n * to fallback to JSON.stringfify, but we generally avoid\n * that to make output easier to read for humans.\n *\n * Supported data types:\n *\n * - null\n * - boolean\n * - number\n * - string\n * - array\n * - object\n *\n * Anything else (including NaN, Infinity, and undefined)\n * must be described in strings, for display purposes.\n *\n * Note that quotes are optional in YAML strings if the\n * strings are "simple", and as such we generally prefer\n * that for improved readability. We output strings in\n * one of three ways:\n *\n * - bare unquoted text, for simple one-line strings.\n * - JSON (quoted text), for complex one-line strings.\n * - YAML Block, for complex multi-line strings.\n *\n * Objects with cyclical references will be stringifed as\n * "[Circular]" as they cannot otherwise be represented.\n */\n\n function prettyYamlValue(value) {\n var indent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;\n\n if (value === undefined) {\n // Not supported in JSON/YAML, turn into string\n // and let the below output it as bare string.\n value = String(value);\n } // Support IE 9-11: Use isFinite instead of ES6 Number.isFinite\n\n\n if (typeof value === "number" && !isFinite(value)) {\n // Turn NaN and Infinity into simple strings.\n // Paranoia: Don\'t return directly just in case there\'s\n // a way to add special characters here.\n value = String(value);\n }\n\n if (typeof value === "number") {\n // Simple numbers\n return JSON.stringify(value);\n }\n\n if (typeof value === "string") {\n // If any of these match, then we can\'t output it\n // as bare unquoted text, because that would either\n // cause data loss or invalid YAML syntax.\n //\n // - Quotes, escapes, line breaks, or JSON-like stuff.\n var rSpecialJson = /[\'"\\\\/[{}\\]\\r\\n]/; // - Characters that are special at the start of a YAML value\n\n var rSpecialYaml = /[-?:,[\\]{}#&*!|=>\'"%@`]/; // - Leading or trailing whitespace.\n\n var rUntrimmed = /(^\\s|\\s$)/; // - Ambiguous as YAML number, e.g. \'2\', \'-1.2\', \'.2\', or \'2_000\'\n\n var rNumerical = /^[\\d._-]+$/; // - Ambiguous as YAML bool.\n // Use case-insensitive match, although technically only\n // fully-lower, fully-upper, or uppercase-first would be ambiguous.\n // e.g. true/True/TRUE, but not tRUe.\n\n var rBool = /^(true|false|y|n|yes|no|on|off)$/i; // Is this a complex string?\n\n if (value === "" || rSpecialJson.test(value) || rSpecialYaml.test(value[0]) || rUntrimmed.test(value) || rNumerical.test(value) || rBool.test(value)) {\n if (!/\\n/.test(value)) {\n // Complex one-line string, use JSON (quoted string)\n return JSON.stringify(value);\n } // See also \n // Support IE 9-11: Avoid ES6 String#repeat\n\n\n var prefix = new Array(indent + 1).join(" ");\n var trailingLinebreakMatch = value.match(/\\n+$/);\n var trailingLinebreaks = trailingLinebreakMatch ? trailingLinebreakMatch[0].length : 0;\n\n if (trailingLinebreaks === 1) {\n // Use the most straight-forward "Block" string in YAML\n // without any "Chomping" indicators.\n var lines = value // Ignore the last new line, since we\'ll get that one for free\n // with the straight-forward Block syntax.\n .replace(/\\n$/, "").split("\\n").map(function (line) {\n return prefix + line;\n });\n return "|\\n" + lines.join("\\n");\n } else {\n // This has either no trailing new lines, or more than 1.\n // Use |+ so that YAML parsers will preserve it exactly.\n var _lines = value.split("\\n").map(function (line) {\n return prefix + line;\n });\n\n return "|+\\n" + _lines.join("\\n");\n }\n } else {\n // Simple string, use bare unquoted text\n return value;\n }\n } // Handle null, boolean, array, and object\n\n\n return JSON.stringify(decycledShallowClone(value), null, 2);\n }\n /**\n * Creates a shallow clone of an object where cycles have\n * been replaced with "[Circular]".\n */\n\n\n function decycledShallowClone(object) {\n var ancestors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n\n if (ancestors.indexOf(object) !== -1) {\n return "[Circular]";\n }\n\n var clone;\n var type = Object.prototype.toString.call(object).replace(/^\\[.+\\s(.+?)]$/, "$1").toLowerCase();\n\n switch (type) {\n case "array":\n ancestors.push(object);\n clone = object.map(function (element) {\n return decycledShallowClone(element, ancestors);\n });\n ancestors.pop();\n break;\n\n case "object":\n ancestors.push(object);\n clone = {};\n Object.keys(object).forEach(function (key) {\n clone[key] = decycledShallowClone(object[key], ancestors);\n });\n ancestors.pop();\n break;\n\n default:\n clone = object;\n }\n\n return clone;\n }\n\n var TapReporter = /*#__PURE__*/function () {\n function TapReporter(runner) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n _classCallCheck(this, TapReporter);\n\n // Cache references to console methods to ensure we can report failures\n // from tests tests that mock the console object itself.\n // https://github.com/qunitjs/qunit/issues/1340\n // Support IE 9: Function#bind is supported, but no console.log.bind().\n this.log = options.log || Function.prototype.bind.call(console$1.log, console$1);\n this.testCount = 0;\n this.ended = false;\n this.bailed = false;\n runner.on("error", this.onError.bind(this));\n runner.on("runStart", this.onRunStart.bind(this));\n runner.on("testEnd", this.onTestEnd.bind(this));\n runner.on("runEnd", this.onRunEnd.bind(this));\n }\n\n _createClass(TapReporter, [{\n key: "onRunStart",\n value: function onRunStart(_globalSuite) {\n this.log("TAP version 13");\n }\n }, {\n key: "onError",\n value: function onError(error) {\n if (this.bailed) {\n return;\n }\n\n this.bailed = true; // Imitate onTestEnd\n // Skip this if we\'re past "runEnd" as it would look odd\n\n if (!this.ended) {\n this.testCount = this.testCount + 1;\n this.log($.red("not ok ".concat(this.testCount, " global failure")));\n this.logError(error);\n }\n\n this.log("Bail out! " + errorString(error).split("\\n")[0]);\n\n if (this.ended) {\n this.logError(error);\n }\n }\n }, {\n key: "onTestEnd",\n value: function onTestEnd(test) {\n var _this = this;\n\n this.testCount = this.testCount + 1;\n\n if (test.status === "passed") {\n this.log("ok ".concat(this.testCount, " ").concat(test.fullName.join(" > ")));\n } else if (test.status === "skipped") {\n this.log($.yellow("ok ".concat(this.testCount, " # SKIP ").concat(test.fullName.join(" > "))));\n } else if (test.status === "todo") {\n this.log($.cyan("not ok ".concat(this.testCount, " # TODO ").concat(test.fullName.join(" > "))));\n test.errors.forEach(function (error) {\n return _this.logAssertion(error, "todo");\n });\n } else {\n this.log($.red("not ok ".concat(this.testCount, " ").concat(test.fullName.join(" > "))));\n test.errors.forEach(function (error) {\n return _this.logAssertion(error);\n });\n }\n }\n }, {\n key: "onRunEnd",\n value: function onRunEnd(globalSuite) {\n this.ended = true;\n this.log("1..".concat(globalSuite.testCounts.total));\n this.log("# pass ".concat(globalSuite.testCounts.passed));\n this.log($.yellow("# skip ".concat(globalSuite.testCounts.skipped)));\n this.log($.cyan("# todo ".concat(globalSuite.testCounts.todo)));\n this.log($.red("# fail ".concat(globalSuite.testCounts.failed)));\n }\n }, {\n key: "logAssertion",\n value: function logAssertion(error, severity) {\n var out = " ---";\n out += "\\n message: ".concat(prettyYamlValue(error.message || "failed"));\n out += "\\n severity: ".concat(prettyYamlValue(severity || "failed"));\n\n if (hasOwn.call(error, "actual")) {\n out += "\\n actual : ".concat(prettyYamlValue(error.actual));\n }\n\n if (hasOwn.call(error, "expected")) {\n out += "\\n expected: ".concat(prettyYamlValue(error.expected));\n }\n\n if (error.stack) {\n // Since stacks aren\'t user generated, take a bit of liberty by\n // adding a trailing new line to allow a straight-forward YAML Blocks.\n out += "\\n stack: ".concat(prettyYamlValue(error.stack + "\\n"));\n }\n\n out += "\\n ...";\n this.log(out);\n }\n }, {\n key: "logError",\n value: function logError(error) {\n var out = " ---";\n out += "\\n message: ".concat(prettyYamlValue(errorString(error)));\n out += "\\n severity: ".concat(prettyYamlValue("failed"));\n\n if (error && error.stack) {\n out += "\\n stack: ".concat(prettyYamlValue(error.stack + "\\n"));\n }\n\n out += "\\n ...";\n this.log(out);\n }\n }], [{\n key: "init",\n value: function init(runner, options) {\n return new TapReporter(runner, options);\n }\n }]);\n\n return TapReporter;\n }();\n\n var reporters = {\n console: ConsoleReporter,\n tap: TapReporter\n };\n\n /**\n * Handle a global error that should result in a failed test run.\n *\n * Summary:\n *\n * - If we\'re strictly inside a test (or one if its module hooks), the exception\n * becomes a failed assertion.\n *\n * This has the important side-effect that uncaught exceptions (such as\n * calling an undefined function) during a "todo" test do NOT result in\n * a failed test run.\n *\n * - If we\'re anywhere outside a test (be it in early event callbacks, or\n * internally between tests, or somewhere after "runEnd" if the process is\n * still alive for some reason), then send an "error" event to the reporters.\n *\n * @since 2.17.0\n * @param {Error|any} error\n */\n\n function onUncaughtException(error) {\n if (config.current) {\n config.current.assert.pushResult({\n result: false,\n message: "global failure: ".concat(errorString(error)),\n // We could let callers specify an offset to subtract a number of frames via\n // sourceFromStacktrace, in case they are a wrapper further away from the error\n // handler, and thus reduce some noise in the stack trace. However, we\'re not\n // doing this right now because it would almost never be used in practice given\n // the vast majority of error values will be Error objects, and thus have their\n // own stack trace already.\n source: error && error.stack || sourceFromStacktrace(2)\n });\n } else {\n // The "error" event was added in QUnit 2.17.\n // Increase "bad assertion" stats despite no longer pushing an assertion in this case.\n // This ensures "runEnd" and "QUnit.done()" handlers behave as expected, since the "bad"\n // count is typically how reporters decide on the boolean outcome of the test run.\n globalSuite.globalFailureCount++;\n config.stats.bad++;\n config.stats.all++;\n emit("error", error);\n }\n }\n\n /**\n * Handle a window.onerror error.\n *\n * If there is a current test that sets the internal `ignoreGlobalErrors` field\n * (such as during `assert.throws()`), then the error is ignored and native\n * error reporting is suppressed as well. This is because in browsers, an error\n * can sometimes end up in `window.onerror` instead of in the local try/catch.\n * This ignoring of errors does not apply to our general onUncaughtException\n * method, nor to our `unhandledRejection` handlers, as those are not meant\n * to receive an "expected" error during `assert.throws()`.\n *\n * @see \n * @deprecated since 2.17.0 Use QUnit.onUncaughtException instead.\n * @param {Object} details\n * @param {string} details.message\n * @param {string} details.fileName\n * @param {number} details.lineNumber\n * @param {string|undefined} [details.stacktrace]\n * @return {bool} True if native error reporting should be suppressed.\n */\n\n function onWindowError(details) {\n Logger.warn("QUnit.onError is deprecated and will be removed in QUnit 3.0." + " Please use QUnit.onUncaughtException instead.");\n\n if (config.current && config.current.ignoreGlobalErrors) {\n return true;\n }\n\n var err = new Error(details.message);\n err.stack = details.stacktrace || details.fileName + ":" + details.lineNumber;\n onUncaughtException(err);\n return false;\n }\n\n var QUnit = {};\n var globalSuite = new SuiteReport(); // The initial "currentModule" represents the global (or top-level) module that\n // is not explicitly defined by the user, therefore we add the "globalSuite" to\n // it since each module has a suiteReport associated with it.\n\n config.currentModule.suiteReport = globalSuite;\n var globalStartCalled = false;\n var runStarted = false; // Figure out if we\'re running the tests from a server or not\n\n QUnit.isLocal = window$1 && window$1.location && window$1.location.protocol === "file:"; // Expose the current QUnit version\n\n QUnit.version = "2.17.2";\n\n extend(QUnit, {\n config: config,\n dump: dump,\n equiv: equiv,\n reporters: reporters,\n is: is,\n objectType: objectType,\n on: on,\n onError: onWindowError,\n onUncaughtException: onUncaughtException,\n pushFailure: pushFailure,\n assert: Assert.prototype,\n module: module$1,\n test: test,\n // alias other test flavors for easy access\n todo: test.todo,\n skip: test.skip,\n only: test.only,\n start: function start(count) {\n if (config.current) {\n throw new Error("QUnit.start cannot be called inside a test context.");\n }\n\n var globalStartAlreadyCalled = globalStartCalled;\n globalStartCalled = true;\n\n if (runStarted) {\n throw new Error("Called start() while test already started running");\n }\n\n if (globalStartAlreadyCalled || count > 1) {\n throw new Error("Called start() outside of a test context too many times");\n }\n\n if (config.autostart) {\n throw new Error("Called start() outside of a test context when " + "QUnit.config.autostart was true");\n }\n\n if (!config.pageLoaded) {\n // The page isn\'t completely loaded yet, so we set autostart and then\n // load if we\'re in Node or wait for the browser\'s load event.\n config.autostart = true; // Starts from Node even if .load was not previously called. We still return\n // early otherwise we\'ll wind up "beginning" twice.\n\n if (!document) {\n QUnit.load();\n }\n\n return;\n }\n\n scheduleBegin();\n },\n onUnhandledRejection: function onUnhandledRejection(reason) {\n Logger.warn("QUnit.onUnhandledRejection is deprecated and will be removed in QUnit 3.0." + " Please use QUnit.onUncaughtException instead.");\n onUncaughtException(reason);\n },\n extend: function extend$1() {\n Logger.warn("QUnit.extend is deprecated and will be removed in QUnit 3.0." + " Please use Object.assign instead."); // delegate to utility implementation, which does not warn and can be used elsewhere internally\n\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return extend.apply(this, args);\n },\n load: function load() {\n config.pageLoaded = true; // Initialize the configuration options\n\n extend(config, {\n started: 0,\n updateRate: 1000,\n autostart: true,\n filter: ""\n }, true);\n\n if (!runStarted) {\n config.blocking = false;\n\n if (config.autostart) {\n scheduleBegin();\n }\n }\n },\n stack: function stack(offset) {\n offset = (offset || 0) + 2;\n return sourceFromStacktrace(offset);\n }\n });\n\n registerLoggingCallbacks(QUnit);\n\n function scheduleBegin() {\n runStarted = true; // Add a slight delay to allow definition of more modules and tests.\n\n if (setTimeout$1) {\n setTimeout$1(function () {\n begin();\n });\n } else {\n begin();\n }\n }\n\n function unblockAndAdvanceQueue() {\n config.blocking = false;\n ProcessingQueue.advance();\n }\n\n function begin() {\n if (config.started) {\n unblockAndAdvanceQueue();\n return;\n } // The test run hasn\'t officially begun yet\n // Record the time of the test run\'s beginning\n\n\n config.started = now(); // Delete the loose unnamed module if unused.\n\n if (config.modules[0].name === "" && config.modules[0].tests.length === 0) {\n config.modules.shift();\n } // Avoid unnecessary information by not logging modules\' test environments\n\n\n var l = config.modules.length;\n var modulesLog = [];\n\n for (var i = 0; i < l; i++) {\n modulesLog.push({\n name: config.modules[i].name,\n tests: config.modules[i].tests\n });\n } // The test run is officially beginning now\n\n\n emit("runStart", globalSuite.start(true));\n runLoggingCallbacks("begin", {\n totalTests: Test.count,\n modules: modulesLog\n }).then(unblockAndAdvanceQueue);\n }\n exportQUnit(QUnit);\n\n (function () {\n if (!window$1 || !document) {\n return;\n }\n\n var config = QUnit.config,\n hasOwn = Object.prototype.hasOwnProperty; // Stores fixture HTML for resetting later\n\n function storeFixture() {\n // Avoid overwriting user-defined values\n if (hasOwn.call(config, "fixture")) {\n return;\n }\n\n var fixture = document.getElementById("qunit-fixture");\n\n if (fixture) {\n config.fixture = fixture.cloneNode(true);\n }\n }\n\n QUnit.begin(storeFixture); // Resets the fixture DOM element if available.\n\n function resetFixture() {\n if (config.fixture == null) {\n return;\n }\n\n var fixture = document.getElementById("qunit-fixture");\n\n var resetFixtureType = _typeof(config.fixture);\n\n if (resetFixtureType === "string") {\n // support user defined values for `config.fixture`\n var newFixture = document.createElement("div");\n newFixture.setAttribute("id", "qunit-fixture");\n newFixture.innerHTML = config.fixture;\n fixture.parentNode.replaceChild(newFixture, fixture);\n } else {\n var clonedFixture = config.fixture.cloneNode(true);\n fixture.parentNode.replaceChild(clonedFixture, fixture);\n }\n }\n\n QUnit.testStart(resetFixture);\n })();\n\n (function () {\n // Only interact with URLs via window.location\n var location = typeof window$1 !== "undefined" && window$1.location;\n\n if (!location) {\n return;\n }\n\n var urlParams = getUrlParams();\n QUnit.urlParams = urlParams; // Match module/test by inclusion in an array\n\n QUnit.config.moduleId = [].concat(urlParams.moduleId || []);\n QUnit.config.testId = [].concat(urlParams.testId || []); // Exact case-insensitive match of the module name\n\n QUnit.config.module = urlParams.module; // Regular expression or case-insenstive substring match against "moduleName: testName"\n\n QUnit.config.filter = urlParams.filter; // Test order randomization\n\n if (urlParams.seed === true) {\n // Generate a random seed if the option is specified without a value\n QUnit.config.seed = Math.random().toString(36).slice(2);\n } else if (urlParams.seed) {\n QUnit.config.seed = urlParams.seed;\n } // Add URL-parameter-mapped config values with UI form rendering data\n\n\n QUnit.config.urlConfig.push({\n id: "hidepassed",\n label: "Hide passed tests",\n tooltip: "Only show tests and assertions that fail. Stored as query-strings."\n }, {\n id: "noglobals",\n label: "Check for Globals",\n tooltip: "Enabling this will test if any test introduces new properties on the " + "global object (`window` in Browsers). Stored as query-strings."\n }, {\n id: "notrycatch",\n label: "No try-catch",\n tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " + "exceptions in IE reasonable. Stored as query-strings."\n });\n QUnit.begin(function () {\n var i,\n option,\n urlConfig = QUnit.config.urlConfig;\n\n for (i = 0; i < urlConfig.length; i++) {\n // Options can be either strings or objects with nonempty "id" properties\n option = QUnit.config.urlConfig[i];\n\n if (typeof option !== "string") {\n option = option.id;\n }\n\n if (QUnit.config[option] === undefined) {\n QUnit.config[option] = urlParams[option];\n }\n }\n });\n\n function getUrlParams() {\n var i, param, name, value;\n var urlParams = Object.create(null);\n var params = location.search.slice(1).split("&");\n var length = params.length;\n\n for (i = 0; i < length; i++) {\n if (params[i]) {\n param = params[i].split("=");\n name = decodeQueryParam(param[0]); // Allow just a key to turn on a flag, e.g., test.html?noglobals\n\n value = param.length === 1 || decodeQueryParam(param.slice(1).join("="));\n\n if (name in urlParams) {\n urlParams[name] = [].concat(urlParams[name], value);\n } else {\n urlParams[name] = value;\n }\n }\n }\n\n return urlParams;\n }\n\n function decodeQueryParam(param) {\n return decodeURIComponent(param.replace(/\\+/g, "%20"));\n }\n })();\n\n var fuzzysort$1 = {exports: {}};\n\n (function (module) {\n\n (function (root, UMD) {\n if (module.exports) module.exports = UMD();else root.fuzzysort = UMD();\n })(commonjsGlobal, function UMD() {\n function fuzzysortNew(instanceOptions) {\n var fuzzysort = {\n single: function single(search, target, options) {\n if (!search) return null;\n if (!isObj(search)) search = fuzzysort.getPreparedSearch(search);\n if (!target) return null;\n if (!isObj(target)) target = fuzzysort.getPrepared(target);\n var allowTypo = options && options.allowTypo !== undefined ? options.allowTypo : instanceOptions && instanceOptions.allowTypo !== undefined ? instanceOptions.allowTypo : true;\n var algorithm = allowTypo ? fuzzysort.algorithm : fuzzysort.algorithmNoTypo;\n return algorithm(search, target, search[0]); // var threshold = options && options.threshold || instanceOptions && instanceOptions.threshold || -9007199254740991\n // var result = algorithm(search, target, search[0])\n // if(result === null) return null\n // if(result.score < threshold) return null\n // return result\n },\n go: function go(search, targets, options) {\n if (!search) return noResults;\n search = fuzzysort.prepareSearch(search);\n var searchLowerCode = search[0];\n var threshold = options && options.threshold || instanceOptions && instanceOptions.threshold || -9007199254740991;\n var limit = options && options.limit || instanceOptions && instanceOptions.limit || 9007199254740991;\n var allowTypo = options && options.allowTypo !== undefined ? options.allowTypo : instanceOptions && instanceOptions.allowTypo !== undefined ? instanceOptions.allowTypo : true;\n var algorithm = allowTypo ? fuzzysort.algorithm : fuzzysort.algorithmNoTypo;\n var resultsLen = 0;\n var limitedCount = 0;\n var targetsLen = targets.length; // This code is copy/pasted 3 times for performance reasons [options.keys, options.key, no keys]\n // options.keys\n\n if (options && options.keys) {\n var scoreFn = options.scoreFn || defaultScoreFn;\n var keys = options.keys;\n var keysLen = keys.length;\n\n for (var i = targetsLen - 1; i >= 0; --i) {\n var obj = targets[i];\n var objResults = new Array(keysLen);\n\n for (var keyI = keysLen - 1; keyI >= 0; --keyI) {\n var key = keys[keyI];\n var target = getValue(obj, key);\n\n if (!target) {\n objResults[keyI] = null;\n continue;\n }\n\n if (!isObj(target)) target = fuzzysort.getPrepared(target);\n objResults[keyI] = algorithm(search, target, searchLowerCode);\n }\n\n objResults.obj = obj; // before scoreFn so scoreFn can use it\n\n var score = scoreFn(objResults);\n if (score === null) continue;\n if (score < threshold) continue;\n objResults.score = score;\n\n if (resultsLen < limit) {\n q.add(objResults);\n ++resultsLen;\n } else {\n ++limitedCount;\n if (score > q.peek().score) q.replaceTop(objResults);\n }\n } // options.key\n\n } else if (options && options.key) {\n var key = options.key;\n\n for (var i = targetsLen - 1; i >= 0; --i) {\n var obj = targets[i];\n var target = getValue(obj, key);\n if (!target) continue;\n if (!isObj(target)) target = fuzzysort.getPrepared(target);\n var result = algorithm(search, target, searchLowerCode);\n if (result === null) continue;\n if (result.score < threshold) continue; // have to clone result so duplicate targets from different obj can each reference the correct obj\n\n result = {\n target: result.target,\n _targetLowerCodes: null,\n _nextBeginningIndexes: null,\n score: result.score,\n indexes: result.indexes,\n obj: obj\n }; // hidden\n\n if (resultsLen < limit) {\n q.add(result);\n ++resultsLen;\n } else {\n ++limitedCount;\n if (result.score > q.peek().score) q.replaceTop(result);\n }\n } // no keys\n\n } else {\n for (var i = targetsLen - 1; i >= 0; --i) {\n var target = targets[i];\n if (!target) continue;\n if (!isObj(target)) target = fuzzysort.getPrepared(target);\n var result = algorithm(search, target, searchLowerCode);\n if (result === null) continue;\n if (result.score < threshold) continue;\n\n if (resultsLen < limit) {\n q.add(result);\n ++resultsLen;\n } else {\n ++limitedCount;\n if (result.score > q.peek().score) q.replaceTop(result);\n }\n }\n }\n\n if (resultsLen === 0) return noResults;\n var results = new Array(resultsLen);\n\n for (var i = resultsLen - 1; i >= 0; --i) {\n results[i] = q.poll();\n }\n\n results.total = resultsLen + limitedCount;\n return results;\n },\n goAsync: function goAsync(search, targets, options) {\n var canceled = false;\n var p = new Promise(function (resolve, reject) {\n if (!search) return resolve(noResults);\n search = fuzzysort.prepareSearch(search);\n var searchLowerCode = search[0];\n var q = fastpriorityqueue();\n var iCurrent = targets.length - 1;\n var threshold = options && options.threshold || instanceOptions && instanceOptions.threshold || -9007199254740991;\n var limit = options && options.limit || instanceOptions && instanceOptions.limit || 9007199254740991;\n var allowTypo = options && options.allowTypo !== undefined ? options.allowTypo : instanceOptions && instanceOptions.allowTypo !== undefined ? instanceOptions.allowTypo : true;\n var algorithm = allowTypo ? fuzzysort.algorithm : fuzzysort.algorithmNoTypo;\n var resultsLen = 0;\n var limitedCount = 0;\n\n function step() {\n if (canceled) return reject(\'canceled\');\n var startMs = Date.now(); // This code is copy/pasted 3 times for performance reasons [options.keys, options.key, no keys]\n // options.keys\n\n if (options && options.keys) {\n var scoreFn = options.scoreFn || defaultScoreFn;\n var keys = options.keys;\n var keysLen = keys.length;\n\n for (; iCurrent >= 0; --iCurrent) {\n var obj = targets[iCurrent];\n var objResults = new Array(keysLen);\n\n for (var keyI = keysLen - 1; keyI >= 0; --keyI) {\n var key = keys[keyI];\n var target = getValue(obj, key);\n\n if (!target) {\n objResults[keyI] = null;\n continue;\n }\n\n if (!isObj(target)) target = fuzzysort.getPrepared(target);\n objResults[keyI] = algorithm(search, target, searchLowerCode);\n }\n\n objResults.obj = obj; // before scoreFn so scoreFn can use it\n\n var score = scoreFn(objResults);\n if (score === null) continue;\n if (score < threshold) continue;\n objResults.score = score;\n\n if (resultsLen < limit) {\n q.add(objResults);\n ++resultsLen;\n } else {\n ++limitedCount;\n if (score > q.peek().score) q.replaceTop(objResults);\n }\n\n if (iCurrent % 1000\n /*itemsPerCheck*/\n === 0) {\n if (Date.now() - startMs >= 10\n /*asyncInterval*/\n ) {\n isNode ? setImmediate(step) : setTimeout(step);\n return;\n }\n }\n } // options.key\n\n } else if (options && options.key) {\n var key = options.key;\n\n for (; iCurrent >= 0; --iCurrent) {\n var obj = targets[iCurrent];\n var target = getValue(obj, key);\n if (!target) continue;\n if (!isObj(target)) target = fuzzysort.getPrepared(target);\n var result = algorithm(search, target, searchLowerCode);\n if (result === null) continue;\n if (result.score < threshold) continue; // have to clone result so duplicate targets from different obj can each reference the correct obj\n\n result = {\n target: result.target,\n _targetLowerCodes: null,\n _nextBeginningIndexes: null,\n score: result.score,\n indexes: result.indexes,\n obj: obj\n }; // hidden\n\n if (resultsLen < limit) {\n q.add(result);\n ++resultsLen;\n } else {\n ++limitedCount;\n if (result.score > q.peek().score) q.replaceTop(result);\n }\n\n if (iCurrent % 1000\n /*itemsPerCheck*/\n === 0) {\n if (Date.now() - startMs >= 10\n /*asyncInterval*/\n ) {\n isNode ? setImmediate(step) : setTimeout(step);\n return;\n }\n }\n } // no keys\n\n } else {\n for (; iCurrent >= 0; --iCurrent) {\n var target = targets[iCurrent];\n if (!target) continue;\n if (!isObj(target)) target = fuzzysort.getPrepared(target);\n var result = algorithm(search, target, searchLowerCode);\n if (result === null) continue;\n if (result.score < threshold) continue;\n\n if (resultsLen < limit) {\n q.add(result);\n ++resultsLen;\n } else {\n ++limitedCount;\n if (result.score > q.peek().score) q.replaceTop(result);\n }\n\n if (iCurrent % 1000\n /*itemsPerCheck*/\n === 0) {\n if (Date.now() - startMs >= 10\n /*asyncInterval*/\n ) {\n isNode ? setImmediate(step) : setTimeout(step);\n return;\n }\n }\n }\n }\n\n if (resultsLen === 0) return resolve(noResults);\n var results = new Array(resultsLen);\n\n for (var i = resultsLen - 1; i >= 0; --i) {\n results[i] = q.poll();\n }\n\n results.total = resultsLen + limitedCount;\n resolve(results);\n }\n\n isNode ? setImmediate(step) : step();\n });\n\n p.cancel = function () {\n canceled = true;\n };\n\n return p;\n },\n highlight: function highlight(result, hOpen, hClose) {\n if (result === null) return null;\n if (hOpen === undefined) hOpen = \'\';\n if (hClose === undefined) hClose = \'\';\n var highlighted = \'\';\n var matchesIndex = 0;\n var opened = false;\n var target = result.target;\n var targetLen = target.length;\n var matchesBest = result.indexes;\n\n for (var i = 0; i < targetLen; ++i) {\n var char = target[i];\n\n if (matchesBest[matchesIndex] === i) {\n ++matchesIndex;\n\n if (!opened) {\n opened = true;\n highlighted += hOpen;\n }\n\n if (matchesIndex === matchesBest.length) {\n highlighted += char + hClose + target.substr(i + 1);\n break;\n }\n } else {\n if (opened) {\n opened = false;\n highlighted += hClose;\n }\n }\n\n highlighted += char;\n }\n\n return highlighted;\n },\n prepare: function prepare(target) {\n if (!target) return;\n return {\n target: target,\n _targetLowerCodes: fuzzysort.prepareLowerCodes(target),\n _nextBeginningIndexes: null,\n score: null,\n indexes: null,\n obj: null\n }; // hidden\n },\n prepareSlow: function prepareSlow(target) {\n if (!target) return;\n return {\n target: target,\n _targetLowerCodes: fuzzysort.prepareLowerCodes(target),\n _nextBeginningIndexes: fuzzysort.prepareNextBeginningIndexes(target),\n score: null,\n indexes: null,\n obj: null\n }; // hidden\n },\n prepareSearch: function prepareSearch(search) {\n if (!search) return;\n return fuzzysort.prepareLowerCodes(search);\n },\n // Below this point is only internal code\n // Below this point is only internal code\n // Below this point is only internal code\n // Below this point is only internal code\n getPrepared: function getPrepared(target) {\n if (target.length > 999) return fuzzysort.prepare(target); // don\'t cache huge targets\n\n var targetPrepared = preparedCache.get(target);\n if (targetPrepared !== undefined) return targetPrepared;\n targetPrepared = fuzzysort.prepare(target);\n preparedCache.set(target, targetPrepared);\n return targetPrepared;\n },\n getPreparedSearch: function getPreparedSearch(search) {\n if (search.length > 999) return fuzzysort.prepareSearch(search); // don\'t cache huge searches\n\n var searchPrepared = preparedSearchCache.get(search);\n if (searchPrepared !== undefined) return searchPrepared;\n searchPrepared = fuzzysort.prepareSearch(search);\n preparedSearchCache.set(search, searchPrepared);\n return searchPrepared;\n },\n algorithm: function algorithm(searchLowerCodes, prepared, searchLowerCode) {\n var targetLowerCodes = prepared._targetLowerCodes;\n var searchLen = searchLowerCodes.length;\n var targetLen = targetLowerCodes.length;\n var searchI = 0; // where we at\n\n var targetI = 0; // where you at\n\n var typoSimpleI = 0;\n var matchesSimpleLen = 0; // very basic fuzzy match; to remove non-matching targets ASAP!\n // walk through target. find sequential matches.\n // if all chars aren\'t found then exit\n\n for (;;) {\n var isMatch = searchLowerCode === targetLowerCodes[targetI];\n\n if (isMatch) {\n matchesSimple[matchesSimpleLen++] = targetI;\n ++searchI;\n if (searchI === searchLen) break;\n searchLowerCode = searchLowerCodes[typoSimpleI === 0 ? searchI : typoSimpleI === searchI ? searchI + 1 : typoSimpleI === searchI - 1 ? searchI - 1 : searchI];\n }\n\n ++targetI;\n\n if (targetI >= targetLen) {\n // Failed to find searchI\n // Check for typo or exit\n // we go as far as possible before trying to transpose\n // then we transpose backwards until we reach the beginning\n for (;;) {\n if (searchI <= 1) return null; // not allowed to transpose first char\n\n if (typoSimpleI === 0) {\n // we haven\'t tried to transpose yet\n --searchI;\n var searchLowerCodeNew = searchLowerCodes[searchI];\n if (searchLowerCode === searchLowerCodeNew) continue; // doesn\'t make sense to transpose a repeat char\n\n typoSimpleI = searchI;\n } else {\n if (typoSimpleI === 1) return null; // reached the end of the line for transposing\n\n --typoSimpleI;\n searchI = typoSimpleI;\n searchLowerCode = searchLowerCodes[searchI + 1];\n var searchLowerCodeNew = searchLowerCodes[searchI];\n if (searchLowerCode === searchLowerCodeNew) continue; // doesn\'t make sense to transpose a repeat char\n }\n\n matchesSimpleLen = searchI;\n targetI = matchesSimple[matchesSimpleLen - 1] + 1;\n break;\n }\n }\n }\n\n var searchI = 0;\n var typoStrictI = 0;\n var successStrict = false;\n var matchesStrictLen = 0;\n var nextBeginningIndexes = prepared._nextBeginningIndexes;\n if (nextBeginningIndexes === null) nextBeginningIndexes = prepared._nextBeginningIndexes = fuzzysort.prepareNextBeginningIndexes(prepared.target);\n var firstPossibleI = targetI = matchesSimple[0] === 0 ? 0 : nextBeginningIndexes[matchesSimple[0] - 1]; // Our target string successfully matched all characters in sequence!\n // Let\'s try a more advanced and strict test to improve the score\n // only count it as a match if it\'s consecutive or a beginning character!\n\n if (targetI !== targetLen) for (;;) {\n if (targetI >= targetLen) {\n // We failed to find a good spot for this search char, go back to the previous search char and force it forward\n if (searchI <= 0) {\n // We failed to push chars forward for a better match\n // transpose, starting from the beginning\n ++typoStrictI;\n if (typoStrictI > searchLen - 2) break;\n if (searchLowerCodes[typoStrictI] === searchLowerCodes[typoStrictI + 1]) continue; // doesn\'t make sense to transpose a repeat char\n\n targetI = firstPossibleI;\n continue;\n }\n\n --searchI;\n var lastMatch = matchesStrict[--matchesStrictLen];\n targetI = nextBeginningIndexes[lastMatch];\n } else {\n var isMatch = searchLowerCodes[typoStrictI === 0 ? searchI : typoStrictI === searchI ? searchI + 1 : typoStrictI === searchI - 1 ? searchI - 1 : searchI] === targetLowerCodes[targetI];\n\n if (isMatch) {\n matchesStrict[matchesStrictLen++] = targetI;\n ++searchI;\n\n if (searchI === searchLen) {\n successStrict = true;\n break;\n }\n\n ++targetI;\n } else {\n targetI = nextBeginningIndexes[targetI];\n }\n }\n }\n {\n // tally up the score & keep track of matches for highlighting later\n if (successStrict) {\n var matchesBest = matchesStrict;\n var matchesBestLen = matchesStrictLen;\n } else {\n var matchesBest = matchesSimple;\n var matchesBestLen = matchesSimpleLen;\n }\n\n var score = 0;\n var lastTargetI = -1;\n\n for (var i = 0; i < searchLen; ++i) {\n var targetI = matchesBest[i]; // score only goes down if they\'re not consecutive\n\n if (lastTargetI !== targetI - 1) score -= targetI;\n lastTargetI = targetI;\n }\n\n if (!successStrict) {\n score *= 1000;\n if (typoSimpleI !== 0) score += -20;\n /*typoPenalty*/\n } else {\n if (typoStrictI !== 0) score += -20;\n /*typoPenalty*/\n }\n\n score -= targetLen - searchLen;\n prepared.score = score;\n prepared.indexes = new Array(matchesBestLen);\n\n for (var i = matchesBestLen - 1; i >= 0; --i) {\n prepared.indexes[i] = matchesBest[i];\n }\n\n return prepared;\n }\n },\n algorithmNoTypo: function algorithmNoTypo(searchLowerCodes, prepared, searchLowerCode) {\n var targetLowerCodes = prepared._targetLowerCodes;\n var searchLen = searchLowerCodes.length;\n var targetLen = targetLowerCodes.length;\n var searchI = 0; // where we at\n\n var targetI = 0; // where you at\n\n var matchesSimpleLen = 0; // very basic fuzzy match; to remove non-matching targets ASAP!\n // walk through target. find sequential matches.\n // if all chars aren\'t found then exit\n\n for (;;) {\n var isMatch = searchLowerCode === targetLowerCodes[targetI];\n\n if (isMatch) {\n matchesSimple[matchesSimpleLen++] = targetI;\n ++searchI;\n if (searchI === searchLen) break;\n searchLowerCode = searchLowerCodes[searchI];\n }\n\n ++targetI;\n if (targetI >= targetLen) return null; // Failed to find searchI\n }\n\n var searchI = 0;\n var successStrict = false;\n var matchesStrictLen = 0;\n var nextBeginningIndexes = prepared._nextBeginningIndexes;\n if (nextBeginningIndexes === null) nextBeginningIndexes = prepared._nextBeginningIndexes = fuzzysort.prepareNextBeginningIndexes(prepared.target);\n targetI = matchesSimple[0] === 0 ? 0 : nextBeginningIndexes[matchesSimple[0] - 1]; // Our target string successfully matched all characters in sequence!\n // Let\'s try a more advanced and strict test to improve the score\n // only count it as a match if it\'s consecutive or a beginning character!\n\n if (targetI !== targetLen) for (;;) {\n if (targetI >= targetLen) {\n // We failed to find a good spot for this search char, go back to the previous search char and force it forward\n if (searchI <= 0) break; // We failed to push chars forward for a better match\n\n --searchI;\n var lastMatch = matchesStrict[--matchesStrictLen];\n targetI = nextBeginningIndexes[lastMatch];\n } else {\n var isMatch = searchLowerCodes[searchI] === targetLowerCodes[targetI];\n\n if (isMatch) {\n matchesStrict[matchesStrictLen++] = targetI;\n ++searchI;\n\n if (searchI === searchLen) {\n successStrict = true;\n break;\n }\n\n ++targetI;\n } else {\n targetI = nextBeginningIndexes[targetI];\n }\n }\n }\n {\n // tally up the score & keep track of matches for highlighting later\n if (successStrict) {\n var matchesBest = matchesStrict;\n var matchesBestLen = matchesStrictLen;\n } else {\n var matchesBest = matchesSimple;\n var matchesBestLen = matchesSimpleLen;\n }\n\n var score = 0;\n var lastTargetI = -1;\n\n for (var i = 0; i < searchLen; ++i) {\n var targetI = matchesBest[i]; // score only goes down if they\'re not consecutive\n\n if (lastTargetI !== targetI - 1) score -= targetI;\n lastTargetI = targetI;\n }\n\n if (!successStrict) score *= 1000;\n score -= targetLen - searchLen;\n prepared.score = score;\n prepared.indexes = new Array(matchesBestLen);\n\n for (var i = matchesBestLen - 1; i >= 0; --i) {\n prepared.indexes[i] = matchesBest[i];\n }\n\n return prepared;\n }\n },\n prepareLowerCodes: function prepareLowerCodes(str) {\n var strLen = str.length;\n var lowerCodes = []; // new Array(strLen) sparse array is too slow\n\n var lower = str.toLowerCase();\n\n for (var i = 0; i < strLen; ++i) {\n lowerCodes[i] = lower.charCodeAt(i);\n }\n\n return lowerCodes;\n },\n prepareBeginningIndexes: function prepareBeginningIndexes(target) {\n var targetLen = target.length;\n var beginningIndexes = [];\n var beginningIndexesLen = 0;\n var wasUpper = false;\n var wasAlphanum = false;\n\n for (var i = 0; i < targetLen; ++i) {\n var targetCode = target.charCodeAt(i);\n var isUpper = targetCode >= 65 && targetCode <= 90;\n var isAlphanum = isUpper || targetCode >= 97 && targetCode <= 122 || targetCode >= 48 && targetCode <= 57;\n var isBeginning = isUpper && !wasUpper || !wasAlphanum || !isAlphanum;\n wasUpper = isUpper;\n wasAlphanum = isAlphanum;\n if (isBeginning) beginningIndexes[beginningIndexesLen++] = i;\n }\n\n return beginningIndexes;\n },\n prepareNextBeginningIndexes: function prepareNextBeginningIndexes(target) {\n var targetLen = target.length;\n var beginningIndexes = fuzzysort.prepareBeginningIndexes(target);\n var nextBeginningIndexes = []; // new Array(targetLen) sparse array is too slow\n\n var lastIsBeginning = beginningIndexes[0];\n var lastIsBeginningI = 0;\n\n for (var i = 0; i < targetLen; ++i) {\n if (lastIsBeginning > i) {\n nextBeginningIndexes[i] = lastIsBeginning;\n } else {\n lastIsBeginning = beginningIndexes[++lastIsBeginningI];\n nextBeginningIndexes[i] = lastIsBeginning === undefined ? targetLen : lastIsBeginning;\n }\n }\n\n return nextBeginningIndexes;\n },\n cleanup: cleanup,\n new: fuzzysortNew\n };\n return fuzzysort;\n } // fuzzysortNew\n // This stuff is outside fuzzysortNew, because it\'s shared with instances of fuzzysort.new()\n\n\n var isNode = typeof commonjsRequire !== \'undefined\' && typeof window === \'undefined\'; // var MAX_INT = Number.MAX_SAFE_INTEGER\n // var MIN_INT = Number.MIN_VALUE\n\n var preparedCache = new Map();\n var preparedSearchCache = new Map();\n var noResults = [];\n noResults.total = 0;\n var matchesSimple = [];\n var matchesStrict = [];\n\n function cleanup() {\n preparedCache.clear();\n preparedSearchCache.clear();\n matchesSimple = [];\n matchesStrict = [];\n }\n\n function defaultScoreFn(a) {\n var max = -9007199254740991;\n\n for (var i = a.length - 1; i >= 0; --i) {\n var result = a[i];\n if (result === null) continue;\n var score = result.score;\n if (score > max) max = score;\n }\n\n if (max === -9007199254740991) return null;\n return max;\n } // prop = \'key\' 2.5ms optimized for this case, seems to be about as fast as direct obj[prop]\n // prop = \'key1.key2\' 10ms\n // prop = [\'key1\', \'key2\'] 27ms\n\n\n function getValue(obj, prop) {\n var tmp = obj[prop];\n if (tmp !== undefined) return tmp;\n var segs = prop;\n if (!Array.isArray(prop)) segs = prop.split(\'.\');\n var len = segs.length;\n var i = -1;\n\n while (obj && ++i < len) {\n obj = obj[segs[i]];\n }\n\n return obj;\n }\n\n function isObj(x) {\n return _typeof(x) === \'object\';\n } // faster as a function\n // Hacked version of https://github.com/lemire/FastPriorityQueue.js\n\n\n var fastpriorityqueue = function fastpriorityqueue() {\n var r = [],\n o = 0,\n e = {};\n\n function n() {\n for (var e = 0, n = r[e], c = 1; c < o;) {\n var f = c + 1;\n e = c, f < o && r[f].score < r[c].score && (e = f), r[e - 1 >> 1] = r[e], c = 1 + (e << 1);\n }\n\n for (var a = e - 1 >> 1; e > 0 && n.score < r[a].score; a = (e = a) - 1 >> 1) {\n r[e] = r[a];\n }\n\n r[e] = n;\n }\n\n return e.add = function (e) {\n var n = o;\n r[o++] = e;\n\n for (var c = n - 1 >> 1; n > 0 && e.score < r[c].score; c = (n = c) - 1 >> 1) {\n r[n] = r[c];\n }\n\n r[n] = e;\n }, e.poll = function () {\n if (0 !== o) {\n var e = r[0];\n return r[0] = r[--o], n(), e;\n }\n }, e.peek = function (e) {\n if (0 !== o) return r[0];\n }, e.replaceTop = function (o) {\n r[0] = o, n();\n }, e;\n };\n\n var q = fastpriorityqueue(); // reuse this, except for async, it needs to make its own\n\n return fuzzysortNew();\n }); // UMD\n // TODO: (performance) wasm version!?\n // TODO: (performance) layout memory in an optimal way to go fast by avoiding cache misses\n // TODO: (performance) preparedCache is a memory leak\n // TODO: (like sublime) backslash === forwardslash\n // TODO: (performance) i have no idea how well optizmied the allowing typos algorithm is\n\n })(fuzzysort$1);\n\n var fuzzysort = fuzzysort$1.exports;\n\n var stats = {\n failedTests: [],\n defined: 0,\n completed: 0\n }; // Escape text for attribute or text content.\n\n function escapeText(s) {\n if (!s) {\n return "";\n }\n\n s = s + ""; // Both single quotes and double quotes (for attributes)\n\n return s.replace(/[\'"<>&]/g, function (s) {\n switch (s) {\n case "\'":\n return "'";\n\n case "\\"":\n return """;\n\n case "<":\n return "<";\n\n case ">":\n return ">";\n\n case "&":\n return "&";\n }\n });\n }\n\n (function () {\n // Don\'t load the HTML Reporter on non-browser environments\n if (!window$1 || !document) {\n return;\n }\n\n var config = QUnit.config,\n hiddenTests = [],\n collapseNext = false,\n hasOwn = Object.prototype.hasOwnProperty,\n unfilteredUrl = setUrl({\n filter: undefined,\n module: undefined,\n moduleId: undefined,\n testId: undefined\n });\n\n function trim(string) {\n if (typeof string.trim === "function") {\n return string.trim();\n } else {\n return string.replace(/^\\s+|\\s+$/g, "");\n }\n }\n\n function addEvent(elem, type, fn) {\n elem.addEventListener(type, fn, false);\n }\n\n function removeEvent(elem, type, fn) {\n elem.removeEventListener(type, fn, false);\n }\n\n function addEvents(elems, type, fn) {\n var i = elems.length;\n\n while (i--) {\n addEvent(elems[i], type, fn);\n }\n }\n\n function hasClass(elem, name) {\n return (" " + elem.className + " ").indexOf(" " + name + " ") >= 0;\n }\n\n function addClass(elem, name) {\n if (!hasClass(elem, name)) {\n elem.className += (elem.className ? " " : "") + name;\n }\n }\n\n function toggleClass(elem, name, force) {\n if (force || typeof force === "undefined" && !hasClass(elem, name)) {\n addClass(elem, name);\n } else {\n removeClass(elem, name);\n }\n }\n\n function removeClass(elem, name) {\n var set = " " + elem.className + " "; // Class name may appear multiple times\n\n while (set.indexOf(" " + name + " ") >= 0) {\n set = set.replace(" " + name + " ", " ");\n } // Trim for prettiness\n\n\n elem.className = trim(set);\n }\n\n function id(name) {\n return document.getElementById && document.getElementById(name);\n }\n\n function abortTests() {\n var abortButton = id("qunit-abort-tests-button");\n\n if (abortButton) {\n abortButton.disabled = true;\n abortButton.innerHTML = "Aborting...";\n }\n\n QUnit.config.queue.length = 0;\n return false;\n }\n\n function interceptNavigation(ev) {\n // Trim potential accidental whitespace so that QUnit doesn\'t throw an error about no tests matching the filter.\n var filterInputElem = id("qunit-filter-input");\n filterInputElem.value = trim(filterInputElem.value);\n applyUrlParams();\n\n if (ev && ev.preventDefault) {\n ev.preventDefault();\n }\n\n return false;\n }\n\n function getUrlConfigHtml() {\n var i,\n j,\n val,\n escaped,\n escapedTooltip,\n selection = false,\n urlConfig = config.urlConfig,\n urlConfigHtml = "";\n\n for (i = 0; i < urlConfig.length; i++) {\n // Options can be either strings or objects with nonempty "id" properties\n val = config.urlConfig[i];\n\n if (typeof val === "string") {\n val = {\n id: val,\n label: val\n };\n }\n\n escaped = escapeText(val.id);\n escapedTooltip = escapeText(val.tooltip);\n\n if (!val.value || typeof val.value === "string") {\n urlConfigHtml += "";\n } else {\n urlConfigHtml += "";\n }\n }\n\n return urlConfigHtml;\n } // Handle "click" events on toolbar checkboxes and "change" for select menus.\n // Updates the URL with the new state of `config.urlConfig` values.\n\n\n function toolbarChanged() {\n var updatedUrl,\n value,\n tests,\n field = this,\n params = {}; // Detect if field is a select menu or a checkbox\n\n if ("selectedIndex" in field) {\n value = field.options[field.selectedIndex].value || undefined;\n } else {\n value = field.checked ? field.defaultValue || true : undefined;\n }\n\n params[field.name] = value;\n updatedUrl = setUrl(params); // Check if we can apply the change without a page refresh\n\n if ("hidepassed" === field.name && "replaceState" in window$1.history) {\n QUnit.urlParams[field.name] = value;\n config[field.name] = value || false;\n tests = id("qunit-tests");\n\n if (tests) {\n var length = tests.children.length;\n var children = tests.children;\n\n if (field.checked) {\n for (var i = 0; i < length; i++) {\n var test = children[i];\n var className = test ? test.className : "";\n var classNameHasPass = className.indexOf("pass") > -1;\n var classNameHasSkipped = className.indexOf("skipped") > -1;\n\n if (classNameHasPass || classNameHasSkipped) {\n hiddenTests.push(test);\n }\n }\n\n var _iterator = _createForOfIteratorHelper(hiddenTests),\n _step;\n\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var hiddenTest = _step.value;\n tests.removeChild(hiddenTest);\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n } else {\n while ((test = hiddenTests.pop()) != null) {\n tests.appendChild(test);\n }\n }\n }\n\n window$1.history.replaceState(null, "", updatedUrl);\n } else {\n window$1.location = updatedUrl;\n }\n }\n\n function setUrl(params) {\n var key,\n arrValue,\n i,\n querystring = "?",\n location = window$1.location;\n params = extend(extend({}, QUnit.urlParams), params);\n\n for (key in params) {\n // Skip inherited or undefined properties\n if (hasOwn.call(params, key) && params[key] !== undefined) {\n // Output a parameter for each value of this key\n // (but usually just one)\n arrValue = [].concat(params[key]);\n\n for (i = 0; i < arrValue.length; i++) {\n querystring += encodeURIComponent(key);\n\n if (arrValue[i] !== true) {\n querystring += "=" + encodeURIComponent(arrValue[i]);\n }\n\n querystring += "&";\n }\n }\n }\n\n return location.protocol + "//" + location.host + location.pathname + querystring.slice(0, -1);\n }\n\n function applyUrlParams() {\n var i,\n selectedModules = [],\n modulesList = id("qunit-modulefilter-dropdown-list").getElementsByTagName("input"),\n filter = id("qunit-filter-input").value;\n\n for (i = 0; i < modulesList.length; i++) {\n if (modulesList[i].checked) {\n selectedModules.push(modulesList[i].value);\n }\n }\n\n window$1.location = setUrl({\n filter: filter === "" ? undefined : filter,\n moduleId: selectedModules.length === 0 ? undefined : selectedModules,\n // Remove module and testId filter\n module: undefined,\n testId: undefined\n });\n }\n\n function toolbarUrlConfigContainer() {\n var urlConfigContainer = document.createElement("span");\n urlConfigContainer.innerHTML = getUrlConfigHtml();\n addClass(urlConfigContainer, "qunit-url-config");\n addEvents(urlConfigContainer.getElementsByTagName("input"), "change", toolbarChanged);\n addEvents(urlConfigContainer.getElementsByTagName("select"), "change", toolbarChanged);\n return urlConfigContainer;\n }\n\n function abortTestsButton() {\n var button = document.createElement("button");\n button.id = "qunit-abort-tests-button";\n button.innerHTML = "Abort";\n addEvent(button, "click", abortTests);\n return button;\n }\n\n function toolbarLooseFilter() {\n var filter = document.createElement("form"),\n label = document.createElement("label"),\n input = document.createElement("input"),\n button = document.createElement("button");\n addClass(filter, "qunit-filter");\n label.innerHTML = "Filter: ";\n input.type = "text";\n input.value = config.filter || "";\n input.name = "filter";\n input.id = "qunit-filter-input";\n button.innerHTML = "Go";\n label.appendChild(input);\n filter.appendChild(label);\n filter.appendChild(document.createTextNode(" "));\n filter.appendChild(button);\n addEvent(filter, "submit", interceptNavigation);\n return filter;\n }\n\n function moduleListHtml(modules) {\n var i,\n checked,\n html = "";\n\n for (i = 0; i < modules.length; i++) {\n if (modules[i].name !== "") {\n checked = config.moduleId.indexOf(modules[i].moduleId) > -1;\n html += "
  • ";\n }\n }\n\n return html;\n }\n\n function toolbarModuleFilter() {\n var commit,\n reset,\n moduleFilter = document.createElement("form"),\n label = document.createElement("label"),\n moduleSearch = document.createElement("input"),\n dropDown = document.createElement("div"),\n actions = document.createElement("span"),\n applyButton = document.createElement("button"),\n resetButton = document.createElement("button"),\n allModulesLabel = document.createElement("label"),\n allCheckbox = document.createElement("input"),\n dropDownList = document.createElement("ul"),\n dirty = false;\n moduleSearch.id = "qunit-modulefilter-search";\n moduleSearch.autocomplete = "off";\n addEvent(moduleSearch, "input", searchInput);\n addEvent(moduleSearch, "input", searchFocus);\n addEvent(moduleSearch, "focus", searchFocus);\n addEvent(moduleSearch, "click", searchFocus);\n config.modules.forEach(function (module) {\n return module.namePrepared = fuzzysort.prepare(module.name);\n });\n label.id = "qunit-modulefilter-search-container";\n label.innerHTML = "Module: ";\n label.appendChild(moduleSearch);\n applyButton.textContent = "Apply";\n applyButton.style.display = "none";\n resetButton.textContent = "Reset";\n resetButton.type = "reset";\n resetButton.style.display = "none";\n allCheckbox.type = "checkbox";\n allCheckbox.checked = config.moduleId.length === 0;\n allModulesLabel.className = "clickable";\n\n if (config.moduleId.length) {\n allModulesLabel.className = "checked";\n }\n\n allModulesLabel.appendChild(allCheckbox);\n allModulesLabel.appendChild(document.createTextNode("All modules"));\n actions.id = "qunit-modulefilter-actions";\n actions.appendChild(applyButton);\n actions.appendChild(resetButton);\n actions.appendChild(allModulesLabel);\n commit = actions.firstChild;\n reset = commit.nextSibling;\n addEvent(commit, "click", applyUrlParams);\n dropDownList.id = "qunit-modulefilter-dropdown-list";\n dropDownList.innerHTML = moduleListHtml(config.modules);\n dropDown.id = "qunit-modulefilter-dropdown";\n dropDown.style.display = "none";\n dropDown.appendChild(actions);\n dropDown.appendChild(dropDownList);\n addEvent(dropDown, "change", selectionChange);\n selectionChange();\n moduleFilter.id = "qunit-modulefilter";\n moduleFilter.appendChild(label);\n moduleFilter.appendChild(dropDown);\n addEvent(moduleFilter, "submit", interceptNavigation);\n addEvent(moduleFilter, "reset", function () {\n // Let the reset happen, then update styles\n window$1.setTimeout(selectionChange);\n }); // Enables show/hide for the dropdown\n\n function searchFocus() {\n if (dropDown.style.display !== "none") {\n return;\n }\n\n dropDown.style.display = "block";\n addEvent(document, "click", hideHandler);\n addEvent(document, "keydown", hideHandler); // Hide on Escape keydown or outside-container click\n\n function hideHandler(e) {\n var inContainer = moduleFilter.contains(e.target);\n\n if (e.keyCode === 27 || !inContainer) {\n if (e.keyCode === 27 && inContainer) {\n moduleSearch.focus();\n }\n\n dropDown.style.display = "none";\n removeEvent(document, "click", hideHandler);\n removeEvent(document, "keydown", hideHandler);\n moduleSearch.value = "";\n searchInput();\n }\n }\n }\n\n function filterModules(searchText) {\n if (searchText === "") {\n return config.modules;\n }\n\n return fuzzysort.go(searchText, config.modules, {\n key: "namePrepared",\n threshold: -10000\n }).map(function (module) {\n return module.obj;\n });\n } // Processes module search box input\n\n\n var searchInputTimeout;\n\n function searchInput() {\n window$1.clearTimeout(searchInputTimeout);\n searchInputTimeout = window$1.setTimeout(function () {\n var searchText = moduleSearch.value.toLowerCase(),\n filteredModules = filterModules(searchText);\n dropDownList.innerHTML = moduleListHtml(filteredModules);\n }, 200);\n } // Processes selection changes\n\n\n function selectionChange(evt) {\n var i,\n item,\n checkbox = evt && evt.target || allCheckbox,\n modulesList = dropDownList.getElementsByTagName("input"),\n selectedNames = [];\n toggleClass(checkbox.parentNode, "checked", checkbox.checked);\n dirty = false;\n\n if (checkbox.checked && checkbox !== allCheckbox) {\n allCheckbox.checked = false;\n removeClass(allCheckbox.parentNode, "checked");\n }\n\n for (i = 0; i < modulesList.length; i++) {\n item = modulesList[i];\n\n if (!evt) {\n toggleClass(item.parentNode, "checked", item.checked);\n } else if (checkbox === allCheckbox && checkbox.checked) {\n item.checked = false;\n removeClass(item.parentNode, "checked");\n }\n\n dirty = dirty || item.checked !== item.defaultChecked;\n\n if (item.checked) {\n selectedNames.push(item.parentNode.textContent);\n }\n }\n\n commit.style.display = reset.style.display = dirty ? "" : "none";\n moduleSearch.placeholder = selectedNames.join(", ") || allCheckbox.parentNode.textContent;\n moduleSearch.title = "Type to filter list. Current selection:\\n" + (selectedNames.join("\\n") || allCheckbox.parentNode.textContent);\n }\n\n return moduleFilter;\n }\n\n function toolbarFilters() {\n var toolbarFilters = document.createElement("span");\n toolbarFilters.id = "qunit-toolbar-filters";\n toolbarFilters.appendChild(toolbarLooseFilter());\n toolbarFilters.appendChild(toolbarModuleFilter());\n return toolbarFilters;\n }\n\n function appendToolbar() {\n var toolbar = id("qunit-testrunner-toolbar");\n\n if (toolbar) {\n toolbar.appendChild(toolbarUrlConfigContainer());\n toolbar.appendChild(toolbarFilters());\n toolbar.appendChild(document.createElement("div")).className = "clearfix";\n }\n }\n\n function appendHeader() {\n var header = id("qunit-header");\n\n if (header) {\n header.innerHTML = "" + header.innerHTML + " ";\n }\n }\n\n function appendBanner() {\n var banner = id("qunit-banner");\n\n if (banner) {\n banner.className = "";\n }\n }\n\n function appendTestResults() {\n var tests = id("qunit-tests"),\n result = id("qunit-testresult"),\n controls;\n\n if (result) {\n result.parentNode.removeChild(result);\n }\n\n if (tests) {\n tests.innerHTML = "";\n result = document.createElement("p");\n result.id = "qunit-testresult";\n result.className = "result";\n tests.parentNode.insertBefore(result, tests);\n result.innerHTML = "
    Running...
     
    " + "
    " + "
    ";\n controls = id("qunit-testresult-controls");\n }\n\n if (controls) {\n controls.appendChild(abortTestsButton());\n }\n }\n\n function appendFilteredTest() {\n var testId = QUnit.config.testId;\n\n if (!testId || testId.length <= 0) {\n return "";\n }\n\n return "
    Rerunning selected tests: " + escapeText(testId.join(", ")) + " Run all tests
    ";\n }\n\n function appendUserAgent() {\n var userAgent = id("qunit-userAgent");\n\n if (userAgent) {\n userAgent.innerHTML = "";\n userAgent.appendChild(document.createTextNode("QUnit " + QUnit.version + "; " + navigator.userAgent));\n }\n }\n\n function appendInterface() {\n var qunit = id("qunit"); // For compat with QUnit 1.2, and to support fully custom theme HTML,\n // we will use any existing elements if no id="qunit" element exists.\n //\n // Note that we don\'t fail or fallback to creating it ourselves,\n // because not having id="qunit" (and not having the below elements)\n // simply means QUnit acts headless, allowing users to use their own\n // reporters, or for a test runner to listen for events directly without\n // having the HTML reporter actively render anything.\n\n if (qunit) {\n qunit.setAttribute("role", "main"); // Since QUnit 1.3, these are created automatically if the page\n // contains id="qunit".\n\n qunit.innerHTML = "

    " + escapeText(document.title) + "

    " + "

    " + "
    " + appendFilteredTest() + "

    " + "
      ";\n }\n\n appendHeader();\n appendBanner();\n appendTestResults();\n appendUserAgent();\n appendToolbar();\n }\n\n function appendTest(name, testId, moduleName) {\n var title,\n rerunTrigger,\n testBlock,\n assertList,\n tests = id("qunit-tests");\n\n if (!tests) {\n return;\n }\n\n title = document.createElement("strong");\n title.innerHTML = getNameHtml(name, moduleName);\n testBlock = document.createElement("li");\n testBlock.appendChild(title); // No ID or rerun link for "global failure" blocks\n\n if (testId !== undefined) {\n rerunTrigger = document.createElement("a");\n rerunTrigger.innerHTML = "Rerun";\n rerunTrigger.href = setUrl({\n testId: testId\n });\n testBlock.id = "qunit-test-output-" + testId;\n testBlock.appendChild(rerunTrigger);\n }\n\n assertList = document.createElement("ol");\n assertList.className = "qunit-assert-list";\n testBlock.appendChild(assertList);\n tests.appendChild(testBlock);\n return testBlock;\n } // HTML Reporter initialization and load\n\n\n QUnit.on("runStart", function (runStart) {\n stats.defined = runStart.testCounts.total;\n });\n QUnit.begin(function () {\n // Initialize QUnit elements\n // This is done from begin() instead of runStart, because\n // urlparams.js uses begin(), which we need to wait for.\n // urlparams.js in turn uses begin() to allow plugins to\n // add entries to QUnit.config.urlConfig, which may be done\n // asynchronously.\n // \n appendInterface();\n });\n\n function getRerunFailedHtml(failedTests) {\n if (failedTests.length === 0) {\n return "";\n }\n\n var href = setUrl({\n testId: failedTests\n });\n return ["
      ", failedTests.length === 1 ? "Rerun 1 failed test" : "Rerun " + failedTests.length + " failed tests", ""].join("");\n }\n\n QUnit.on("runEnd", function (runEnd) {\n var banner = id("qunit-banner"),\n tests = id("qunit-tests"),\n abortButton = id("qunit-abort-tests-button"),\n assertPassed = config.stats.all - config.stats.bad,\n html = [runEnd.testCounts.total, " tests completed in ", runEnd.runtime, " milliseconds, with ", runEnd.testCounts.failed, " failed, ", runEnd.testCounts.skipped, " skipped, and ", runEnd.testCounts.todo, " todo.
      ", "", assertPassed, " assertions of ", config.stats.all, " passed, ", config.stats.bad, " failed.", getRerunFailedHtml(stats.failedTests)].join(""),\n test,\n assertLi,\n assertList; // Update remaining tests to aborted\n\n if (abortButton && abortButton.disabled) {\n html = "Tests aborted after " + runEnd.runtime + " milliseconds.";\n\n for (var i = 0; i < tests.children.length; i++) {\n test = tests.children[i];\n\n if (test.className === "" || test.className === "running") {\n test.className = "aborted";\n assertList = test.getElementsByTagName("ol")[0];\n assertLi = document.createElement("li");\n assertLi.className = "fail";\n assertLi.innerHTML = "Test aborted.";\n assertList.appendChild(assertLi);\n }\n }\n }\n\n if (banner && (!abortButton || abortButton.disabled === false)) {\n banner.className = runEnd.status === "failed" ? "qunit-fail" : "qunit-pass";\n }\n\n if (abortButton) {\n abortButton.parentNode.removeChild(abortButton);\n }\n\n if (tests) {\n id("qunit-testresult-display").innerHTML = html;\n }\n\n if (config.altertitle && document.title) {\n // Show \u2716 for good, \u2714 for bad suite result in title\n // use escape sequences in case file gets loaded with non-utf-8\n // charset\n document.title = [runEnd.status === "failed" ? "\\u2716" : "\\u2714", document.title.replace(/^[\\u2714\\u2716] /i, "")].join(" ");\n } // Scroll back to top to show results\n\n\n if (config.scrolltop && window$1.scrollTo) {\n window$1.scrollTo(0, 0);\n }\n });\n\n function getNameHtml(name, module) {\n var nameHtml = "";\n\n if (module) {\n nameHtml = "" + escapeText(module) + ": ";\n }\n\n nameHtml += "" + escapeText(name) + "";\n return nameHtml;\n }\n\n function getProgressHtml(stats) {\n return [stats.completed, " / ", stats.defined, " tests completed.
      "].join("");\n }\n\n QUnit.testStart(function (details) {\n var running, bad;\n appendTest(details.name, details.testId, details.module);\n running = id("qunit-testresult-display");\n\n if (running) {\n addClass(running, "running");\n bad = QUnit.config.reorder && details.previousFailure;\n running.innerHTML = [getProgressHtml(stats), bad ? "Rerunning previously failed test:
      " : "Running: ", getNameHtml(details.name, details.module), getRerunFailedHtml(stats.failedTests)].join("");\n }\n });\n\n function stripHtml(string) {\n // Strip tags, html entity and whitespaces\n return string.replace(/<\\/?[^>]+(>|$)/g, "").replace(/"/g, "").replace(/\\s+/g, "");\n }\n\n QUnit.log(function (details) {\n var assertList,\n assertLi,\n message,\n expected,\n actual,\n diff,\n showDiff = false,\n testItem = id("qunit-test-output-" + details.testId);\n\n if (!testItem) {\n return;\n }\n\n message = escapeText(details.message) || (details.result ? "okay" : "failed");\n message = "" + message + "";\n message += "@ " + details.runtime + " ms"; // The pushFailure doesn\'t provide details.expected\n // when it calls, it\'s implicit to also not show expected and diff stuff\n // Also, we need to check details.expected existence, as it can exist and be undefined\n\n if (!details.result && hasOwn.call(details, "expected")) {\n if (details.negative) {\n expected = "NOT " + QUnit.dump.parse(details.expected);\n } else {\n expected = QUnit.dump.parse(details.expected);\n }\n\n actual = QUnit.dump.parse(details.actual);\n message += "";\n\n if (actual !== expected) {\n message += "";\n\n if (typeof details.actual === "number" && typeof details.expected === "number") {\n if (!isNaN(details.actual) && !isNaN(details.expected)) {\n showDiff = true;\n diff = details.actual - details.expected;\n diff = (diff > 0 ? "+" : "") + diff;\n }\n } else if (typeof details.actual !== "boolean" && typeof details.expected !== "boolean") {\n diff = QUnit.diff(expected, actual); // don\'t show diff if there is zero overlap\n\n showDiff = stripHtml(diff).length !== stripHtml(expected).length + stripHtml(actual).length;\n }\n\n if (showDiff) {\n message += "";\n }\n } else if (expected.indexOf("[object Array]") !== -1 || expected.indexOf("[object Object]") !== -1) {\n message += "";\n } else {\n message += "";\n }\n\n if (details.source) {\n message += "";\n }\n\n message += "
      Expected:
      " + escapeText(expected) + "
      Result:
      " + escapeText(actual) + "
      Diff:
      " + diff + "
      Message: " + "Diff suppressed as the depth of object is more than current max depth (" + QUnit.config.maxDepth + ").

      Hint: Use QUnit.dump.maxDepth to " + " run with a higher max depth or " + "Rerun without max depth.

      Message: " + "Diff suppressed as the expected and actual results have an equivalent" + " serialization
      Source:
      " + escapeText(details.source) + "
      "; // This occurs when pushFailure is set and we have an extracted stack trace\n } else if (!details.result && details.source) {\n message += "" + "" + "
      Source:
      " + escapeText(details.source) + "
      ";\n }\n\n assertList = testItem.getElementsByTagName("ol")[0];\n assertLi = document.createElement("li");\n assertLi.className = details.result ? "pass" : "fail";\n assertLi.innerHTML = message;\n assertList.appendChild(assertLi);\n });\n QUnit.testDone(function (details) {\n var testTitle,\n time,\n assertList,\n status,\n good,\n bad,\n testCounts,\n skipped,\n sourceName,\n tests = id("qunit-tests"),\n testItem = id("qunit-test-output-" + details.testId);\n\n if (!tests || !testItem) {\n return;\n }\n\n removeClass(testItem, "running");\n\n if (details.failed > 0) {\n status = "failed";\n } else if (details.todo) {\n status = "todo";\n } else {\n status = details.skipped ? "skipped" : "passed";\n }\n\n assertList = testItem.getElementsByTagName("ol")[0];\n good = details.passed;\n bad = details.failed; // This test passed if it has no unexpected failed assertions\n\n var testPassed = details.failed > 0 ? details.todo : !details.todo;\n\n if (testPassed) {\n // Collapse the passing tests\n addClass(assertList, "qunit-collapsed");\n } else {\n stats.failedTests.push(details.testId);\n\n if (config.collapse) {\n if (!collapseNext) {\n // Skip collapsing the first failing test\n collapseNext = true;\n } else {\n // Collapse remaining tests\n addClass(assertList, "qunit-collapsed");\n }\n }\n } // The testItem.firstChild is the test name\n\n\n testTitle = testItem.firstChild;\n testCounts = bad ? "" + bad + ", " + "" + good + ", " : "";\n testTitle.innerHTML += " (" + testCounts + details.assertions.length + ")";\n stats.completed++;\n\n if (details.skipped) {\n testItem.className = "skipped";\n skipped = document.createElement("em");\n skipped.className = "qunit-skipped-label";\n skipped.innerHTML = "skipped";\n testItem.insertBefore(skipped, testTitle);\n } else {\n addEvent(testTitle, "click", function () {\n toggleClass(assertList, "qunit-collapsed");\n });\n testItem.className = testPassed ? "pass" : "fail";\n\n if (details.todo) {\n var todoLabel = document.createElement("em");\n todoLabel.className = "qunit-todo-label";\n todoLabel.innerHTML = "todo";\n testItem.className += " todo";\n testItem.insertBefore(todoLabel, testTitle);\n }\n\n time = document.createElement("span");\n time.className = "runtime";\n time.innerHTML = details.runtime + " ms";\n testItem.insertBefore(time, assertList);\n } // Show the source of the test when showing assertions\n\n\n if (details.source) {\n sourceName = document.createElement("p");\n sourceName.innerHTML = "Source: " + escapeText(details.source);\n addClass(sourceName, "qunit-source");\n\n if (testPassed) {\n addClass(sourceName, "qunit-collapsed");\n }\n\n addEvent(testTitle, "click", function () {\n toggleClass(sourceName, "qunit-collapsed");\n });\n testItem.appendChild(sourceName);\n }\n\n if (config.hidepassed && (status === "passed" || details.skipped)) {\n // use removeChild instead of remove because of support\n hiddenTests.push(testItem);\n tests.removeChild(testItem);\n }\n });\n QUnit.on("error", function (error) {\n var testItem = appendTest("global failure");\n\n if (!testItem) {\n // HTML Reporter is probably disabled or not yet initialized.\n return;\n } // Render similar to a failed assertion (see above QUnit.log callback)\n\n\n var message = escapeText(errorString(error));\n message = "" + message + "";\n\n if (error && error.stack) {\n message += "" + "" + "
      Source:
      " + escapeText(error.stack) + "
      ";\n }\n\n var assertList = testItem.getElementsByTagName("ol")[0];\n var assertLi = document.createElement("li");\n assertLi.className = "fail";\n assertLi.innerHTML = message;\n assertList.appendChild(assertLi); // Make it visible\n\n testItem.className = "fail";\n }); // Avoid readyState issue with phantomjs\n // Ref: #818\n\n var usingPhantom = function (p) {\n return p && p.version && p.version.major > 0;\n }(window$1.phantom);\n\n if (usingPhantom) {\n console$1.warn("Support for PhantomJS is deprecated and will be removed in QUnit 3.0.");\n }\n\n if (!usingPhantom && document.readyState === "complete") {\n QUnit.load();\n } else {\n addEvent(window$1, "load", QUnit.load);\n } // Wrap window.onerror. We will call the original window.onerror to see if\n // the existing handler fully handles the error; if not, we will call the\n // QUnit.onError function.\n\n\n var originalWindowOnError = window$1.onerror; // Cover uncaught exceptions\n // Returning true will suppress the default browser handler,\n // returning false will let it run.\n\n window$1.onerror = function (message, fileName, lineNumber, columnNumber, errorObj) {\n var ret = false;\n\n if (originalWindowOnError) {\n for (var _len = arguments.length, args = new Array(_len > 5 ? _len - 5 : 0), _key = 5; _key < _len; _key++) {\n args[_key - 5] = arguments[_key];\n }\n\n ret = originalWindowOnError.call.apply(originalWindowOnError, [this, message, fileName, lineNumber, columnNumber, errorObj].concat(args));\n } // Treat return value as window.onerror itself does,\n // Only do our handling if not suppressed.\n\n\n if (ret !== true) {\n // If there is a current test that sets the internal `ignoreGlobalErrors` field\n // (such as during `assert.throws()`), then the error is ignored and native\n // error reporting is suppressed as well. This is because in browsers, an error\n // can sometimes end up in `window.onerror` instead of in the local try/catch.\n // This ignoring of errors does not apply to our general onUncaughtException\n // method, nor to our `unhandledRejection` handlers, as those are not meant\n // to receive an "expected" error during `assert.throws()`.\n if (config.current && config.current.ignoreGlobalErrors) {\n return true;\n } // According to\n // https://blog.sentry.io/2016/01/04/client-javascript-reporting-window-onerror,\n // most modern browsers support an errorObj argument; use that to\n // get a full stack trace if it\'s available.\n\n\n var error = errorObj || new Error(message);\n\n if (!error.stack && fileName && lineNumber) {\n error.stack = "".concat(fileName, ":").concat(lineNumber);\n }\n\n QUnit.onUncaughtException(error);\n }\n\n return ret;\n };\n\n window$1.addEventListener("unhandledrejection", function (event) {\n QUnit.onUncaughtException(event.reason);\n });\n })();\n\n /*\n * This file is a modified version of google-diff-match-patch\'s JavaScript implementation\n * (https://code.google.com/p/google-diff-match-patch/source/browse/trunk/javascript/diff_match_patch_uncompressed.js),\n * modifications are licensed as more fully set forth in LICENSE.txt.\n *\n * The original source of google-diff-match-patch is attributable and licensed as follows:\n *\n * Copyright 2006 Google Inc.\n * https://code.google.com/p/google-diff-match-patch/\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * More Info:\n * https://code.google.com/p/google-diff-match-patch/\n *\n * Usage: QUnit.diff(expected, actual)\n *\n */\n\n QUnit.diff = function () {\n function DiffMatchPatch() {} // DIFF FUNCTIONS\n\n /**\n * The data structure representing a diff is an array of tuples:\n * [[DIFF_DELETE, \'Hello\'], [DIFF_INSERT, \'Goodbye\'], [DIFF_EQUAL, \' world.\']]\n * which means: delete \'Hello\', add \'Goodbye\' and keep \' world.\'\n */\n\n\n var DIFF_DELETE = -1,\n DIFF_INSERT = 1,\n DIFF_EQUAL = 0,\n hasOwn = Object.prototype.hasOwnProperty;\n /**\n * Find the differences between two texts. Simplifies the problem by stripping\n * any common prefix or suffix off the texts before diffing.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {boolean=} optChecklines Optional speedup flag. If present and false,\n * then don\'t run a line-level diff first to identify the changed areas.\n * Defaults to true, which does a faster, slightly less optimal diff.\n * @return {!Array.} Array of diff tuples.\n */\n\n DiffMatchPatch.prototype.DiffMain = function (text1, text2, optChecklines) {\n var deadline, checklines, commonlength, commonprefix, commonsuffix, diffs; // The diff must be complete in up to 1 second.\n\n deadline = new Date().getTime() + 1000; // Check for null inputs.\n\n if (text1 === null || text2 === null) {\n throw new Error("Null input. (DiffMain)");\n } // Check for equality (speedup).\n\n\n if (text1 === text2) {\n if (text1) {\n return [[DIFF_EQUAL, text1]];\n }\n\n return [];\n }\n\n if (typeof optChecklines === "undefined") {\n optChecklines = true;\n }\n\n checklines = optChecklines; // Trim off common prefix (speedup).\n\n commonlength = this.diffCommonPrefix(text1, text2);\n commonprefix = text1.substring(0, commonlength);\n text1 = text1.substring(commonlength);\n text2 = text2.substring(commonlength); // Trim off common suffix (speedup).\n\n commonlength = this.diffCommonSuffix(text1, text2);\n commonsuffix = text1.substring(text1.length - commonlength);\n text1 = text1.substring(0, text1.length - commonlength);\n text2 = text2.substring(0, text2.length - commonlength); // Compute the diff on the middle block.\n\n diffs = this.diffCompute(text1, text2, checklines, deadline); // Restore the prefix and suffix.\n\n if (commonprefix) {\n diffs.unshift([DIFF_EQUAL, commonprefix]);\n }\n\n if (commonsuffix) {\n diffs.push([DIFF_EQUAL, commonsuffix]);\n }\n\n this.diffCleanupMerge(diffs);\n return diffs;\n };\n /**\n * Reduce the number of edits by eliminating operationally trivial equalities.\n * @param {!Array.} diffs Array of diff tuples.\n */\n\n\n DiffMatchPatch.prototype.diffCleanupEfficiency = function (diffs) {\n var changes, equalities, equalitiesLength, lastequality, pointer, preIns, preDel, postIns, postDel;\n changes = false;\n equalities = []; // Stack of indices where equalities are found.\n\n equalitiesLength = 0; // Keeping our own length var is faster in JS.\n\n /** @type {?string} */\n\n lastequality = null; // Always equal to diffs[equalities[equalitiesLength - 1]][1]\n\n pointer = 0; // Index of current position.\n // Is there an insertion operation before the last equality.\n\n preIns = false; // Is there a deletion operation before the last equality.\n\n preDel = false; // Is there an insertion operation after the last equality.\n\n postIns = false; // Is there a deletion operation after the last equality.\n\n postDel = false;\n\n while (pointer < diffs.length) {\n // Equality found.\n if (diffs[pointer][0] === DIFF_EQUAL) {\n if (diffs[pointer][1].length < 4 && (postIns || postDel)) {\n // Candidate found.\n equalities[equalitiesLength++] = pointer;\n preIns = postIns;\n preDel = postDel;\n lastequality = diffs[pointer][1];\n } else {\n // Not a candidate, and can never become one.\n equalitiesLength = 0;\n lastequality = null;\n }\n\n postIns = postDel = false; // An insertion or deletion.\n } else {\n if (diffs[pointer][0] === DIFF_DELETE) {\n postDel = true;\n } else {\n postIns = true;\n }\n /*\n * Five types to be split:\n * ABXYCD\n * AXCD\n * ABXC\n * AXCD\n * ABXC\n */\n\n\n if (lastequality && (preIns && preDel && postIns && postDel || lastequality.length < 2 && preIns + preDel + postIns + postDel === 3)) {\n // Duplicate record.\n diffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastequality]); // Change second copy to insert.\n\n diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;\n equalitiesLength--; // Throw away the equality we just deleted;\n\n lastequality = null;\n\n if (preIns && preDel) {\n // No changes made which could affect previous entry, keep going.\n postIns = postDel = true;\n equalitiesLength = 0;\n } else {\n equalitiesLength--; // Throw away the previous equality.\n\n pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;\n postIns = postDel = false;\n }\n\n changes = true;\n }\n }\n\n pointer++;\n }\n\n if (changes) {\n this.diffCleanupMerge(diffs);\n }\n };\n /**\n * Convert a diff array into a pretty HTML report.\n * @param {!Array.} diffs Array of diff tuples.\n * @param {integer} string to be beautified.\n * @return {string} HTML representation.\n */\n\n\n DiffMatchPatch.prototype.diffPrettyHtml = function (diffs) {\n var op,\n data,\n x,\n html = [];\n\n for (x = 0; x < diffs.length; x++) {\n op = diffs[x][0]; // Operation (insert, delete, equal)\n\n data = diffs[x][1]; // Text of change.\n\n switch (op) {\n case DIFF_INSERT:\n html[x] = "" + escapeText(data) + "";\n break;\n\n case DIFF_DELETE:\n html[x] = "" + escapeText(data) + "";\n break;\n\n case DIFF_EQUAL:\n html[x] = "" + escapeText(data) + "";\n break;\n }\n }\n\n return html.join("");\n };\n /**\n * Determine the common prefix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the start of each\n * string.\n */\n\n\n DiffMatchPatch.prototype.diffCommonPrefix = function (text1, text2) {\n var pointermid, pointermax, pointermin, pointerstart; // Quick check for common null cases.\n\n if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) {\n return 0;\n } // Binary search.\n // Performance analysis: https://neil.fraser.name/news/2007/10/09/\n\n\n pointermin = 0;\n pointermax = Math.min(text1.length, text2.length);\n pointermid = pointermax;\n pointerstart = 0;\n\n while (pointermin < pointermid) {\n if (text1.substring(pointerstart, pointermid) === text2.substring(pointerstart, pointermid)) {\n pointermin = pointermid;\n pointerstart = pointermin;\n } else {\n pointermax = pointermid;\n }\n\n pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n }\n\n return pointermid;\n };\n /**\n * Determine the common suffix of two strings.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of each string.\n */\n\n\n DiffMatchPatch.prototype.diffCommonSuffix = function (text1, text2) {\n var pointermid, pointermax, pointermin, pointerend; // Quick check for common null cases.\n\n if (!text1 || !text2 || text1.charAt(text1.length - 1) !== text2.charAt(text2.length - 1)) {\n return 0;\n } // Binary search.\n // Performance analysis: https://neil.fraser.name/news/2007/10/09/\n\n\n pointermin = 0;\n pointermax = Math.min(text1.length, text2.length);\n pointermid = pointermax;\n pointerend = 0;\n\n while (pointermin < pointermid) {\n if (text1.substring(text1.length - pointermid, text1.length - pointerend) === text2.substring(text2.length - pointermid, text2.length - pointerend)) {\n pointermin = pointermid;\n pointerend = pointermin;\n } else {\n pointermax = pointermid;\n }\n\n pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);\n }\n\n return pointermid;\n };\n /**\n * Find the differences between two texts. Assumes that the texts do not\n * have any common prefix or suffix.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {boolean} checklines Speedup flag. If false, then don\'t run a\n * line-level diff first to identify the changed areas.\n * If true, then run a faster, slightly less optimal diff.\n * @param {number} deadline Time when the diff should be complete by.\n * @return {!Array.} Array of diff tuples.\n * @private\n */\n\n\n DiffMatchPatch.prototype.diffCompute = function (text1, text2, checklines, deadline) {\n var diffs, longtext, shorttext, i, hm, text1A, text2A, text1B, text2B, midCommon, diffsA, diffsB;\n\n if (!text1) {\n // Just add some text (speedup).\n return [[DIFF_INSERT, text2]];\n }\n\n if (!text2) {\n // Just delete some text (speedup).\n return [[DIFF_DELETE, text1]];\n }\n\n longtext = text1.length > text2.length ? text1 : text2;\n shorttext = text1.length > text2.length ? text2 : text1;\n i = longtext.indexOf(shorttext);\n\n if (i !== -1) {\n // Shorter text is inside the longer text (speedup).\n diffs = [[DIFF_INSERT, longtext.substring(0, i)], [DIFF_EQUAL, shorttext], [DIFF_INSERT, longtext.substring(i + shorttext.length)]]; // Swap insertions for deletions if diff is reversed.\n\n if (text1.length > text2.length) {\n diffs[0][0] = diffs[2][0] = DIFF_DELETE;\n }\n\n return diffs;\n }\n\n if (shorttext.length === 1) {\n // Single character string.\n // After the previous speedup, the character can\'t be an equality.\n return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\n } // Check to see if the problem can be split in two.\n\n\n hm = this.diffHalfMatch(text1, text2);\n\n if (hm) {\n // A half-match was found, sort out the return data.\n text1A = hm[0];\n text1B = hm[1];\n text2A = hm[2];\n text2B = hm[3];\n midCommon = hm[4]; // Send both pairs off for separate processing.\n\n diffsA = this.DiffMain(text1A, text2A, checklines, deadline);\n diffsB = this.DiffMain(text1B, text2B, checklines, deadline); // Merge the results.\n\n return diffsA.concat([[DIFF_EQUAL, midCommon]], diffsB);\n }\n\n if (checklines && text1.length > 100 && text2.length > 100) {\n return this.diffLineMode(text1, text2, deadline);\n }\n\n return this.diffBisect(text1, text2, deadline);\n };\n /**\n * Do the two texts share a substring which is at least half the length of the\n * longer text?\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {Array.} Five element Array, containing the prefix of\n * text1, the suffix of text1, the prefix of text2, the suffix of\n * text2 and the common middle. Or null if there was no match.\n * @private\n */\n\n\n DiffMatchPatch.prototype.diffHalfMatch = function (text1, text2) {\n var longtext, shorttext, dmp, text1A, text2B, text2A, text1B, midCommon, hm1, hm2, hm;\n longtext = text1.length > text2.length ? text1 : text2;\n shorttext = text1.length > text2.length ? text2 : text1;\n\n if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {\n return null; // Pointless.\n }\n\n dmp = this; // \'this\' becomes \'window\' in a closure.\n\n /**\n * Does a substring of shorttext exist within longtext such that the substring\n * is at least half the length of longtext?\n * Closure, but does not reference any external variables.\n * @param {string} longtext Longer string.\n * @param {string} shorttext Shorter string.\n * @param {number} i Start index of quarter length substring within longtext.\n * @return {Array.} Five element Array, containing the prefix of\n * longtext, the suffix of longtext, the prefix of shorttext, the suffix\n * of shorttext and the common middle. Or null if there was no match.\n * @private\n */\n\n function diffHalfMatchI(longtext, shorttext, i) {\n var seed, j, bestCommon, prefixLength, suffixLength, bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB; // Start with a 1/4 length substring at position i as a seed.\n\n seed = longtext.substring(i, i + Math.floor(longtext.length / 4));\n j = -1;\n bestCommon = "";\n\n while ((j = shorttext.indexOf(seed, j + 1)) !== -1) {\n prefixLength = dmp.diffCommonPrefix(longtext.substring(i), shorttext.substring(j));\n suffixLength = dmp.diffCommonSuffix(longtext.substring(0, i), shorttext.substring(0, j));\n\n if (bestCommon.length < suffixLength + prefixLength) {\n bestCommon = shorttext.substring(j - suffixLength, j) + shorttext.substring(j, j + prefixLength);\n bestLongtextA = longtext.substring(0, i - suffixLength);\n bestLongtextB = longtext.substring(i + prefixLength);\n bestShorttextA = shorttext.substring(0, j - suffixLength);\n bestShorttextB = shorttext.substring(j + prefixLength);\n }\n }\n\n if (bestCommon.length * 2 >= longtext.length) {\n return [bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB, bestCommon];\n } else {\n return null;\n }\n } // First check if the second quarter is the seed for a half-match.\n\n\n hm1 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 4)); // Check again based on the third quarter.\n\n hm2 = diffHalfMatchI(longtext, shorttext, Math.ceil(longtext.length / 2));\n\n if (!hm1 && !hm2) {\n return null;\n } else if (!hm2) {\n hm = hm1;\n } else if (!hm1) {\n hm = hm2;\n } else {\n // Both matched. Select the longest.\n hm = hm1[4].length > hm2[4].length ? hm1 : hm2;\n } // A half-match was found, sort out the return data.\n\n\n if (text1.length > text2.length) {\n text1A = hm[0];\n text1B = hm[1];\n text2A = hm[2];\n text2B = hm[3];\n } else {\n text2A = hm[0];\n text2B = hm[1];\n text1A = hm[2];\n text1B = hm[3];\n }\n\n midCommon = hm[4];\n return [text1A, text1B, text2A, text2B, midCommon];\n };\n /**\n * Do a quick line-level diff on both strings, then rediff the parts for\n * greater accuracy.\n * This speedup can produce non-minimal diffs.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} deadline Time when the diff should be complete by.\n * @return {!Array.} Array of diff tuples.\n * @private\n */\n\n\n DiffMatchPatch.prototype.diffLineMode = function (text1, text2, deadline) {\n var a, diffs, linearray, pointer, countInsert, countDelete, textInsert, textDelete, j; // Scan the text on a line-by-line basis first.\n\n a = this.diffLinesToChars(text1, text2);\n text1 = a.chars1;\n text2 = a.chars2;\n linearray = a.lineArray;\n diffs = this.DiffMain(text1, text2, false, deadline); // Convert the diff back to original text.\n\n this.diffCharsToLines(diffs, linearray); // Eliminate freak matches (e.g. blank lines)\n\n this.diffCleanupSemantic(diffs); // Rediff any replacement blocks, this time character-by-character.\n // Add a dummy entry at the end.\n\n diffs.push([DIFF_EQUAL, ""]);\n pointer = 0;\n countDelete = 0;\n countInsert = 0;\n textDelete = "";\n textInsert = "";\n\n while (pointer < diffs.length) {\n switch (diffs[pointer][0]) {\n case DIFF_INSERT:\n countInsert++;\n textInsert += diffs[pointer][1];\n break;\n\n case DIFF_DELETE:\n countDelete++;\n textDelete += diffs[pointer][1];\n break;\n\n case DIFF_EQUAL:\n // Upon reaching an equality, check for prior redundancies.\n if (countDelete >= 1 && countInsert >= 1) {\n // Delete the offending records and add the merged ones.\n diffs.splice(pointer - countDelete - countInsert, countDelete + countInsert);\n pointer = pointer - countDelete - countInsert;\n a = this.DiffMain(textDelete, textInsert, false, deadline);\n\n for (j = a.length - 1; j >= 0; j--) {\n diffs.splice(pointer, 0, a[j]);\n }\n\n pointer = pointer + a.length;\n }\n\n countInsert = 0;\n countDelete = 0;\n textDelete = "";\n textInsert = "";\n break;\n }\n\n pointer++;\n }\n\n diffs.pop(); // Remove the dummy entry at the end.\n\n return diffs;\n };\n /**\n * Find the \'middle snake\' of a diff, split the problem in two\n * and return the recursively constructed diff.\n * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} deadline Time at which to bail if not yet complete.\n * @return {!Array.} Array of diff tuples.\n * @private\n */\n\n\n DiffMatchPatch.prototype.diffBisect = function (text1, text2, deadline) {\n var text1Length, text2Length, maxD, vOffset, vLength, v1, v2, x, delta, front, k1start, k1end, k2start, k2end, k2Offset, k1Offset, x1, x2, y1, y2, d, k1, k2; // Cache the text lengths to prevent multiple calls.\n\n text1Length = text1.length;\n text2Length = text2.length;\n maxD = Math.ceil((text1Length + text2Length) / 2);\n vOffset = maxD;\n vLength = 2 * maxD;\n v1 = new Array(vLength);\n v2 = new Array(vLength); // Setting all elements to -1 is faster in Chrome & Firefox than mixing\n // integers and undefined.\n\n for (x = 0; x < vLength; x++) {\n v1[x] = -1;\n v2[x] = -1;\n }\n\n v1[vOffset + 1] = 0;\n v2[vOffset + 1] = 0;\n delta = text1Length - text2Length; // If the total number of characters is odd, then the front path will collide\n // with the reverse path.\n\n front = delta % 2 !== 0; // Offsets for start and end of k loop.\n // Prevents mapping of space beyond the grid.\n\n k1start = 0;\n k1end = 0;\n k2start = 0;\n k2end = 0;\n\n for (d = 0; d < maxD; d++) {\n // Bail out if deadline is reached.\n if (new Date().getTime() > deadline) {\n break;\n } // Walk the front path one step.\n\n\n for (k1 = -d + k1start; k1 <= d - k1end; k1 += 2) {\n k1Offset = vOffset + k1;\n\n if (k1 === -d || k1 !== d && v1[k1Offset - 1] < v1[k1Offset + 1]) {\n x1 = v1[k1Offset + 1];\n } else {\n x1 = v1[k1Offset - 1] + 1;\n }\n\n y1 = x1 - k1;\n\n while (x1 < text1Length && y1 < text2Length && text1.charAt(x1) === text2.charAt(y1)) {\n x1++;\n y1++;\n }\n\n v1[k1Offset] = x1;\n\n if (x1 > text1Length) {\n // Ran off the right of the graph.\n k1end += 2;\n } else if (y1 > text2Length) {\n // Ran off the bottom of the graph.\n k1start += 2;\n } else if (front) {\n k2Offset = vOffset + delta - k1;\n\n if (k2Offset >= 0 && k2Offset < vLength && v2[k2Offset] !== -1) {\n // Mirror x2 onto top-left coordinate system.\n x2 = text1Length - v2[k2Offset];\n\n if (x1 >= x2) {\n // Overlap detected.\n return this.diffBisectSplit(text1, text2, x1, y1, deadline);\n }\n }\n }\n } // Walk the reverse path one step.\n\n\n for (k2 = -d + k2start; k2 <= d - k2end; k2 += 2) {\n k2Offset = vOffset + k2;\n\n if (k2 === -d || k2 !== d && v2[k2Offset - 1] < v2[k2Offset + 1]) {\n x2 = v2[k2Offset + 1];\n } else {\n x2 = v2[k2Offset - 1] + 1;\n }\n\n y2 = x2 - k2;\n\n while (x2 < text1Length && y2 < text2Length && text1.charAt(text1Length - x2 - 1) === text2.charAt(text2Length - y2 - 1)) {\n x2++;\n y2++;\n }\n\n v2[k2Offset] = x2;\n\n if (x2 > text1Length) {\n // Ran off the left of the graph.\n k2end += 2;\n } else if (y2 > text2Length) {\n // Ran off the top of the graph.\n k2start += 2;\n } else if (!front) {\n k1Offset = vOffset + delta - k2;\n\n if (k1Offset >= 0 && k1Offset < vLength && v1[k1Offset] !== -1) {\n x1 = v1[k1Offset];\n y1 = vOffset + x1 - k1Offset; // Mirror x2 onto top-left coordinate system.\n\n x2 = text1Length - x2;\n\n if (x1 >= x2) {\n // Overlap detected.\n return this.diffBisectSplit(text1, text2, x1, y1, deadline);\n }\n }\n }\n }\n } // Diff took too long and hit the deadline or\n // number of diffs equals number of characters, no commonality at all.\n\n\n return [[DIFF_DELETE, text1], [DIFF_INSERT, text2]];\n };\n /**\n * Given the location of the \'middle snake\', split the diff in two parts\n * and recurse.\n * @param {string} text1 Old string to be diffed.\n * @param {string} text2 New string to be diffed.\n * @param {number} x Index of split point in text1.\n * @param {number} y Index of split point in text2.\n * @param {number} deadline Time at which to bail if not yet complete.\n * @return {!Array.} Array of diff tuples.\n * @private\n */\n\n\n DiffMatchPatch.prototype.diffBisectSplit = function (text1, text2, x, y, deadline) {\n var text1a, text1b, text2a, text2b, diffs, diffsb;\n text1a = text1.substring(0, x);\n text2a = text2.substring(0, y);\n text1b = text1.substring(x);\n text2b = text2.substring(y); // Compute both diffs serially.\n\n diffs = this.DiffMain(text1a, text2a, false, deadline);\n diffsb = this.DiffMain(text1b, text2b, false, deadline);\n return diffs.concat(diffsb);\n };\n /**\n * Reduce the number of edits by eliminating semantically trivial equalities.\n * @param {!Array.} diffs Array of diff tuples.\n */\n\n\n DiffMatchPatch.prototype.diffCleanupSemantic = function (diffs) {\n var changes, equalities, equalitiesLength, lastequality, pointer, lengthInsertions2, lengthDeletions2, lengthInsertions1, lengthDeletions1, deletion, insertion, overlapLength1, overlapLength2;\n changes = false;\n equalities = []; // Stack of indices where equalities are found.\n\n equalitiesLength = 0; // Keeping our own length var is faster in JS.\n\n /** @type {?string} */\n\n lastequality = null; // Always equal to diffs[equalities[equalitiesLength - 1]][1]\n\n pointer = 0; // Index of current position.\n // Number of characters that changed prior to the equality.\n\n lengthInsertions1 = 0;\n lengthDeletions1 = 0; // Number of characters that changed after the equality.\n\n lengthInsertions2 = 0;\n lengthDeletions2 = 0;\n\n while (pointer < diffs.length) {\n if (diffs[pointer][0] === DIFF_EQUAL) {\n // Equality found.\n equalities[equalitiesLength++] = pointer;\n lengthInsertions1 = lengthInsertions2;\n lengthDeletions1 = lengthDeletions2;\n lengthInsertions2 = 0;\n lengthDeletions2 = 0;\n lastequality = diffs[pointer][1];\n } else {\n // An insertion or deletion.\n if (diffs[pointer][0] === DIFF_INSERT) {\n lengthInsertions2 += diffs[pointer][1].length;\n } else {\n lengthDeletions2 += diffs[pointer][1].length;\n } // Eliminate an equality that is smaller or equal to the edits on both\n // sides of it.\n\n\n if (lastequality && lastequality.length <= Math.max(lengthInsertions1, lengthDeletions1) && lastequality.length <= Math.max(lengthInsertions2, lengthDeletions2)) {\n // Duplicate record.\n diffs.splice(equalities[equalitiesLength - 1], 0, [DIFF_DELETE, lastequality]); // Change second copy to insert.\n\n diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT; // Throw away the equality we just deleted.\n\n equalitiesLength--; // Throw away the previous equality (it needs to be reevaluated).\n\n equalitiesLength--;\n pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1; // Reset the counters.\n\n lengthInsertions1 = 0;\n lengthDeletions1 = 0;\n lengthInsertions2 = 0;\n lengthDeletions2 = 0;\n lastequality = null;\n changes = true;\n }\n }\n\n pointer++;\n } // Normalize the diff.\n\n\n if (changes) {\n this.diffCleanupMerge(diffs);\n } // Find any overlaps between deletions and insertions.\n // e.g: abcxxxxxxdef\n // -> abcxxxdef\n // e.g: xxxabcdefxxx\n // -> defxxxabc\n // Only extract an overlap if it is as big as the edit ahead or behind it.\n\n\n pointer = 1;\n\n while (pointer < diffs.length) {\n if (diffs[pointer - 1][0] === DIFF_DELETE && diffs[pointer][0] === DIFF_INSERT) {\n deletion = diffs[pointer - 1][1];\n insertion = diffs[pointer][1];\n overlapLength1 = this.diffCommonOverlap(deletion, insertion);\n overlapLength2 = this.diffCommonOverlap(insertion, deletion);\n\n if (overlapLength1 >= overlapLength2) {\n if (overlapLength1 >= deletion.length / 2 || overlapLength1 >= insertion.length / 2) {\n // Overlap found. Insert an equality and trim the surrounding edits.\n diffs.splice(pointer, 0, [DIFF_EQUAL, insertion.substring(0, overlapLength1)]);\n diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlapLength1);\n diffs[pointer + 1][1] = insertion.substring(overlapLength1);\n pointer++;\n }\n } else {\n if (overlapLength2 >= deletion.length / 2 || overlapLength2 >= insertion.length / 2) {\n // Reverse overlap found.\n // Insert an equality and swap and trim the surrounding edits.\n diffs.splice(pointer, 0, [DIFF_EQUAL, deletion.substring(0, overlapLength2)]);\n diffs[pointer - 1][0] = DIFF_INSERT;\n diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlapLength2);\n diffs[pointer + 1][0] = DIFF_DELETE;\n diffs[pointer + 1][1] = deletion.substring(overlapLength2);\n pointer++;\n }\n }\n\n pointer++;\n }\n\n pointer++;\n }\n };\n /**\n * Determine if the suffix of one string is the prefix of another.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {number} The number of characters common to the end of the first\n * string and the start of the second string.\n * @private\n */\n\n\n DiffMatchPatch.prototype.diffCommonOverlap = function (text1, text2) {\n var text1Length, text2Length, textLength, best, length, pattern, found; // Cache the text lengths to prevent multiple calls.\n\n text1Length = text1.length;\n text2Length = text2.length; // Eliminate the null case.\n\n if (text1Length === 0 || text2Length === 0) {\n return 0;\n } // Truncate the longer string.\n\n\n if (text1Length > text2Length) {\n text1 = text1.substring(text1Length - text2Length);\n } else if (text1Length < text2Length) {\n text2 = text2.substring(0, text1Length);\n }\n\n textLength = Math.min(text1Length, text2Length); // Quick check for the worst case.\n\n if (text1 === text2) {\n return textLength;\n } // Start by looking for a single character match\n // and increase length until no match is found.\n // Performance analysis: https://neil.fraser.name/news/2010/11/04/\n\n\n best = 0;\n length = 1;\n\n while (true) {\n pattern = text1.substring(textLength - length);\n found = text2.indexOf(pattern);\n\n if (found === -1) {\n return best;\n }\n\n length += found;\n\n if (found === 0 || text1.substring(textLength - length) === text2.substring(0, length)) {\n best = length;\n length++;\n }\n }\n };\n /**\n * Split two texts into an array of strings. Reduce the texts to a string of\n * hashes where each Unicode character represents one line.\n * @param {string} text1 First string.\n * @param {string} text2 Second string.\n * @return {{chars1: string, chars2: string, lineArray: !Array.}}\n * An object containing the encoded text1, the encoded text2 and\n * the array of unique strings.\n * The zeroth element of the array of unique strings is intentionally blank.\n * @private\n */\n\n\n DiffMatchPatch.prototype.diffLinesToChars = function (text1, text2) {\n var lineArray, lineHash, chars1, chars2;\n lineArray = []; // E.g. lineArray[4] === \'Hello\\n\'\n\n lineHash = {}; // E.g. lineHash[\'Hello\\n\'] === 4\n // \'\\x00\' is a valid character, but various debuggers don\'t like it.\n // So we\'ll insert a junk entry to avoid generating a null character.\n\n lineArray[0] = "";\n /**\n * Split a text into an array of strings. Reduce the texts to a string of\n * hashes where each Unicode character represents one line.\n * Modifies linearray and linehash through being a closure.\n * @param {string} text String to encode.\n * @return {string} Encoded string.\n * @private\n */\n\n function diffLinesToCharsMunge(text) {\n var chars, lineStart, lineEnd, lineArrayLength, line;\n chars = ""; // Walk the text, pulling out a substring for each line.\n // text.split(\'\\n\') would would temporarily double our memory footprint.\n // Modifying text would create many large strings to garbage collect.\n\n lineStart = 0;\n lineEnd = -1; // Keeping our own length variable is faster than looking it up.\n\n lineArrayLength = lineArray.length;\n\n while (lineEnd < text.length - 1) {\n lineEnd = text.indexOf("\\n", lineStart);\n\n if (lineEnd === -1) {\n lineEnd = text.length - 1;\n }\n\n line = text.substring(lineStart, lineEnd + 1);\n lineStart = lineEnd + 1;\n\n if (hasOwn.call(lineHash, line)) {\n chars += String.fromCharCode(lineHash[line]);\n } else {\n chars += String.fromCharCode(lineArrayLength);\n lineHash[line] = lineArrayLength;\n lineArray[lineArrayLength++] = line;\n }\n }\n\n return chars;\n }\n\n chars1 = diffLinesToCharsMunge(text1);\n chars2 = diffLinesToCharsMunge(text2);\n return {\n chars1: chars1,\n chars2: chars2,\n lineArray: lineArray\n };\n };\n /**\n * Rehydrate the text in a diff from a string of line hashes to real lines of\n * text.\n * @param {!Array.} diffs Array of diff tuples.\n * @param {!Array.} lineArray Array of unique strings.\n * @private\n */\n\n\n DiffMatchPatch.prototype.diffCharsToLines = function (diffs, lineArray) {\n var x, chars, text, y;\n\n for (x = 0; x < diffs.length; x++) {\n chars = diffs[x][1];\n text = [];\n\n for (y = 0; y < chars.length; y++) {\n text[y] = lineArray[chars.charCodeAt(y)];\n }\n\n diffs[x][1] = text.join("");\n }\n };\n /**\n * Reorder and merge like edit sections. Merge equalities.\n * Any edit section can move as long as it doesn\'t cross an equality.\n * @param {!Array.} diffs Array of diff tuples.\n */\n\n\n DiffMatchPatch.prototype.diffCleanupMerge = function (diffs) {\n var pointer, countDelete, countInsert, textInsert, textDelete, commonlength, changes, diffPointer, position;\n diffs.push([DIFF_EQUAL, ""]); // Add a dummy entry at the end.\n\n pointer = 0;\n countDelete = 0;\n countInsert = 0;\n textDelete = "";\n textInsert = "";\n\n while (pointer < diffs.length) {\n switch (diffs[pointer][0]) {\n case DIFF_INSERT:\n countInsert++;\n textInsert += diffs[pointer][1];\n pointer++;\n break;\n\n case DIFF_DELETE:\n countDelete++;\n textDelete += diffs[pointer][1];\n pointer++;\n break;\n\n case DIFF_EQUAL:\n // Upon reaching an equality, check for prior redundancies.\n if (countDelete + countInsert > 1) {\n if (countDelete !== 0 && countInsert !== 0) {\n // Factor out any common prefixes.\n commonlength = this.diffCommonPrefix(textInsert, textDelete);\n\n if (commonlength !== 0) {\n if (pointer - countDelete - countInsert > 0 && diffs[pointer - countDelete - countInsert - 1][0] === DIFF_EQUAL) {\n diffs[pointer - countDelete - countInsert - 1][1] += textInsert.substring(0, commonlength);\n } else {\n diffs.splice(0, 0, [DIFF_EQUAL, textInsert.substring(0, commonlength)]);\n pointer++;\n }\n\n textInsert = textInsert.substring(commonlength);\n textDelete = textDelete.substring(commonlength);\n } // Factor out any common suffixies.\n\n\n commonlength = this.diffCommonSuffix(textInsert, textDelete);\n\n if (commonlength !== 0) {\n diffs[pointer][1] = textInsert.substring(textInsert.length - commonlength) + diffs[pointer][1];\n textInsert = textInsert.substring(0, textInsert.length - commonlength);\n textDelete = textDelete.substring(0, textDelete.length - commonlength);\n }\n } // Delete the offending records and add the merged ones.\n\n\n if (countDelete === 0) {\n diffs.splice(pointer - countInsert, countDelete + countInsert, [DIFF_INSERT, textInsert]);\n } else if (countInsert === 0) {\n diffs.splice(pointer - countDelete, countDelete + countInsert, [DIFF_DELETE, textDelete]);\n } else {\n diffs.splice(pointer - countDelete - countInsert, countDelete + countInsert, [DIFF_DELETE, textDelete], [DIFF_INSERT, textInsert]);\n }\n\n pointer = pointer - countDelete - countInsert + (countDelete ? 1 : 0) + (countInsert ? 1 : 0) + 1;\n } else if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) {\n // Merge this equality with the previous one.\n diffs[pointer - 1][1] += diffs[pointer][1];\n diffs.splice(pointer, 1);\n } else {\n pointer++;\n }\n\n countInsert = 0;\n countDelete = 0;\n textDelete = "";\n textInsert = "";\n break;\n }\n }\n\n if (diffs[diffs.length - 1][1] === "") {\n diffs.pop(); // Remove the dummy entry at the end.\n } // Second pass: look for single edits surrounded on both sides by equalities\n // which can be shifted sideways to eliminate an equality.\n // e.g: ABAC -> ABAC\n\n\n changes = false;\n pointer = 1; // Intentionally ignore the first and last element (don\'t need checking).\n\n while (pointer < diffs.length - 1) {\n if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) {\n diffPointer = diffs[pointer][1];\n position = diffPointer.substring(diffPointer.length - diffs[pointer - 1][1].length); // This is a single edit surrounded by equalities.\n\n if (position === diffs[pointer - 1][1]) {\n // Shift the edit over the previous equality.\n diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length);\n diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];\n diffs.splice(pointer - 1, 1);\n changes = true;\n } else if (diffPointer.substring(0, diffs[pointer + 1][1].length) === diffs[pointer + 1][1]) {\n // Shift the edit over the next equality.\n diffs[pointer - 1][1] += diffs[pointer + 1][1];\n diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1];\n diffs.splice(pointer + 1, 1);\n changes = true;\n }\n }\n\n pointer++;\n } // If shifts were made, the diff needs reordering and another shift sweep.\n\n\n if (changes) {\n this.diffCleanupMerge(diffs);\n }\n };\n\n return function (o, n) {\n var diff, output, text;\n diff = new DiffMatchPatch();\n output = diff.DiffMain(o, n);\n diff.diffCleanupEfficiency(output);\n text = diff.diffPrettyHtml(output);\n return text;\n };\n }();\n\n}());\n'; + loader.global.define = undefined; + loader.global.module = undefined; + loader.global.exports = undefined; + loader.__exec({ + 'source': source, + 'address': module.uri + }); + loader.global.require = require; + loader.global.define = define; + return loader.get('@@global-helpers').retrieveGlobal(module.id, 'QUnit'); +}); +/*steal-css@1.3.2#css*/ +define('steal-css@1.3.2#css', [ + 'require', + 'exports', + 'module', + '@loader', + '@steal' +], function (require, exports, module) { + (function (global, require, exports, module) { + var loader = require('@loader'); + var steal = require('@steal'); + var isNode = typeof process === 'object' && {}.toString.call(process) === '[object process]'; + var importRegEx = /@import [^uU]['"]?([^'"\)]*)['"]?/g; + var resourceRegEx = /url\(['"]?([^'"\)]*)['"]?\)/g; + var waitSeconds = loader.cssOptions && loader.cssOptions.timeout ? parseInt(loader.cssOptions.timeout, 10) : 60; + var onloadCss = function (link, cb) { + var styleSheets = getDocument().styleSheets, i = styleSheets.length; + while (i--) { + if (styleSheets[i].href === link.href) { + return cb(); + } + } + setTimeout(function () { + onloadCss(link, cb); + }); + }; + function isIE9() { + var doc = getDocument(); + return doc && !!Function('/*@cc_on return (/^9/.test(@_jscript_version) && /MSIE 9.0(?!.*IEMobile)/i.test(navigator.userAgent)); @*/')(); + } + function getDocument() { + if (typeof doneSsr !== 'undefined' && doneSsr.globalDocument) { + return doneSsr.globalDocument; + } + if (typeof document !== 'undefined') { + return document; + } + throw new Error('Unable to load CSS in an environment without a document.'); + } + function getHead() { + var doc = getDocument(); + var head = doc.head || doc.getElementsByTagName('head')[0]; + if (!head) { + var docEl = doc.documentElement || doc; + head = doc.createElement('head'); + docEl.insertBefore(head, docEl.firstChild); + } + return head; + } + function CSSModule(load, loader) { + if (typeof load === 'object') { + this.load = load; + this.loader = loader; + this.address = this.load.address; + this.source = this.load.source; + } else { + this.address = load; + this.source = loader; + } + } + CSSModule.cssCount = 0; + CSSModule.ie9MaxStyleSheets = 31; + CSSModule.currentStyleSheet = null; + CSSModule.prototype = { + injectLink: function () { + if (this._loaded) { + return this._loaded; + } + if (this.linkExists()) { + this._loaded = Promise.resolve(''); + return this._loaded; + } + var doc = getDocument(); + var link = this.link = doc.createElement('link'); + link.type = 'text/css'; + link.rel = 'stylesheet'; + link.href = this.address; + this._loaded = new Promise(function (resolve, reject) { + var timeout = setTimeout(function () { + reject('Unable to load CSS'); + }, waitSeconds * 1000); + var loadCB = function (event) { + clearTimeout(timeout); + link.removeEventListener('load', loadCB); + link.removeEventListener('error', loadCB); + if (event && event.type === 'error') { + reject('Unable to load CSS'); + } else { + resolve(''); + } + }; + if ('isApplicationInstalled' in navigator || !link.addEventListener) { + onloadCss(link, loadCB); + } else if (navigator.noUI) { + loadCB(); + } else { + link.addEventListener('load', loadCB); + link.addEventListener('error', loadCB); + } + getHead().appendChild(link); + }); + return this._loaded; + }, + injectStyle: function () { + var doc = getDocument(); + var head = getHead(); + var style = this.style = doc.createElement('style'); + style.type = 'text/css'; + if (style.sheet) { + style.sheet.cssText = this.source; + } else if (style.styleSheet) { + style.styleSheet.cssText = this.source; + } else { + style.appendChild(doc.createTextNode(this.source)); + } + head.appendChild(style); + }, + ie9StyleSheetLimitHack: function () { + var doc = getDocument(); + if (!CSSModule.cssCount) { + CSSModule.currentStyleSheet = doc.createStyleSheet(); + } + CSSModule.cssCount += 1; + CSSModule.currentStyleSheet.cssText += this.source; + if (CSSModule.cssCount === CSSModule.ie9MaxStyleSheets) { + CSSModule.cssCount = 0; + } + }, + updateURLs: function () { + var rawSource = this.source, address = this.address; + this.source = rawSource.replace(importRegEx, function (whole, part) { + if (isNode) { + return '@import url(' + part + ')'; + } else { + return '@import url(' + steal.joinURIs(address, part) + ')'; + } + }); + if (!loader.isEnv('build')) { + this.source = this.source + '/*# sourceURL=' + address + ' */'; + this.source = this.source.replace(resourceRegEx, function (whole, part) { + return 'url(' + steal.joinURIs(address, part) + ')'; + }); + } + return this.source; + }, + getExistingNode: function () { + var doc = getDocument(); + var selector = '[href=\'' + this.address + '\']'; + return doc.querySelector && doc.querySelector(selector); + }, + linkExists: function () { + var styleSheets = getDocument().styleSheets; + for (var i = 0; i < styleSheets.length; ++i) { + if (this.address === styleSheets[i].href) { + return true; + } + } + return false; + }, + setupLiveReload: function (loader, name) { + var head = getHead(); + var css = this; + if (loader.liveReloadInstalled) { + var cssReload = loader['import']('live-reload', { name: module.id }); + Promise.resolve(cssReload).then(function (reload) { + loader['import'](name).then(function () { + reload.once('!dispose/' + name, function () { + css.style.__isDirty = true; + reload.once('!cycleComplete', function () { + head.removeChild(css.style); + }); + }); + }); + }); + } + } + }; + if (loader.isEnv('production')) { + exports.fetch = function (load) { + var css = new CSSModule(load.address); + return css.injectLink(); + }; + } else { + exports.instantiate = function (load) { + var loader = this; + var css = new CSSModule(load.address, load.source); + load.source = css.updateURLs(); + load.metadata.deps = []; + load.metadata.format = 'css'; + load.metadata.execute = function () { + if (getDocument()) { + if (isIE9()) { + css.ie9StyleSheetLimitHack(); + } else { + css.injectStyle(); + } + css.setupLiveReload(loader, load.name); + } + return loader.newModule({ source: css.source }); + }; + }; + } + exports.CSSModule = CSSModule; + exports.getDocument = getDocument; + exports.getHead = getHead; + exports.locateScheme = true; + exports.buildType = 'css'; + exports.includeInBuild = true; + exports.pluginBuilder = 'steal-css/slim'; + }(function () { + return this; + }(), require, exports, module)); +}); +/*steal-qunit@2.0.0#steal-qunit*/ +'format amd'; +define('steal-qunit@2.0.0#steal-qunit', [ + '@loader', + 'qunit/qunit/qunit', + 'qunit/qunit/qunit.css' +], function (loader, QUnit) { + if (loader.has('live-reload')) { + setupLiveReload(); + } + setupSauceLabsReporting(); + function setupLiveReload() { + QUnit.done(updateResults); + function findModule(name) { + var mods = QUnit.config.modules; + return mods.filter(function (mod) { + return mod.name === name; + }).pop(); + } + function findTestResult(mod, id) { + var tests = mod.tests || []; + return tests.filter(function (test) { + return test.testId === id; + })[0]; + } + function updateResults() { + var tests = document.getElementById('qunit-tests').children; + var node, id, test, moduleName, mod; + passed = true, removedNodes = []; + for (var i = 0, len = tests.length; i < len; i++) { + node = tests.item(i); + id = node.id.split('-').pop(); + moduleName = node.querySelector('.module-name').textContent; + mod = findModule(moduleName); + test = findTestResult(mod, id); + if (test) { + removeAllButLast(node, 'runtime'); + if (node.hasAttribute && node.hasAttribute('class') && node.className !== 'pass') { + passed = false; + break; + } + } else { + removedNodes.push(node); + } + } + removedNodes.forEach(function (node) { + node.parentNode.removeChild(node); + }); + document.getElementById('qunit-banner').className = passed ? 'qunit-pass' : 'qunit-fail'; + } + function removeAllButLast(parent, className) { + var node, nodes = []; + var children = parent.children; + for (var i = 0, len = children.length; i < len; i++) { + node = children.item(i); + if (node.className === className) + nodes.push(node); + } + while (nodes.length > 1) { + node = nodes.shift(); + parent.removeChild(node); + } + } + } + function setupSauceLabsReporting() { + var log = []; + QUnit.done(function (test_results) { + var tests = []; + for (var i = 0, len = log.length; i < len; i++) { + var details = log[i]; + tests.push({ + name: details.name, + result: details.result, + expected: details.expected, + actual: details.actual, + source: details.source + }); + } + test_results.tests = tests; + window.global_test_results = test_results; + }); + QUnit.testStart(function (testDetails) { + QUnit.log(function (details) { + if (!details.result) { + details.name = testDetails.name; + log.push(details); + } + }); + }); + } + QUnit.config.autostart = false; + steal.done().then(function () { + if (window.Testee && window.Testee.init) { + Testee.init(); + } + var qunitVersion = Number(QUnit.version.split('.')[0]); + if (qunitVersion < 2) { + QUnit.load(); + } + }); + return QUnit; +}); +/*can-namespace@1.0.0#can-namespace*/ +define('can-namespace@1.0.0#can-namespace', function (require, exports, module) { + module.exports = {}; +}); +/*can-symbol@1.6.5#can-symbol*/ +define('can-symbol@1.6.5#can-symbol', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var supportsNativeSymbols = function () { + var symbolExists = typeof Symbol !== 'undefined' && typeof Symbol.for === 'function'; + if (!symbolExists) { + return false; + } + var symbol = Symbol('a symbol for testing symbols'); + return typeof symbol === 'symbol'; + }(); + var CanSymbol; + if (supportsNativeSymbols) { + CanSymbol = Symbol; + } else { + var symbolNum = 0; + CanSymbol = function CanSymbolPolyfill(description) { + var symbolValue = '@@symbol' + symbolNum++ + description; + var symbol = {}; + Object.defineProperties(symbol, { + toString: { + value: function () { + return symbolValue; + } + } + }); + return symbol; + }; + var descriptionToSymbol = {}; + var symbolToDescription = {}; + CanSymbol.for = function (description) { + var symbol = descriptionToSymbol[description]; + if (!symbol) { + symbol = descriptionToSymbol[description] = CanSymbol(description); + symbolToDescription[symbol] = description; + } + return symbol; + }; + CanSymbol.keyFor = function (symbol) { + return symbolToDescription[symbol]; + }; + [ + 'hasInstance', + 'isConcatSpreadable', + 'iterator', + 'match', + 'prototype', + 'replace', + 'search', + 'species', + 'split', + 'toPrimitive', + 'toStringTag', + 'unscopables' + ].forEach(function (name) { + CanSymbol[name] = CanSymbol('Symbol.' + name); + }); + } + [ + 'isMapLike', + 'isListLike', + 'isValueLike', + 'isFunctionLike', + 'getOwnKeys', + 'getOwnKeyDescriptor', + 'proto', + 'getOwnEnumerableKeys', + 'hasOwnKey', + 'hasKey', + 'size', + 'getName', + 'getIdentity', + 'assignDeep', + 'updateDeep', + 'getValue', + 'setValue', + 'getKeyValue', + 'setKeyValue', + 'updateValues', + 'addValue', + 'removeValues', + 'apply', + 'new', + 'onValue', + 'offValue', + 'onKeyValue', + 'offKeyValue', + 'getKeyDependencies', + 'getValueDependencies', + 'keyHasDependencies', + 'valueHasDependencies', + 'onKeys', + 'onKeysAdded', + 'onKeysRemoved', + 'onPatches' + ].forEach(function (name) { + CanSymbol.for('can.' + name); + }); + module.exports = namespace.Symbol = CanSymbol; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-observation-recorder@1.3.1#can-observation-recorder*/ +define('can-observation-recorder@1.3.1#can-observation-recorder', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var canSymbol = require('can-symbol'); + var stack = []; + var addParentSymbol = canSymbol.for('can.addParent'), getValueSymbol = canSymbol.for('can.getValue'); + var ObservationRecorder = { + stack: stack, + start: function (name) { + var deps = { + keyDependencies: new Map(), + valueDependencies: new Set(), + childDependencies: new Set(), + traps: null, + ignore: 0, + name: name + }; + stack.push(deps); + return deps; + }, + stop: function () { + return stack.pop(); + }, + add: function (obj, event) { + var top = stack[stack.length - 1]; + if (top && top.ignore === 0) { + if (top.traps) { + top.traps.push([ + obj, + event + ]); + } else { + if (event === undefined) { + top.valueDependencies.add(obj); + } else { + var eventSet = top.keyDependencies.get(obj); + if (!eventSet) { + eventSet = new Set(); + top.keyDependencies.set(obj, eventSet); + } + eventSet.add(event); + } + } + } + }, + addMany: function (observes) { + var top = stack[stack.length - 1]; + if (top) { + if (top.traps) { + top.traps.push.apply(top.traps, observes); + } else { + for (var i = 0, len = observes.length; i < len; i++) { + this.add(observes[i][0], observes[i][1]); + } + } + } + }, + created: function (obs) { + var top = stack[stack.length - 1]; + if (top) { + top.childDependencies.add(obs); + if (obs[addParentSymbol]) { + obs[addParentSymbol](top); + } + } + }, + ignore: function (fn) { + return function () { + if (stack.length) { + var top = stack[stack.length - 1]; + top.ignore++; + var res = fn.apply(this, arguments); + top.ignore--; + return res; + } else { + return fn.apply(this, arguments); + } + }; + }, + peekValue: function (value) { + if (!value || !value[getValueSymbol]) { + return value; + } + if (stack.length) { + var top = stack[stack.length - 1]; + top.ignore++; + var res = value[getValueSymbol](); + top.ignore--; + return res; + } else { + return value[getValueSymbol](); + } + }, + isRecording: function () { + var len = stack.length; + var last = len && stack[len - 1]; + return last && last.ignore === 0 && last; + }, + makeDependenciesRecord: function (name) { + return { + traps: null, + keyDependencies: new Map(), + valueDependencies: new Set(), + ignore: 0, + name: name + }; + }, + makeDependenciesRecorder: function () { + return ObservationRecorder.makeDependenciesRecord(); + }, + trap: function () { + if (stack.length) { + var top = stack[stack.length - 1]; + var oldTraps = top.traps; + var traps = top.traps = []; + return function () { + top.traps = oldTraps; + return traps; + }; + } else { + return function () { + return []; + }; + } + }, + trapsCount: function () { + if (stack.length) { + var top = stack[stack.length - 1]; + return top.traps.length; + } else { + return 0; + } + } + }; + if (namespace.ObservationRecorder) { + throw new Error('You can\'t have two versions of can-observation-recorder, check your dependencies'); + } else { + module.exports = namespace.ObservationRecorder = ObservationRecorder; + } +}); +/*can-log@1.0.2#can-log*/ +define('can-log@1.0.2#can-log', function (require, exports, module) { + 'use strict'; + exports.warnTimeout = 5000; + exports.logLevel = 0; + exports.warn = function () { + var ll = this.logLevel; + if (ll < 2) { + if (typeof console !== 'undefined' && console.warn) { + this._logger('warn', Array.prototype.slice.call(arguments)); + } else if (typeof console !== 'undefined' && console.log) { + this._logger('log', Array.prototype.slice.call(arguments)); + } + } + }; + exports.log = function () { + var ll = this.logLevel; + if (ll < 1) { + if (typeof console !== 'undefined' && console.log) { + this._logger('log', Array.prototype.slice.call(arguments)); + } + } + }; + exports.error = function () { + var ll = this.logLevel; + if (ll < 1) { + if (typeof console !== 'undefined' && console.error) { + this._logger('error', Array.prototype.slice.call(arguments)); + } + } + }; + exports._logger = function (type, arr) { + try { + console[type].apply(console, arr); + } catch (e) { + console[type](arr); + } + }; +}); +/*can-log@1.0.2#dev/dev*/ +define('can-log@1.0.2#dev/dev', [ + 'require', + 'exports', + 'module', + '../can-log' +], function (require, exports, module) { + 'use strict'; + var canLog = require('../can-log'); + module.exports = { + warnTimeout: 5000, + logLevel: 0, + stringify: function (value) { + var flagUndefined = function flagUndefined(key, value) { + return value === undefined ? '/* void(undefined) */' : value; + }; + return JSON.stringify(value, flagUndefined, ' ').replace(/"\/\* void\(undefined\) \*\/"/g, 'undefined'); + }, + warn: function () { + }, + log: function () { + }, + error: function () { + }, + _logger: canLog._logger + }; +}); +/*can-reflect@1.18.0#reflections/helpers*/ +define('can-reflect@1.18.0#reflections/helpers', [ + 'require', + 'exports', + 'module', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + module.exports = { + makeGetFirstSymbolValue: function (symbolNames) { + var symbols = symbolNames.map(function (name) { + return canSymbol.for(name); + }); + var length = symbols.length; + return function getFirstSymbol(obj) { + var index = -1; + while (++index < length) { + if (obj[symbols[index]] !== undefined) { + return obj[symbols[index]]; + } + } + }; + }, + hasLength: function (list) { + var type = typeof list; + if (type === 'string' || Array.isArray(list)) { + return true; + } + var length = list && (type !== 'boolean' && type !== 'number' && 'length' in list) && list.length; + return typeof list !== 'function' && (length === 0 || typeof length === 'number' && length > 0 && length - 1 in list); + } + }; +}); +/*can-reflect@1.18.0#reflections/type/type*/ +define('can-reflect@1.18.0#reflections/type/type', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../helpers' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var helpers = require('../helpers'); + var plainFunctionPrototypePropertyNames = Object.getOwnPropertyNames(function () { + }.prototype); + var plainFunctionPrototypeProto = Object.getPrototypeOf(function () { + }.prototype); + function isConstructorLike(func) { + var value = func[canSymbol.for('can.new')]; + if (value !== undefined) { + return value; + } + if (typeof func !== 'function') { + return false; + } + var prototype = func.prototype; + if (!prototype) { + return false; + } + if (plainFunctionPrototypeProto !== Object.getPrototypeOf(prototype)) { + return true; + } + var propertyNames = Object.getOwnPropertyNames(prototype); + if (propertyNames.length === plainFunctionPrototypePropertyNames.length) { + for (var i = 0, len = propertyNames.length; i < len; i++) { + if (propertyNames[i] !== plainFunctionPrototypePropertyNames[i]) { + return true; + } + } + return false; + } else { + return true; + } + } + var getNewOrApply = helpers.makeGetFirstSymbolValue([ + 'can.new', + 'can.apply' + ]); + function isFunctionLike(obj) { + var result, symbolValue = !!obj && obj[canSymbol.for('can.isFunctionLike')]; + if (symbolValue !== undefined) { + return symbolValue; + } + result = getNewOrApply(obj); + if (result !== undefined) { + return !!result; + } + return typeof obj === 'function'; + } + function isPrimitive(obj) { + var type = typeof obj; + if (obj == null || type !== 'function' && type !== 'object') { + return true; + } else { + return false; + } + } + var coreHasOwn = Object.prototype.hasOwnProperty; + var funcToString = Function.prototype.toString; + var objectCtorString = funcToString.call(Object); + function isPlainObject(obj) { + if (!obj || typeof obj !== 'object') { + return false; + } + var proto = Object.getPrototypeOf(obj); + if (proto === Object.prototype || proto === null) { + return true; + } + var Constructor = coreHasOwn.call(proto, 'constructor') && proto.constructor; + return typeof Constructor === 'function' && Constructor instanceof Constructor && funcToString.call(Constructor) === objectCtorString; + } + function isBuiltIn(obj) { + if (isPrimitive(obj) || Array.isArray(obj) || isPlainObject(obj) || Object.prototype.toString.call(obj) !== '[object Object]' && Object.prototype.toString.call(obj).indexOf('[object ') !== -1) { + return true; + } else { + return false; + } + } + function isValueLike(obj) { + var symbolValue; + if (isPrimitive(obj)) { + return true; + } + symbolValue = obj[canSymbol.for('can.isValueLike')]; + if (typeof symbolValue !== 'undefined') { + return symbolValue; + } + var value = obj[canSymbol.for('can.getValue')]; + if (value !== undefined) { + return !!value; + } + } + function isMapLike(obj) { + if (isPrimitive(obj)) { + return false; + } + var isMapLike = obj[canSymbol.for('can.isMapLike')]; + if (typeof isMapLike !== 'undefined') { + return !!isMapLike; + } + var value = obj[canSymbol.for('can.getKeyValue')]; + if (value !== undefined) { + return !!value; + } + return true; + } + var onValueSymbol = canSymbol.for('can.onValue'), onKeyValueSymbol = canSymbol.for('can.onKeyValue'), onPatchesSymbol = canSymbol.for('can.onPatches'); + function isObservableLike(obj) { + if (isPrimitive(obj)) { + return false; + } + return Boolean(obj[onValueSymbol] || obj[onKeyValueSymbol] || obj[onPatchesSymbol]); + } + function isListLike(list) { + var symbolValue, type = typeof list; + if (type === 'string') { + return true; + } + if (isPrimitive(list)) { + return false; + } + symbolValue = list[canSymbol.for('can.isListLike')]; + if (typeof symbolValue !== 'undefined') { + return symbolValue; + } + var value = list[canSymbol.iterator]; + if (value !== undefined) { + return !!value; + } + if (Array.isArray(list)) { + return true; + } + return helpers.hasLength(list); + } + var supportsNativeSymbols = function () { + var symbolExists = typeof Symbol !== 'undefined' && typeof Symbol.for === 'function'; + if (!symbolExists) { + return false; + } + var symbol = Symbol('a symbol for testing symbols'); + return typeof symbol === 'symbol'; + }(); + var isSymbolLike; + if (supportsNativeSymbols) { + isSymbolLike = function (symbol) { + return typeof symbol === 'symbol'; + }; + } else { + var symbolStart = '@@symbol'; + isSymbolLike = function (symbol) { + if (typeof symbol === 'object' && !Array.isArray(symbol)) { + return symbol.toString().substr(0, symbolStart.length) === symbolStart; + } else { + return false; + } + }; + } + module.exports = { + isConstructorLike: isConstructorLike, + isFunctionLike: isFunctionLike, + isListLike: isListLike, + isMapLike: isMapLike, + isObservableLike: isObservableLike, + isPrimitive: isPrimitive, + isBuiltIn: isBuiltIn, + isValueLike: isValueLike, + isSymbolLike: isSymbolLike, + isMoreListLikeThanMapLike: function (obj) { + if (Array.isArray(obj)) { + return true; + } + if (obj instanceof Array) { + return true; + } + if (obj == null) { + return false; + } + var value = obj[canSymbol.for('can.isMoreListLikeThanMapLike')]; + if (value !== undefined) { + return value; + } + var isListLike = this.isListLike(obj), isMapLike = this.isMapLike(obj); + if (isListLike && !isMapLike) { + return true; + } else if (!isListLike && isMapLike) { + return false; + } + }, + isIteratorLike: function (obj) { + return obj && typeof obj === 'object' && typeof obj.next === 'function' && obj.next.length === 0; + }, + isPromise: function (obj) { + return obj instanceof Promise || Object.prototype.toString.call(obj) === '[object Promise]'; + }, + isPlainObject: isPlainObject + }; +}); +/*can-reflect@1.18.0#reflections/call/call*/ +define('can-reflect@1.18.0#reflections/call/call', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../type/type' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var typeReflections = require('../type/type'); + module.exports = { + call: function (func, context) { + var args = [].slice.call(arguments, 2); + var apply = func[canSymbol.for('can.apply')]; + if (apply) { + return apply.call(func, context, args); + } else { + return func.apply(context, args); + } + }, + apply: function (func, context, args) { + var apply = func[canSymbol.for('can.apply')]; + if (apply) { + return apply.call(func, context, args); + } else { + return func.apply(context, args); + } + }, + 'new': function (func) { + var args = [].slice.call(arguments, 1); + var makeNew = func[canSymbol.for('can.new')]; + if (makeNew) { + return makeNew.apply(func, args); + } else { + var context = Object.create(func.prototype); + var ret = func.apply(context, args); + if (typeReflections.isPrimitive(ret)) { + return context; + } else { + return ret; + } + } + } + }; +}); +/*can-reflect@1.18.0#reflections/get-set/get-set*/ +define('can-reflect@1.18.0#reflections/get-set/get-set', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../type/type' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var typeReflections = require('../type/type'); + var setKeyValueSymbol = canSymbol.for('can.setKeyValue'), getKeyValueSymbol = canSymbol.for('can.getKeyValue'), getValueSymbol = canSymbol.for('can.getValue'), setValueSymbol = canSymbol.for('can.setValue'); + var reflections = { + setKeyValue: function (obj, key, value) { + if (typeReflections.isSymbolLike(key)) { + if (typeof key === 'symbol') { + obj[key] = value; + } else { + Object.defineProperty(obj, key, { + enumerable: false, + configurable: true, + value: value, + writable: true + }); + } + return; + } + var setKeyValue = obj[setKeyValueSymbol]; + if (setKeyValue !== undefined) { + return setKeyValue.call(obj, key, value); + } else { + obj[key] = value; + } + }, + getKeyValue: function (obj, key) { + var getKeyValue = obj[getKeyValueSymbol]; + if (getKeyValue) { + return getKeyValue.call(obj, key); + } + return obj[key]; + }, + deleteKeyValue: function (obj, key) { + var deleteKeyValue = obj[canSymbol.for('can.deleteKeyValue')]; + if (deleteKeyValue) { + return deleteKeyValue.call(obj, key); + } + delete obj[key]; + }, + getValue: function (value) { + if (typeReflections.isPrimitive(value)) { + return value; + } + var getValue = value[getValueSymbol]; + if (getValue) { + return getValue.call(value); + } + return value; + }, + setValue: function (item, value) { + var setValue = item && item[setValueSymbol]; + if (setValue) { + return setValue.call(item, value); + } else { + throw new Error('can-reflect.setValue - Can not set value.'); + } + }, + splice: function (obj, index, removing, adding) { + var howMany; + if (typeof removing !== 'number') { + var updateValues = obj[canSymbol.for('can.updateValues')]; + if (updateValues) { + return updateValues.call(obj, index, removing, adding); + } + howMany = removing.length; + } else { + howMany = removing; + } + if (arguments.length <= 3) { + adding = []; + } + var splice = obj[canSymbol.for('can.splice')]; + if (splice) { + return splice.call(obj, index, howMany, adding); + } + return [].splice.apply(obj, [ + index, + howMany + ].concat(adding)); + }, + addValues: function (obj, adding, index) { + var add = obj[canSymbol.for('can.addValues')]; + if (add) { + return add.call(obj, adding, index); + } + if (Array.isArray(obj) && index === undefined) { + return obj.push.apply(obj, adding); + } + return reflections.splice(obj, index, [], adding); + }, + removeValues: function (obj, removing, index) { + var removeValues = obj[canSymbol.for('can.removeValues')]; + if (removeValues) { + return removeValues.call(obj, removing, index); + } + if (Array.isArray(obj) && index === undefined) { + removing.forEach(function (item) { + var index = obj.indexOf(item); + if (index >= 0) { + obj.splice(index, 1); + } + }); + return; + } + return reflections.splice(obj, index, removing, []); + } + }; + reflections.get = reflections.getKeyValue; + reflections.set = reflections.setKeyValue; + reflections['delete'] = reflections.deleteKeyValue; + module.exports = reflections; +}); +/*can-reflect@1.18.0#reflections/observe/observe*/ +define('can-reflect@1.18.0#reflections/observe/observe', [ + 'require', + 'exports', + 'module', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var slice = [].slice; + function makeFallback(symbolName, fallbackName) { + return function (obj, event, handler, queueName) { + var method = obj[canSymbol.for(symbolName)]; + if (method !== undefined) { + return method.call(obj, event, handler, queueName); + } + return this[fallbackName].apply(this, arguments); + }; + } + function makeErrorIfMissing(symbolName, errorMessage) { + return function (obj) { + var method = obj[canSymbol.for(symbolName)]; + if (method !== undefined) { + var args = slice.call(arguments, 1); + return method.apply(obj, args); + } + throw new Error(errorMessage); + }; + } + module.exports = { + onKeyValue: makeFallback('can.onKeyValue', 'onEvent'), + offKeyValue: makeFallback('can.offKeyValue', 'offEvent'), + onKeys: makeErrorIfMissing('can.onKeys', 'can-reflect: can not observe an onKeys event'), + onKeysAdded: makeErrorIfMissing('can.onKeysAdded', 'can-reflect: can not observe an onKeysAdded event'), + onKeysRemoved: makeErrorIfMissing('can.onKeysRemoved', 'can-reflect: can not unobserve an onKeysRemoved event'), + getKeyDependencies: makeErrorIfMissing('can.getKeyDependencies', 'can-reflect: can not determine dependencies'), + getWhatIChange: makeErrorIfMissing('can.getWhatIChange', 'can-reflect: can not determine dependencies'), + getChangesDependencyRecord: function getChangesDependencyRecord(handler) { + var fn = handler[canSymbol.for('can.getChangesDependencyRecord')]; + if (typeof fn === 'function') { + return fn(); + } + }, + keyHasDependencies: makeErrorIfMissing('can.keyHasDependencies', 'can-reflect: can not determine if this has key dependencies'), + onValue: makeErrorIfMissing('can.onValue', 'can-reflect: can not observe value change'), + offValue: makeErrorIfMissing('can.offValue', 'can-reflect: can not unobserve value change'), + getValueDependencies: makeErrorIfMissing('can.getValueDependencies', 'can-reflect: can not determine dependencies'), + valueHasDependencies: makeErrorIfMissing('can.valueHasDependencies', 'can-reflect: can not determine if value has dependencies'), + onPatches: makeErrorIfMissing('can.onPatches', 'can-reflect: can not observe patches on object'), + offPatches: makeErrorIfMissing('can.offPatches', 'can-reflect: can not unobserve patches on object'), + onInstancePatches: makeErrorIfMissing('can.onInstancePatches', 'can-reflect: can not observe onInstancePatches on Type'), + offInstancePatches: makeErrorIfMissing('can.offInstancePatches', 'can-reflect: can not unobserve onInstancePatches on Type'), + onInstanceBoundChange: makeErrorIfMissing('can.onInstanceBoundChange', 'can-reflect: can not observe bound state change in instances.'), + offInstanceBoundChange: makeErrorIfMissing('can.offInstanceBoundChange', 'can-reflect: can not unobserve bound state change'), + isBound: makeErrorIfMissing('can.isBound', 'can-reflect: cannot determine if object is bound'), + onEvent: function (obj, eventName, callback, queue) { + if (obj) { + var onEvent = obj[canSymbol.for('can.onEvent')]; + if (onEvent !== undefined) { + return onEvent.call(obj, eventName, callback, queue); + } else if (obj.addEventListener) { + obj.addEventListener(eventName, callback, queue); + } + } + }, + offEvent: function (obj, eventName, callback, queue) { + if (obj) { + var offEvent = obj[canSymbol.for('can.offEvent')]; + if (offEvent !== undefined) { + return offEvent.call(obj, eventName, callback, queue); + } else if (obj.removeEventListener) { + obj.removeEventListener(eventName, callback, queue); + } + } + }, + setPriority: function (obj, priority) { + if (obj) { + var setPriority = obj[canSymbol.for('can.setPriority')]; + if (setPriority !== undefined) { + setPriority.call(obj, priority); + return true; + } + } + return false; + }, + getPriority: function (obj) { + if (obj) { + var getPriority = obj[canSymbol.for('can.getPriority')]; + if (getPriority !== undefined) { + return getPriority.call(obj); + } + } + return undefined; + } + }; +}); +/*can-reflect@1.18.0#reflections/shape/shape*/ +define('can-reflect@1.18.0#reflections/shape/shape', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../get-set/get-set', + '../type/type', + '../helpers' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var getSetReflections = require('../get-set/get-set'); + var typeReflections = require('../type/type'); + var helpers = require('../helpers'); + var getPrototypeOfWorksWithPrimitives = true; + try { + Object.getPrototypeOf(1); + } catch (e) { + getPrototypeOfWorksWithPrimitives = false; + } + var ArrayMap; + if (typeof Map === 'function') { + ArrayMap = Map; + } else { + var isEven = function isEven(num) { + return num % 2 === 0; + }; + ArrayMap = function () { + this.contents = []; + }; + ArrayMap.prototype = { + _getIndex: function (key) { + var idx; + do { + idx = this.contents.indexOf(key, idx); + } while (idx !== -1 && !isEven(idx)); + return idx; + }, + has: function (key) { + return this._getIndex(key) !== -1; + }, + get: function (key) { + var idx = this._getIndex(key); + if (idx !== -1) { + return this.contents[idx + 1]; + } + }, + set: function (key, value) { + var idx = this._getIndex(key); + if (idx !== -1) { + this.contents[idx + 1] = value; + } else { + this.contents.push(key); + this.contents.push(value); + } + }, + 'delete': function (key) { + var idx = this._getIndex(key); + if (idx !== -1) { + this.contents.splice(idx, 2); + } + } + }; + } + var hasOwnProperty = Object.prototype.hasOwnProperty; + var shapeReflections; + var shiftFirstArgumentToThis = function (func) { + return function () { + var args = [this]; + args.push.apply(args, arguments); + return func.apply(null, args); + }; + }; + var getKeyValueSymbol = canSymbol.for('can.getKeyValue'); + var shiftedGetKeyValue = shiftFirstArgumentToThis(getSetReflections.getKeyValue); + var setKeyValueSymbol = canSymbol.for('can.setKeyValue'); + var shiftedSetKeyValue = shiftFirstArgumentToThis(getSetReflections.setKeyValue); + var sizeSymbol = canSymbol.for('can.size'); + var hasUpdateSymbol = helpers.makeGetFirstSymbolValue([ + 'can.updateDeep', + 'can.assignDeep', + 'can.setKeyValue' + ]); + var shouldUpdateOrAssign = function (obj) { + return typeReflections.isPlainObject(obj) || Array.isArray(obj) || !!hasUpdateSymbol(obj); + }; + function isSerializedHelper(obj) { + if (typeReflections.isPrimitive(obj)) { + return true; + } + if (hasUpdateSymbol(obj)) { + return false; + } + return typeReflections.isBuiltIn(obj) && !typeReflections.isPlainObject(obj) && !Array.isArray(obj) && !typeReflections.isObservableLike(obj); + } + var Object_Keys; + try { + Object.keys(1); + Object_Keys = Object.keys; + } catch (e) { + Object_Keys = function (obj) { + if (typeReflections.isPrimitive(obj)) { + return []; + } else { + return Object.keys(obj); + } + }; + } + function createSerializeMap(Type) { + var MapType = Type || ArrayMap; + return { + unwrap: new MapType(), + serialize: new MapType(), + isSerializing: { + unwrap: new MapType(), + serialize: new MapType() + }, + circularReferenceIsSerializing: { + unwrap: new MapType(), + serialize: new MapType() + } + }; + } + function makeSerializer(methodName, symbolsToCheck) { + var serializeMap = null; + function SerializeOperation(MapType) { + this.first = !serializeMap; + if (this.first) { + serializeMap = createSerializeMap(MapType); + } + this.map = serializeMap; + this.result = null; + } + SerializeOperation.prototype.end = function () { + if (this.first) { + serializeMap = null; + } + return this.result; + }; + return function serializer(value, MapType) { + if (isSerializedHelper(value)) { + return value; + } + var operation = new SerializeOperation(MapType); + if (typeReflections.isValueLike(value)) { + operation.result = this[methodName](getSetReflections.getValue(value)); + } else { + var isListLike = typeReflections.isIteratorLike(value) || typeReflections.isMoreListLikeThanMapLike(value); + operation.result = isListLike ? [] : {}; + if (operation.map[methodName].has(value)) { + if (operation.map.isSerializing[methodName].has(value)) { + operation.map.circularReferenceIsSerializing[methodName].set(value, true); + } + return operation.map[methodName].get(value); + } else { + operation.map[methodName].set(value, operation.result); + } + for (var i = 0, len = symbolsToCheck.length; i < len; i++) { + var serializer = value[symbolsToCheck[i]]; + if (serializer) { + operation.map.isSerializing[methodName].set(value, true); + var oldResult = operation.result; + operation.result = serializer.call(value, oldResult); + operation.map.isSerializing[methodName].delete(value); + if (operation.result !== oldResult) { + if (operation.map.circularReferenceIsSerializing[methodName].has(value)) { + operation.end(); + throw new Error('Cannot serialize cirular reference!'); + } + operation.map[methodName].set(value, operation.result); + } + return operation.end(); + } + } + if (typeof obj === 'function') { + operation.map[methodName].set(value, value); + operation.result = value; + } else if (isListLike) { + this.eachIndex(value, function (childValue, index) { + operation.result[index] = this[methodName](childValue); + }, this); + } else { + this.eachKey(value, function (childValue, prop) { + operation.result[prop] = this[methodName](childValue); + }, this); + } + } + return operation.end(); + }; + } + var makeMap; + if (typeof Map !== 'undefined') { + makeMap = function (keys) { + var map = new Map(); + shapeReflections.eachIndex(keys, function (key) { + map.set(key, true); + }); + return map; + }; + } else { + makeMap = function (keys) { + var map = {}; + keys.forEach(function (key) { + map[key] = true; + }); + return { + get: function (key) { + return map[key]; + }, + set: function (key, value) { + map[key] = value; + }, + keys: function () { + return keys; + } + }; + }; + } + var fastHasOwnKey = function (obj) { + var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')]; + if (hasOwnKey) { + return hasOwnKey.bind(obj); + } else { + var map = makeMap(shapeReflections.getOwnEnumerableKeys(obj)); + return function (key) { + return map.get(key); + }; + } + }; + function addPatch(patches, patch) { + var lastPatch = patches[patches.length - 1]; + if (lastPatch) { + if (lastPatch.deleteCount === lastPatch.insert.length && patch.index - lastPatch.index === lastPatch.deleteCount) { + lastPatch.insert.push.apply(lastPatch.insert, patch.insert); + lastPatch.deleteCount += patch.deleteCount; + return; + } + } + patches.push(patch); + } + function updateDeepList(target, source, isAssign) { + var sourceArray = this.toArray(source); + var patches = [], lastIndex = -1; + this.eachIndex(target, function (curVal, index) { + lastIndex = index; + if (index >= sourceArray.length) { + if (!isAssign) { + addPatch(patches, { + index: index, + deleteCount: target.length - index + 1, + insert: [] + }); + } + return false; + } + var newVal = sourceArray[index]; + if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) { + addPatch(patches, { + index: index, + deleteCount: 1, + insert: [newVal] + }); + } else { + if (isAssign === true) { + this.assignDeep(curVal, newVal); + } else { + this.updateDeep(curVal, newVal); + } + } + }, this); + if (sourceArray.length > lastIndex) { + addPatch(patches, { + index: lastIndex + 1, + deleteCount: 0, + insert: sourceArray.slice(lastIndex + 1) + }); + } + for (var i = 0, patchLen = patches.length; i < patchLen; i++) { + var patch = patches[i]; + getSetReflections.splice(target, patch.index, patch.deleteCount, patch.insert); + } + return target; + } + shapeReflections = { + each: function (obj, callback, context) { + if (typeReflections.isIteratorLike(obj) || typeReflections.isMoreListLikeThanMapLike(obj)) { + return shapeReflections.eachIndex(obj, callback, context); + } else { + return shapeReflections.eachKey(obj, callback, context); + } + }, + eachIndex: function (list, callback, context) { + if (Array.isArray(list)) { + return shapeReflections.eachListLike(list, callback, context); + } else { + var iter, iterator = list[canSymbol.iterator]; + if (typeReflections.isIteratorLike(list)) { + iter = list; + } else if (iterator) { + iter = iterator.call(list); + } + if (iter) { + var res, index = 0; + while (!(res = iter.next()).done) { + if (callback.call(context || list, res.value, index++, list) === false) { + break; + } + } + } else { + shapeReflections.eachListLike(list, callback, context); + } + } + return list; + }, + eachListLike: function (list, callback, context) { + var index = -1; + var length = list.length; + if (length === undefined) { + var size = list[sizeSymbol]; + if (size) { + length = size.call(list); + } else { + throw new Error('can-reflect: unable to iterate.'); + } + } + while (++index < length) { + var item = list[index]; + if (callback.call(context || item, item, index, list) === false) { + break; + } + } + return list; + }, + toArray: function (obj) { + var arr = []; + shapeReflections.each(obj, function (value) { + arr.push(value); + }); + return arr; + }, + eachKey: function (obj, callback, context) { + if (obj) { + var enumerableKeys = shapeReflections.getOwnEnumerableKeys(obj); + var getKeyValue = obj[getKeyValueSymbol] || shiftedGetKeyValue; + return shapeReflections.eachIndex(enumerableKeys, function (key) { + var value = getKeyValue.call(obj, key); + return callback.call(context || obj, value, key, obj); + }); + } + return obj; + }, + 'hasOwnKey': function (obj, key) { + var hasOwnKey = obj[canSymbol.for('can.hasOwnKey')]; + if (hasOwnKey) { + return hasOwnKey.call(obj, key); + } + var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')]; + if (getOwnKeys) { + var found = false; + shapeReflections.eachIndex(getOwnKeys.call(obj), function (objKey) { + if (objKey === key) { + found = true; + return false; + } + }); + return found; + } + return hasOwnProperty.call(obj, key); + }, + getOwnEnumerableKeys: function (obj) { + var getOwnEnumerableKeys = obj[canSymbol.for('can.getOwnEnumerableKeys')]; + if (getOwnEnumerableKeys) { + return getOwnEnumerableKeys.call(obj); + } + if (obj[canSymbol.for('can.getOwnKeys')] && obj[canSymbol.for('can.getOwnKeyDescriptor')]) { + var keys = []; + shapeReflections.eachIndex(shapeReflections.getOwnKeys(obj), function (key) { + var descriptor = shapeReflections.getOwnKeyDescriptor(obj, key); + if (descriptor.enumerable) { + keys.push(key); + } + }, this); + return keys; + } else { + return Object_Keys(obj); + } + }, + getOwnKeys: function (obj) { + var getOwnKeys = obj[canSymbol.for('can.getOwnKeys')]; + if (getOwnKeys) { + return getOwnKeys.call(obj); + } else { + return Object.getOwnPropertyNames(obj); + } + }, + getOwnKeyDescriptor: function (obj, key) { + var getOwnKeyDescriptor = obj[canSymbol.for('can.getOwnKeyDescriptor')]; + if (getOwnKeyDescriptor) { + return getOwnKeyDescriptor.call(obj, key); + } else { + return Object.getOwnPropertyDescriptor(obj, key); + } + }, + unwrap: makeSerializer('unwrap', [canSymbol.for('can.unwrap')]), + serialize: makeSerializer('serialize', [ + canSymbol.for('can.serialize'), + canSymbol.for('can.unwrap') + ]), + assignMap: function (target, source) { + var hasOwnKey = fastHasOwnKey(target); + var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue; + var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue; + shapeReflections.eachKey(source, function (value, key) { + if (!hasOwnKey(key) || getKeyValue.call(target, key) !== value) { + setKeyValue.call(target, key, value); + } + }); + return target; + }, + assignList: function (target, source) { + var inserting = shapeReflections.toArray(source); + getSetReflections.splice(target, 0, inserting, inserting); + return target; + }, + assign: function (target, source) { + if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) { + shapeReflections.assignList(target, source); + } else { + shapeReflections.assignMap(target, source); + } + return target; + }, + assignDeepMap: function (target, source) { + var hasOwnKey = fastHasOwnKey(target); + var getKeyValue = target[getKeyValueSymbol] || shiftedGetKeyValue; + var setKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue; + shapeReflections.eachKey(source, function (newVal, key) { + if (!hasOwnKey(key)) { + getSetReflections.setKeyValue(target, key, newVal); + } else { + var curVal = getKeyValue.call(target, key); + if (newVal === curVal) { + } else if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) { + setKeyValue.call(target, key, newVal); + } else { + shapeReflections.assignDeep(curVal, newVal); + } + } + }, this); + return target; + }, + assignDeepList: function (target, source) { + return updateDeepList.call(this, target, source, true); + }, + assignDeep: function (target, source) { + var assignDeep = target[canSymbol.for('can.assignDeep')]; + if (assignDeep) { + assignDeep.call(target, source); + } else if (typeReflections.isMoreListLikeThanMapLike(source)) { + shapeReflections.assignDeepList(target, source); + } else { + shapeReflections.assignDeepMap(target, source); + } + return target; + }, + updateMap: function (target, source) { + var sourceKeyMap = makeMap(shapeReflections.getOwnEnumerableKeys(source)); + var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue; + var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue; + shapeReflections.eachKey(target, function (curVal, key) { + if (!sourceKeyMap.get(key)) { + getSetReflections.deleteKeyValue(target, key); + return; + } + sourceKeyMap.set(key, false); + var newVal = sourceGetKeyValue.call(source, key); + if (newVal !== curVal) { + targetSetKeyValue.call(target, key, newVal); + } + }, this); + shapeReflections.eachIndex(sourceKeyMap.keys(), function (key) { + if (sourceKeyMap.get(key)) { + targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key)); + } + }); + return target; + }, + updateList: function (target, source) { + var inserting = shapeReflections.toArray(source); + getSetReflections.splice(target, 0, target, inserting); + return target; + }, + update: function (target, source) { + if (typeReflections.isIteratorLike(source) || typeReflections.isMoreListLikeThanMapLike(source)) { + shapeReflections.updateList(target, source); + } else { + shapeReflections.updateMap(target, source); + } + return target; + }, + updateDeepMap: function (target, source) { + var sourceKeyMap = makeMap(shapeReflections.getOwnEnumerableKeys(source)); + var sourceGetKeyValue = source[getKeyValueSymbol] || shiftedGetKeyValue; + var targetSetKeyValue = target[setKeyValueSymbol] || shiftedSetKeyValue; + shapeReflections.eachKey(target, function (curVal, key) { + if (!sourceKeyMap.get(key)) { + getSetReflections.deleteKeyValue(target, key); + return; + } + sourceKeyMap.set(key, false); + var newVal = sourceGetKeyValue.call(source, key); + if (typeReflections.isPrimitive(curVal) || typeReflections.isPrimitive(newVal) || shouldUpdateOrAssign(curVal) === false) { + targetSetKeyValue.call(target, key, newVal); + } else { + shapeReflections.updateDeep(curVal, newVal); + } + }, this); + shapeReflections.eachIndex(sourceKeyMap.keys(), function (key) { + if (sourceKeyMap.get(key)) { + targetSetKeyValue.call(target, key, sourceGetKeyValue.call(source, key)); + } + }); + return target; + }, + updateDeepList: function (target, source) { + return updateDeepList.call(this, target, source); + }, + updateDeep: function (target, source) { + var updateDeep = target[canSymbol.for('can.updateDeep')]; + if (updateDeep) { + updateDeep.call(target, source); + } else if (typeReflections.isMoreListLikeThanMapLike(source)) { + shapeReflections.updateDeepList(target, source); + } else { + shapeReflections.updateDeepMap(target, source); + } + return target; + }, + hasKey: function (obj, key) { + if (obj == null) { + return false; + } + if (typeReflections.isPrimitive(obj)) { + if (hasOwnProperty.call(obj, key)) { + return true; + } else { + var proto; + if (getPrototypeOfWorksWithPrimitives) { + proto = Object.getPrototypeOf(obj); + } else { + proto = obj.__proto__; + } + if (proto !== undefined) { + return key in proto; + } else { + return obj[key] !== undefined; + } + } + } + var hasKey = obj[canSymbol.for('can.hasKey')]; + if (hasKey) { + return hasKey.call(obj, key); + } + var found = shapeReflections.hasOwnKey(obj, key); + return found || key in obj; + }, + getAllEnumerableKeys: function () { + }, + getAllKeys: function () { + }, + assignSymbols: function (target, source) { + shapeReflections.eachKey(source, function (value, key) { + var symbol = typeReflections.isSymbolLike(canSymbol[key]) ? canSymbol[key] : canSymbol.for(key); + getSetReflections.setKeyValue(target, symbol, value); + }); + return target; + }, + isSerialized: isSerializedHelper, + size: function (obj) { + if (obj == null) { + return 0; + } + var size = obj[sizeSymbol]; + var count = 0; + if (size) { + return size.call(obj); + } else if (helpers.hasLength(obj)) { + return obj.length; + } else if (typeReflections.isListLike(obj)) { + shapeReflections.eachIndex(obj, function () { + count++; + }); + return count; + } else if (obj) { + return shapeReflections.getOwnEnumerableKeys(obj).length; + } else { + return undefined; + } + }, + defineInstanceKey: function (cls, key, properties) { + var defineInstanceKey = cls[canSymbol.for('can.defineInstanceKey')]; + if (defineInstanceKey) { + return defineInstanceKey.call(cls, key, properties); + } + var proto = cls.prototype; + defineInstanceKey = proto[canSymbol.for('can.defineInstanceKey')]; + if (defineInstanceKey) { + defineInstanceKey.call(proto, key, properties); + } else { + Object.defineProperty(proto, key, shapeReflections.assign({ + configurable: true, + enumerable: !typeReflections.isSymbolLike(key), + writable: true + }, properties)); + } + } + }; + shapeReflections.isSerializable = shapeReflections.isSerialized; + shapeReflections.keys = shapeReflections.getOwnEnumerableKeys; + module.exports = shapeReflections; +}); +/*can-reflect@1.18.0#reflections/shape/schema/schema*/ +define('can-reflect@1.18.0#reflections/shape/schema/schema', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../../type/type', + '../../get-set/get-set', + '../shape' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var typeReflections = require('../../type/type'); + var getSetReflections = require('../../get-set/get-set'); + var shapeReflections = require('../shape'); + var getSchemaSymbol = canSymbol.for('can.getSchema'), isMemberSymbol = canSymbol.for('can.isMember'), newSymbol = canSymbol.for('can.new'); + function comparator(a, b) { + return a.localeCompare(b); + } + function sort(obj) { + if (typeReflections.isPrimitive(obj) || obj instanceof Date) { + return obj; + } + var out; + if (typeReflections.isListLike(obj)) { + out = []; + shapeReflections.eachKey(obj, function (item) { + out.push(sort(item)); + }); + return out; + } + if (typeReflections.isMapLike(obj)) { + out = {}; + shapeReflections.getOwnKeys(obj).sort(comparator).forEach(function (key) { + out[key] = sort(getSetReflections.getKeyValue(obj, key)); + }); + return out; + } + return obj; + } + function isPrimitiveConverter(Type) { + return Type === Number || Type === String || Type === Boolean; + } + var schemaReflections = { + getSchema: function (type) { + if (type === undefined) { + return undefined; + } + var getSchema = type[getSchemaSymbol]; + if (getSchema === undefined) { + type = type.constructor; + getSchema = type && type[getSchemaSymbol]; + } + return getSchema !== undefined ? getSchema.call(type) : undefined; + }, + getIdentity: function (value, schema) { + schema = schema || schemaReflections.getSchema(value); + if (schema === undefined) { + throw new Error('can-reflect.getIdentity - Unable to find a schema for the given value.'); + } + var identity = schema.identity; + if (!identity || identity.length === 0) { + throw new Error('can-reflect.getIdentity - Provided schema lacks an identity property.'); + } else if (identity.length === 1) { + return getSetReflections.getKeyValue(value, identity[0]); + } else { + var id = {}; + identity.forEach(function (key) { + id[key] = getSetReflections.getKeyValue(value, key); + }); + return JSON.stringify(schemaReflections.cloneKeySort(id)); + } + }, + cloneKeySort: function (obj) { + return sort(obj); + }, + convert: function (value, Type) { + if (isPrimitiveConverter(Type)) { + return Type(value); + } + var isMemberTest = Type[isMemberSymbol], isMember = false, type = typeof Type, createNew = Type[newSymbol]; + if (isMemberTest !== undefined) { + isMember = isMemberTest.call(Type, value); + } else if (type === 'function') { + if (typeReflections.isConstructorLike(Type)) { + isMember = value instanceof Type; + } + } + if (isMember) { + return value; + } + if (createNew !== undefined) { + return createNew.call(Type, value); + } else if (type === 'function') { + if (typeReflections.isConstructorLike(Type)) { + return new Type(value); + } else { + return Type(value); + } + } else { + throw new Error('can-reflect: Can not convert values into type. Type must provide `can.new` symbol.'); + } + } + }; + module.exports = schemaReflections; +}); +/*can-reflect@1.18.0#reflections/get-name/get-name*/ +define('can-reflect@1.18.0#reflections/get-name/get-name', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../type/type' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var typeReflections = require('../type/type'); + var getNameSymbol = canSymbol.for('can.getName'); + function setName(obj, nameGetter) { + if (typeof nameGetter !== 'function') { + var value = nameGetter; + nameGetter = function () { + return value; + }; + } + Object.defineProperty(obj, getNameSymbol, { value: nameGetter }); + } + var anonymousID = 0; + function getName(obj) { + var type = typeof obj; + if (obj === null || type !== 'object' && type !== 'function') { + return '' + obj; + } + var nameGetter = obj[getNameSymbol]; + if (nameGetter) { + return nameGetter.call(obj); + } + if (type === 'function') { + if (!('name' in obj)) { + obj.name = 'functionIE' + anonymousID++; + } + return obj.name; + } + if (obj.constructor && obj !== obj.constructor) { + var parent = getName(obj.constructor); + if (parent) { + if (typeReflections.isValueLike(obj)) { + return parent + '<>'; + } + if (typeReflections.isMoreListLikeThanMapLike(obj)) { + return parent + '[]'; + } + if (typeReflections.isMapLike(obj)) { + return parent + '{}'; + } + } + } + return undefined; + } + module.exports = { + setName: setName, + getName: getName + }; +}); +/*can-reflect@1.18.0#types/map*/ +define('can-reflect@1.18.0#types/map', [ + 'require', + 'exports', + 'module', + '../reflections/shape/shape', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var shape = require('../reflections/shape/shape'); + var CanSymbol = require('can-symbol'); + function keysPolyfill() { + var keys = []; + var currentIndex = 0; + this.forEach(function (val, key) { + keys.push(key); + }); + return { + next: function () { + return { + value: keys[currentIndex], + done: currentIndex++ === keys.length + }; + } + }; + } + if (typeof Map !== 'undefined') { + shape.assignSymbols(Map.prototype, { + 'can.getOwnEnumerableKeys': Map.prototype.keys, + 'can.setKeyValue': Map.prototype.set, + 'can.getKeyValue': Map.prototype.get, + 'can.deleteKeyValue': Map.prototype['delete'], + 'can.hasOwnKey': Map.prototype.has + }); + if (typeof Map.prototype.keys !== 'function') { + Map.prototype.keys = Map.prototype[CanSymbol.for('can.getOwnEnumerableKeys')] = keysPolyfill; + } + } + if (typeof WeakMap !== 'undefined') { + shape.assignSymbols(WeakMap.prototype, { + 'can.getOwnEnumerableKeys': function () { + throw new Error('can-reflect: WeakMaps do not have enumerable keys.'); + }, + 'can.setKeyValue': WeakMap.prototype.set, + 'can.getKeyValue': WeakMap.prototype.get, + 'can.deleteKeyValue': WeakMap.prototype['delete'], + 'can.hasOwnKey': WeakMap.prototype.has + }); + } +}); +/*can-reflect@1.18.0#types/set*/ +define('can-reflect@1.18.0#types/set', [ + 'require', + 'exports', + 'module', + '../reflections/shape/shape', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var shape = require('../reflections/shape/shape'); + var CanSymbol = require('can-symbol'); + if (typeof Set !== 'undefined') { + shape.assignSymbols(Set.prototype, { + 'can.isMoreListLikeThanMapLike': true, + 'can.updateValues': function (index, removing, adding) { + if (removing !== adding) { + shape.each(removing, function (value) { + this.delete(value); + }, this); + } + shape.each(adding, function (value) { + this.add(value); + }, this); + }, + 'can.size': function () { + return this.size; + } + }); + if (typeof Set.prototype[CanSymbol.iterator] !== 'function') { + Set.prototype[CanSymbol.iterator] = function () { + var arr = []; + var currentIndex = 0; + this.forEach(function (val) { + arr.push(val); + }); + return { + next: function () { + return { + value: arr[currentIndex], + done: currentIndex++ === arr.length + }; + } + }; + }; + } + } + if (typeof WeakSet !== 'undefined') { + shape.assignSymbols(WeakSet.prototype, { + 'can.isListLike': true, + 'can.isMoreListLikeThanMapLike': true, + 'can.updateValues': function (index, removing, adding) { + if (removing !== adding) { + shape.each(removing, function (value) { + this.delete(value); + }, this); + } + shape.each(adding, function (value) { + this.add(value); + }, this); + }, + 'can.size': function () { + throw new Error('can-reflect: WeakSets do not have enumerable keys.'); + } + }); + } +}); +/*can-reflect@1.18.0#can-reflect*/ +define('can-reflect@1.18.0#can-reflect', [ + 'require', + 'exports', + 'module', + './reflections/call/call', + './reflections/get-set/get-set', + './reflections/observe/observe', + './reflections/shape/shape', + './reflections/shape/schema/schema', + './reflections/type/type', + './reflections/get-name/get-name', + 'can-namespace', + './types/map', + './types/set' +], function (require, exports, module) { + 'use strict'; + var functionReflections = require('./reflections/call/call'); + var getSet = require('./reflections/get-set/get-set'); + var observe = require('./reflections/observe/observe'); + var shape = require('./reflections/shape/shape'); + var schema = require('./reflections/shape/schema/schema'); + var type = require('./reflections/type/type'); + var getName = require('./reflections/get-name/get-name'); + var namespace = require('can-namespace'); + var reflect = {}; + [ + functionReflections, + getSet, + observe, + shape, + type, + getName, + schema + ].forEach(function (reflections) { + for (var prop in reflections) { + reflect[prop] = reflections[prop]; + } + }); + require('./types/map'); + require('./types/set'); + module.exports = namespace.Reflect = reflect; +}); +/*can-queues@1.3.2#queue-state*/ +define('can-queues@1.3.2#queue-state', function (require, exports, module) { + 'use strict'; + module.exports = { lastTask: null }; +}); +/*can-assign@1.3.3#can-assign*/ +define('can-assign@1.3.3#can-assign', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + var namespace = require('can-namespace'); + module.exports = namespace.assign = function (d, s) { + for (var prop in s) { + var desc = Object.getOwnPropertyDescriptor(d, prop); + if (!desc || desc.writable !== false) { + d[prop] = s[prop]; + } + } + return d; + }; +}); +/*can-queues@1.3.2#queue*/ +define('can-queues@1.3.2#queue', [ + 'require', + 'exports', + 'module', + './queue-state', + 'can-log/dev/dev', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var queueState = require('./queue-state'); + var canDev = require('can-log/dev/dev'); + var assign = require('can-assign'); + function noOperation() { + } + var Queue = function (name, callbacks) { + this.callbacks = assign({ + onFirstTask: noOperation, + onComplete: function () { + queueState.lastTask = null; + } + }, callbacks || {}); + this.name = name; + this.index = 0; + this.tasks = []; + this._log = false; + }; + Queue.prototype.constructor = Queue; + Queue.noop = noOperation; + Queue.prototype.enqueue = function (fn, context, args, meta) { + var len = this.tasks.push({ + fn: fn, + context: context, + args: args, + meta: meta || {} + }); + if (len === 1) { + this.callbacks.onFirstTask(this); + } + }; + Queue.prototype.flush = function () { + while (this.index < this.tasks.length) { + var task = this.tasks[this.index++]; + task.fn.apply(task.context, task.args); + } + this.index = 0; + this.tasks = []; + this.callbacks.onComplete(this); + }; + Queue.prototype.log = function () { + this._log = arguments.length ? arguments[0] : true; + }; + module.exports = Queue; +}); +/*can-queues@1.3.2#priority-queue*/ +define('can-queues@1.3.2#priority-queue', [ + 'require', + 'exports', + 'module', + './queue' +], function (require, exports, module) { + 'use strict'; + var Queue = require('./queue'); + var PriorityQueue = function () { + Queue.apply(this, arguments); + this.taskMap = new Map(); + this.taskContainersByPriority = []; + this.curPriorityIndex = Infinity; + this.curPriorityMax = 0; + this.isFlushing = false; + this.tasksRemaining = 0; + }; + PriorityQueue.prototype = Object.create(Queue.prototype); + PriorityQueue.prototype.constructor = PriorityQueue; + PriorityQueue.prototype.enqueue = function (fn, context, args, meta) { + if (!this.taskMap.has(fn)) { + this.tasksRemaining++; + var isFirst = this.taskContainersByPriority.length === 0; + var task = { + fn: fn, + context: context, + args: args, + meta: meta || {} + }; + var taskContainer = this.getTaskContainerAndUpdateRange(task); + taskContainer.tasks.push(task); + this.taskMap.set(fn, task); + if (isFirst) { + this.callbacks.onFirstTask(this); + } + } + }; + PriorityQueue.prototype.getTaskContainerAndUpdateRange = function (task) { + var priority = task.meta.priority || 0; + if (priority < this.curPriorityIndex) { + this.curPriorityIndex = priority; + } + if (priority > this.curPriorityMax) { + this.curPriorityMax = priority; + } + var tcByPriority = this.taskContainersByPriority; + var taskContainer = tcByPriority[priority]; + if (!taskContainer) { + taskContainer = tcByPriority[priority] = { + tasks: [], + index: 0 + }; + } + return taskContainer; + }; + PriorityQueue.prototype.flush = function () { + if (this.isFlushing) { + return; + } + this.isFlushing = true; + while (true) { + if (this.curPriorityIndex <= this.curPriorityMax) { + var taskContainer = this.taskContainersByPriority[this.curPriorityIndex]; + if (taskContainer && taskContainer.tasks.length > taskContainer.index) { + var task = taskContainer.tasks[taskContainer.index++]; + this.tasksRemaining--; + this.taskMap['delete'](task.fn); + task.fn.apply(task.context, task.args); + } else { + this.curPriorityIndex++; + } + } else { + this.taskMap = new Map(); + this.curPriorityIndex = Infinity; + this.curPriorityMax = 0; + this.taskContainersByPriority = []; + this.isFlushing = false; + this.callbacks.onComplete(this); + return; + } + } + }; + PriorityQueue.prototype.isEnqueued = function (fn) { + return this.taskMap.has(fn); + }; + PriorityQueue.prototype.flushQueuedTask = function (fn) { + var task = this.dequeue(fn); + if (task) { + task.fn.apply(task.context, task.args); + } + }; + PriorityQueue.prototype.dequeue = function (fn) { + var task = this.taskMap.get(fn); + if (task) { + var priority = task.meta.priority || 0; + var taskContainer = this.taskContainersByPriority[priority]; + var index = taskContainer.tasks.indexOf(task, taskContainer.index); + if (index >= 0) { + taskContainer.tasks.splice(index, 1); + this.tasksRemaining--; + this.taskMap['delete'](task.fn); + return task; + } else { + console.warn('Task', fn, 'has already run'); + } + } + }; + PriorityQueue.prototype.tasksRemainingCount = function () { + return this.tasksRemaining; + }; + module.exports = PriorityQueue; +}); +/*can-queues@1.3.2#completion-queue*/ +define('can-queues@1.3.2#completion-queue', [ + 'require', + 'exports', + 'module', + './queue' +], function (require, exports, module) { + 'use strict'; + var Queue = require('./queue'); + var CompletionQueue = function () { + Queue.apply(this, arguments); + this.flushCount = 0; + }; + CompletionQueue.prototype = Object.create(Queue.prototype); + CompletionQueue.prototype.constructor = CompletionQueue; + CompletionQueue.prototype.flush = function () { + if (this.flushCount === 0) { + this.flushCount++; + while (this.index < this.tasks.length) { + var task = this.tasks[this.index++]; + task.fn.apply(task.context, task.args); + } + this.index = 0; + this.tasks = []; + this.flushCount--; + this.callbacks.onComplete(this); + } + }; + module.exports = CompletionQueue; +}); +/*can-queues@1.3.2#sorted-index-by*/ +define('can-queues@1.3.2#sorted-index-by', function (require, exports, module) { + module.exports = function (compare, array, value) { + if (!array || !array.length) { + return undefined; + } + if (compare(value, array[0]) === -1) { + return 0; + } else if (compare(value, array[array.length - 1]) === 1) { + return array.length; + } + var low = 0, high = array.length; + while (low < high) { + var mid = low + high >>> 1, item = array[mid], computed = compare(value, item); + if (computed === -1) { + high = mid; + } else { + low = mid + 1; + } + } + return high; + }; +}); +/*can-queues@1.3.2#element-sort*/ +define('can-queues@1.3.2#element-sort', function (require, exports, module) { + var hasDuplicate, sortInput, sortStable = true, indexOf = Array.prototype.indexOf; + function sortOrder(a, b) { + if (a === b) { + hasDuplicate = true; + return 0; + } + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if (compare) { + return compare; + } + compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1; + if (compare & 1) { + if (a === document || a.ownerDocument === document && document.documentElement.contains(a)) { + return -1; + } + if (b === document || b.ownerDocument === document && document.documentElement.contains(b)) { + return 1; + } + return sortInput ? indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 0; + } + return compare & 4 ? -1 : 1; + } + function uniqueSort(results) { + var elem, duplicates = [], j = 0, i = 0; + hasDuplicate = false; + sortInput = !sortStable && results.slice(0); + results.sort(sortOrder); + if (hasDuplicate) { + while (elem = results[i++]) { + if (elem === results[i]) { + j = duplicates.push(i); + } + } + while (j--) { + results.splice(duplicates[j], 1); + } + } + sortInput = null; + return results; + } + module.exports = { + uniqueSort: uniqueSort, + sortOrder: sortOrder + }; +}); +/*can-queues@1.3.2#dom-order-queue*/ +define('can-queues@1.3.2#dom-order-queue', [ + 'require', + 'exports', + 'module', + './queue', + './sorted-index-by', + './element-sort', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Queue = require('./queue'); + var sortedIndexBy = require('./sorted-index-by'); + var elementSort = require('./element-sort'); + var canSymbol = require('can-symbol'); + var canElementSymbol = canSymbol.for('can.element'); + function sortTasks(taskA, taskB) { + return elementSort.sortOrder(taskA.meta.element, taskB.meta.element); + } + var DomOrderQueue = function () { + Queue.apply(this, arguments); + this.taskMap = new Map(); + this.unsortable = []; + this.isFlushing = false; + }; + DomOrderQueue.prototype = Object.create(Queue.prototype); + DomOrderQueue.prototype.constructor = DomOrderQueue; + DomOrderQueue.prototype.enqueue = function (fn, context, args, meta) { + var task; + if (!this.taskMap.has(fn)) { + if (!meta) { + meta = {}; + } + if (!meta.element) { + meta.element = fn[canElementSymbol]; + } + task = { + fn: fn, + context: context, + args: args, + meta: meta + }; + this.taskMap.set(fn, task); + var index = sortedIndexBy(sortTasks, this.tasks, task); + this.tasks.splice(index, 0, task); + if (this.tasks.length === 1) { + this.callbacks.onFirstTask(this); + } + } else { + task = this.taskMap.get(fn); + task.context = context; + task.args = args; + if (!meta) { + meta = {}; + } + if (!meta.element) { + meta.element = fn[canElementSymbol]; + } + task.meta = meta; + } + }; + DomOrderQueue.prototype.flush = function () { + if (this.isFlushing) { + return; + } + this.isFlushing = true; + while (this.tasks.length) { + var task = this.tasks.shift(); + this.taskMap['delete'](task.fn); + task.fn.apply(task.context, task.args); + } + this.isFlushing = false; + this.callbacks.onComplete(this); + }; + DomOrderQueue.prototype.isEnqueued = function (fn) { + return this.taskMap.has(fn); + }; + DomOrderQueue.prototype.flushQueuedTask = function (fn) { + var task = this.dequeue(fn); + if (task) { + task.fn.apply(task.context, task.args); + } + }; + DomOrderQueue.prototype.dequeue = function (fn) { + var task = this.taskMap.get(fn); + if (task) { + var index = this.tasks.indexOf(task); + if (index >= 0) { + this.tasks.splice(index, 1); + this.taskMap['delete'](task.fn); + return task; + } else { + console.warn('Task', fn, 'has already run'); + } + } + }; + DomOrderQueue.prototype.tasksRemainingCount = function () { + return this.tasks.length; + }; + module.exports = DomOrderQueue; +}); +/*can-queues@1.3.2#can-queues*/ +define('can-queues@1.3.2#can-queues', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + './queue', + './priority-queue', + './queue-state', + './completion-queue', + './dom-order-queue', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var canDev = require('can-log/dev/dev'); + var Queue = require('./queue'); + var PriorityQueue = require('./priority-queue'); + var queueState = require('./queue-state'); + var CompletionQueue = require('./completion-queue'); + var DomOrderQueue = require('./dom-order-queue'); + var ns = require('can-namespace'); + var batchStartCounter = 0; + var addedTask = false; + var isFlushing = false; + var batchNum = 0; + var batchData; + var queueNames = [ + 'notify', + 'derive', + 'domUI', + 'dom', + 'mutate' + ]; + var NOTIFY_QUEUE, DERIVE_QUEUE, DOM_UI_QUEUE, DOM_QUEUE, MUTATE_QUEUE; + NOTIFY_QUEUE = new Queue('NOTIFY', { + onComplete: function () { + DERIVE_QUEUE.flush(); + }, + onFirstTask: function () { + if (!batchStartCounter) { + NOTIFY_QUEUE.flush(); + } else { + addedTask = true; + } + } + }); + DERIVE_QUEUE = new PriorityQueue('DERIVE', { + onComplete: function () { + DOM_QUEUE.flush(); + }, + onFirstTask: function () { + addedTask = true; + } + }); + DOM_QUEUE = new DomOrderQueue('DOM ', { + onComplete: function () { + DOM_UI_QUEUE.flush(); + }, + onFirstTask: function () { + addedTask = true; + } + }); + DOM_UI_QUEUE = new CompletionQueue('DOM_UI', { + onComplete: function () { + MUTATE_QUEUE.flush(); + }, + onFirstTask: function () { + addedTask = true; + } + }); + MUTATE_QUEUE = new Queue('MUTATE', { + onComplete: function () { + queueState.lastTask = null; + isFlushing = false; + }, + onFirstTask: function () { + addedTask = true; + } + }); + var queues = { + Queue: Queue, + PriorityQueue: PriorityQueue, + CompletionQueue: CompletionQueue, + DomOrderQueue: DomOrderQueue, + notifyQueue: NOTIFY_QUEUE, + deriveQueue: DERIVE_QUEUE, + domQueue: DOM_QUEUE, + domUIQueue: DOM_UI_QUEUE, + mutateQueue: MUTATE_QUEUE, + batch: { + start: function () { + batchStartCounter++; + if (batchStartCounter === 1) { + batchNum++; + batchData = { number: batchNum }; + } + }, + stop: function () { + batchStartCounter--; + if (batchStartCounter === 0) { + if (addedTask) { + addedTask = false; + isFlushing = true; + NOTIFY_QUEUE.flush(); + } + } + }, + isCollecting: function () { + return batchStartCounter > 0; + }, + number: function () { + return batchNum; + }, + data: function () { + return batchData; + } + }, + runAsTask: function (fn, reasonLog) { + return fn; + }, + enqueueByQueue: function enqueueByQueue(fnByQueue, context, args, makeMeta, reasonLog) { + if (fnByQueue) { + queues.batch.start(); + queueNames.forEach(function (queueName) { + var name = queueName + 'Queue'; + var QUEUE = queues[name]; + var tasks = fnByQueue[queueName]; + if (tasks !== undefined) { + tasks.forEach(function (fn) { + var meta = makeMeta != null ? makeMeta(fn, context, args) : {}; + meta.reasonLog = reasonLog; + QUEUE.enqueue(fn, context, args, meta); + }); + } + }); + queues.batch.stop(); + } + }, + lastTask: function () { + return queueState.lastTask; + }, + stack: function (task) { + var current = task || queueState.lastTask; + var stack = []; + while (current) { + stack.unshift(current); + current = current.meta.parentTask; + } + return stack; + }, + logStack: function (task) { + var stack = this.stack(task); + stack.forEach(function (task, i) { + var meta = task.meta; + if (i === 0 && meta && meta.reasonLog) { + canDev.log.apply(canDev, meta.reasonLog); + } + var log = meta && meta.log ? meta.log : [ + task.fn.name, + task + ]; + canDev.log.apply(canDev, [task.meta.stack.name + ' ran task:'].concat(log)); + }); + }, + taskCount: function () { + return NOTIFY_QUEUE.tasks.length + DERIVE_QUEUE.tasks.length + DOM_UI_QUEUE.tasks.length + MUTATE_QUEUE.tasks.length; + }, + flush: function () { + NOTIFY_QUEUE.flush(); + }, + log: function () { + NOTIFY_QUEUE.log.apply(NOTIFY_QUEUE, arguments); + DERIVE_QUEUE.log.apply(DERIVE_QUEUE, arguments); + DOM_UI_QUEUE.log.apply(DOM_UI_QUEUE, arguments); + DOM_QUEUE.log.apply(DOM_QUEUE, arguments); + MUTATE_QUEUE.log.apply(MUTATE_QUEUE, arguments); + } + }; + if (ns.queues) { + throw new Error('You can\'t have two versions of can-queues, check your dependencies'); + } else { + module.exports = ns.queues = queues; + } +}); +/*can-key-tree@1.2.2#can-key-tree*/ +define('can-key-tree@1.2.2#can-key-tree', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var reflect = require('can-reflect'); + function isBuiltInPrototype(obj) { + if (obj === Object.prototype) { + return true; + } + var protoString = Object.prototype.toString.call(obj); + var isNotObjObj = protoString !== '[object Object]'; + var isObjSomething = protoString.indexOf('[object ') !== -1; + return isNotObjObj && isObjSomething; + } + function getDeepSize(root, level) { + if (level === 0) { + return reflect.size(root); + } else if (reflect.size(root) === 0) { + return 0; + } else { + var count = 0; + reflect.each(root, function (value) { + count += getDeepSize(value, level - 1); + }); + return count; + } + } + function getDeep(node, items, depth, maxDepth) { + if (!node) { + return; + } + if (maxDepth === depth) { + if (reflect.isMoreListLikeThanMapLike(node)) { + reflect.addValues(items, reflect.toArray(node)); + } else { + throw new Error('can-key-tree: Map-type leaf containers are not supported yet.'); + } + } else { + reflect.each(node, function (value) { + getDeep(value, items, depth + 1, maxDepth); + }); + } + } + function clearDeep(node, keys, maxDepth, deleteHandler) { + if (maxDepth === keys.length) { + if (reflect.isMoreListLikeThanMapLike(node)) { + var valuesToRemove = reflect.toArray(node); + if (deleteHandler) { + valuesToRemove.forEach(function (value) { + deleteHandler.apply(null, keys.concat(value)); + }); + } + reflect.removeValues(node, valuesToRemove); + } else { + throw new Error('can-key-tree: Map-type leaf containers are not supported yet.'); + } + } else { + reflect.each(node, function (value, key) { + clearDeep(value, keys.concat(key), maxDepth, deleteHandler); + reflect.deleteKeyValue(node, key); + }); + } + } + var KeyTree = function (treeStructure, callbacks) { + var FirstConstructor = treeStructure[0]; + if (reflect.isConstructorLike(FirstConstructor)) { + this.root = new FirstConstructor(); + } else { + this.root = FirstConstructor; + } + this.callbacks = callbacks || {}; + this.treeStructure = treeStructure; + this.empty = true; + }; + reflect.assign(KeyTree.prototype, { + add: function (keys) { + if (keys.length > this.treeStructure.length) { + throw new Error('can-key-tree: Can not add path deeper than tree.'); + } + var place = this.root; + var rootWasEmpty = this.empty === true; + for (var i = 0; i < keys.length - 1; i++) { + var key = keys[i]; + var childNode = reflect.getKeyValue(place, key); + if (!childNode) { + var Constructor = this.treeStructure[i + 1]; + if (isBuiltInPrototype(Constructor.prototype)) { + childNode = new Constructor(); + } else { + childNode = new Constructor(key); + } + reflect.setKeyValue(place, key, childNode); + } + place = childNode; + } + if (reflect.isMoreListLikeThanMapLike(place)) { + reflect.addValues(place, [keys[keys.length - 1]]); + } else { + throw new Error('can-key-tree: Map types are not supported yet.'); + } + if (rootWasEmpty) { + this.empty = false; + if (this.callbacks.onFirst) { + this.callbacks.onFirst.call(this); + } + } + return this; + }, + getNode: function (keys) { + var node = this.root; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + node = reflect.getKeyValue(node, key); + if (!node) { + return; + } + } + return node; + }, + get: function (keys) { + var node = this.getNode(keys); + if (this.treeStructure.length === keys.length) { + return node; + } else { + var Type = this.treeStructure[this.treeStructure.length - 1]; + var items = new Type(); + getDeep(node, items, keys.length, this.treeStructure.length - 1); + return items; + } + }, + delete: function (keys, deleteHandler) { + var parentNode = this.root, path = [this.root], lastKey = keys[keys.length - 1]; + for (var i = 0; i < keys.length - 1; i++) { + var key = keys[i]; + var childNode = reflect.getKeyValue(parentNode, key); + if (childNode === undefined) { + return false; + } else { + path.push(childNode); + } + parentNode = childNode; + } + if (!keys.length) { + clearDeep(parentNode, [], this.treeStructure.length - 1, deleteHandler); + } else if (keys.length === this.treeStructure.length) { + if (reflect.isMoreListLikeThanMapLike(parentNode)) { + if (deleteHandler) { + deleteHandler.apply(null, keys.concat(lastKey)); + } + reflect.removeValues(parentNode, [lastKey]); + } else { + throw new Error('can-key-tree: Map types are not supported yet.'); + } + } else { + var nodeToRemove = reflect.getKeyValue(parentNode, lastKey); + if (nodeToRemove !== undefined) { + clearDeep(nodeToRemove, keys, this.treeStructure.length - 1, deleteHandler); + reflect.deleteKeyValue(parentNode, lastKey); + } else { + return false; + } + } + for (i = path.length - 2; i >= 0; i--) { + if (reflect.size(parentNode) === 0) { + parentNode = path[i]; + reflect.deleteKeyValue(parentNode, keys[i]); + } else { + break; + } + } + if (reflect.size(this.root) === 0) { + this.empty = true; + if (this.callbacks.onEmpty) { + this.callbacks.onEmpty.call(this); + } + } + return true; + }, + size: function () { + return getDeepSize(this.root, this.treeStructure.length - 1); + }, + isEmpty: function () { + return this.empty; + } + }); + module.exports = KeyTree; +}); +/*can-reflect-promise@2.2.1#can-reflect-promise*/ +define('can-reflect-promise@2.2.1#can-reflect-promise', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + 'can-observation-recorder', + 'can-queues', + 'can-key-tree', + 'can-log/dev/dev' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var ObservationRecorder = require('can-observation-recorder'); + var queues = require('can-queues'); + var KeyTree = require('can-key-tree'); + var dev = require('can-log/dev/dev'); + var getKeyValueSymbol = canSymbol.for('can.getKeyValue'), observeDataSymbol = canSymbol.for('can.meta'); + var promiseDataPrototype = { + isPending: true, + state: 'pending', + isResolved: false, + isRejected: false, + value: undefined, + reason: undefined + }; + function setVirtualProp(promise, property, value) { + var observeData = promise[observeDataSymbol]; + var old = observeData[property]; + observeData[property] = value; + queues.enqueueByQueue(observeData.handlers.getNode([property]), promise, [ + value, + old + ], function () { + return {}; + }, [ + 'Promise', + promise, + 'resolved with value', + value, + 'and changed virtual property: ' + property + ]); + } + function initPromise(promise) { + var observeData = promise[observeDataSymbol]; + if (!observeData) { + Object.defineProperty(promise, observeDataSymbol, { + enumerable: false, + configurable: false, + writable: false, + value: Object.create(promiseDataPrototype) + }); + observeData = promise[observeDataSymbol]; + observeData.handlers = new KeyTree([ + Object, + Object, + Array + ]); + } + promise.then(function (value) { + queues.batch.start(); + setVirtualProp(promise, 'isPending', false); + setVirtualProp(promise, 'isResolved', true); + setVirtualProp(promise, 'value', value); + setVirtualProp(promise, 'state', 'resolved'); + queues.batch.stop(); + }, function (reason) { + queues.batch.start(); + setVirtualProp(promise, 'isPending', false); + setVirtualProp(promise, 'isRejected', true); + setVirtualProp(promise, 'reason', reason); + setVirtualProp(promise, 'state', 'rejected'); + queues.batch.stop(); + }); + } + function setupPromise(value) { + var oldPromiseFn; + var proto = 'getPrototypeOf' in Object ? Object.getPrototypeOf(value) : value.__proto__; + if (value[getKeyValueSymbol] && value[observeDataSymbol]) { + return; + } + if (proto === null || proto === Object.prototype) { + proto = value; + if (typeof proto.promise === 'function') { + oldPromiseFn = proto.promise; + proto.promise = function () { + var result = oldPromiseFn.call(proto); + setupPromise(result); + return result; + }; + } + } + canReflect.assignSymbols(proto, { + 'can.getKeyValue': function (key) { + if (!this[observeDataSymbol]) { + initPromise(this); + } + ObservationRecorder.add(this, key); + switch (key) { + case 'state': + case 'isPending': + case 'isResolved': + case 'isRejected': + case 'value': + case 'reason': + return this[observeDataSymbol][key]; + default: + return this[key]; + } + }, + 'can.getValue': function () { + return this[getKeyValueSymbol]('value'); + }, + 'can.isValueLike': false, + 'can.onKeyValue': function (key, handler, queue) { + if (!this[observeDataSymbol]) { + initPromise(this); + } + this[observeDataSymbol].handlers.add([ + key, + queue || 'mutate', + handler + ]); + }, + 'can.offKeyValue': function (key, handler, queue) { + if (!this[observeDataSymbol]) { + initPromise(this); + } + this[observeDataSymbol].handlers.delete([ + key, + queue || 'mutate', + handler + ]); + }, + 'can.hasOwnKey': function (key) { + if (!this[observeDataSymbol]) { + initPromise(this); + } + return key in this[observeDataSymbol]; + } + }); + } + module.exports = setupPromise; +}); +/*can-stache-key@1.4.3#can-stache-key*/ +define('can-stache-key@1.4.3#can-stache-key', [ + 'require', + 'exports', + 'module', + 'can-observation-recorder', + 'can-log/dev/dev', + 'can-symbol', + 'can-reflect', + 'can-reflect-promise' +], function (require, exports, module) { + 'use strict'; + var ObservationRecorder = require('can-observation-recorder'); + var dev = require('can-log/dev/dev'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var canReflectPromise = require('can-reflect-promise'); + var getValueSymbol = canSymbol.for('can.getValue'); + var setValueSymbol = canSymbol.for('can.setValue'); + var isValueLikeSymbol = canSymbol.for('can.isValueLike'); + var peek = ObservationRecorder.ignore(canReflect.getKeyValue.bind(canReflect)); + var observeReader; + var isPromiseLike = ObservationRecorder.ignore(function isPromiseLike(value) { + return typeof value === 'object' && value && typeof value.then === 'function'; + }); + var bindName = Function.prototype.bind; + var isAt = function (index, reads) { + var prevRead = reads[index - 1]; + return prevRead && prevRead.at; + }; + var readValue = function (value, index, reads, options, state, prev) { + var usedValueReader; + do { + usedValueReader = false; + for (var i = 0, len = observeReader.valueReaders.length; i < len; i++) { + if (observeReader.valueReaders[i].test(value, index, reads, options)) { + value = observeReader.valueReaders[i].read(value, index, reads, options, state, prev); + } + } + } while (usedValueReader); + return value; + }; + var specialRead = { + index: true, + key: true, + event: true, + element: true, + viewModel: true + }; + var checkForObservableAndNotify = function (options, state, getObserves, value, index) { + if (options.foundObservable && !state.foundObservable) { + if (ObservationRecorder.trapsCount()) { + ObservationRecorder.addMany(getObserves()); + options.foundObservable(value, index); + state.foundObservable = true; + } + } + }; + var objHasKeyAtIndex = function (obj, reads, index) { + return !!(reads && reads.length && canReflect.hasKey(obj, reads[index].key)); + }; + observeReader = { + read: function (parent, reads, options) { + options = options || {}; + var state = { foundObservable: false }; + var getObserves; + if (options.foundObservable) { + getObserves = ObservationRecorder.trap(); + } + var cur = readValue(parent, 0, reads, options, state), type, prev, readLength = reads.length, i = 0, last, parentHasKey; + checkForObservableAndNotify(options, state, getObserves, parent, 0); + while (i < readLength) { + prev = cur; + for (var r = 0, readersLength = observeReader.propertyReaders.length; r < readersLength; r++) { + var reader = observeReader.propertyReaders[r]; + if (reader.test(cur)) { + cur = reader.read(cur, reads[i], i, options, state); + break; + } + } + checkForObservableAndNotify(options, state, getObserves, prev, i); + last = cur; + i = i + 1; + cur = readValue(cur, i, reads, options, state, prev); + checkForObservableAndNotify(options, state, getObserves, prev, i - 1); + type = typeof cur; + if (i < reads.length && (cur === null || cur === undefined)) { + parentHasKey = objHasKeyAtIndex(prev, reads, i - 1); + if (options.earlyExit && !parentHasKey) { + options.earlyExit(prev, i - 1, cur); + } + return { + value: undefined, + parent: prev, + parentHasKey: parentHasKey, + foundLastParent: false + }; + } + } + parentHasKey = objHasKeyAtIndex(prev, reads, reads.length - 1); + if (cur === undefined && !parentHasKey) { + if (options.earlyExit) { + options.earlyExit(prev, i - 1); + } + } + return { + value: cur, + parent: prev, + parentHasKey: parentHasKey, + foundLastParent: true + }; + }, + get: function (parent, reads, options) { + return observeReader.read(parent, observeReader.reads(reads), options || {}).value; + }, + valueReadersMap: {}, + valueReaders: [ + { + name: 'function', + test: function (value) { + return value && canReflect.isFunctionLike(value) && !canReflect.isConstructorLike(value); + }, + read: function (value, i, reads, options, state, prev) { + if (options.callMethodsOnObservables && canReflect.isObservableLike(prev) && canReflect.isMapLike(prev)) { + dev.warn('can-stache-key: read() called with `callMethodsOnObservables: true`.'); + return value.apply(prev, options.args || []); + } + return options.proxyMethods !== false ? bindName.call(value, prev) : value; + } + }, + { + name: 'isValueLike', + test: function (value, i, reads, options) { + return value && value[getValueSymbol] && value[isValueLikeSymbol] !== false && (options.foundAt || !isAt(i, reads)); + }, + read: function (value, i, reads, options) { + if (options.readCompute === false && i === reads.length) { + return value; + } + return canReflect.getValue(value); + }, + write: function (base, newVal) { + if (base[setValueSymbol]) { + base[setValueSymbol](newVal); + } else if (base.set) { + base.set(newVal); + } else { + base(newVal); + } + } + } + ], + propertyReadersMap: {}, + propertyReaders: [ + { + name: 'map', + test: function (value) { + if (canReflect.isPromise(value) || isPromiseLike(value)) { + canReflectPromise(value); + } + return canReflect.isObservableLike(value) && canReflect.isMapLike(value); + }, + read: function (value, prop) { + var res = canReflect.getKeyValue(value, prop.key); + if (res !== undefined) { + return res; + } else { + return value[prop.key]; + } + }, + write: canReflect.setKeyValue + }, + { + name: 'object', + test: function () { + return true; + }, + read: function (value, prop, i, options) { + if (value == null) { + return undefined; + } else { + if (typeof value === 'object') { + if (prop.key in value) { + return value[prop.key]; + } + } else { + return value[prop.key]; + } + } + }, + write: function (base, prop, newVal) { + var propValue = base[prop]; + if (newVal != null && typeof newVal === 'object' && canReflect.isMapLike(propValue)) { + dev.warn('can-stache-key: Merging data into "' + prop + '" because its parent is non-observable'); + canReflect.update(propValue, newVal); + } else if (propValue != null && propValue[setValueSymbol] !== undefined) { + canReflect.setValue(propValue, newVal); + } else { + base[prop] = newVal; + } + } + } + ], + reads: function (keyArg) { + var key = '' + keyArg; + var keys = []; + var last = 0; + var at = false; + if (key.charAt(0) === '@') { + last = 1; + at = true; + } + var keyToAdd = ''; + for (var i = last; i < key.length; i++) { + var character = key.charAt(i); + if (character === '.' || character === '@') { + if (key.charAt(i - 1) !== '\\') { + keys.push({ + key: keyToAdd, + at: at + }); + at = character === '@'; + keyToAdd = ''; + } else { + keyToAdd = keyToAdd.substr(0, keyToAdd.length - 1) + '.'; + } + } else { + keyToAdd += character; + } + } + keys.push({ + key: keyToAdd, + at: at + }); + return keys; + }, + write: function (parent, key, value, options) { + var keys = typeof key === 'string' ? observeReader.reads(key) : key; + var last; + options = options || {}; + if (keys.length > 1) { + last = keys.pop(); + parent = observeReader.read(parent, keys, options).value; + keys.push(last); + } else { + last = keys[0]; + } + if (!parent) { + return; + } + var keyValue = peek(parent, last.key); + if (observeReader.valueReadersMap.isValueLike.test(keyValue, keys.length - 1, keys, options)) { + observeReader.valueReadersMap.isValueLike.write(keyValue, value, options); + } else { + if (observeReader.valueReadersMap.isValueLike.test(parent, keys.length - 1, keys, options)) { + parent = parent[getValueSymbol](); + } + if (observeReader.propertyReadersMap.map.test(parent)) { + observeReader.propertyReadersMap.map.write(parent, last.key, value, options); + } else if (observeReader.propertyReadersMap.object.test(parent)) { + observeReader.propertyReadersMap.object.write(parent, last.key, value, options); + if (options.observation) { + options.observation.update(); + } + } + } + } + }; + observeReader.propertyReaders.forEach(function (reader) { + observeReader.propertyReadersMap[reader.name] = reader; + }); + observeReader.valueReaders.forEach(function (reader) { + observeReader.valueReadersMap[reader.name] = reader; + }); + observeReader.set = observeReader.write; + module.exports = observeReader; +}); +/*can-string@1.1.0#can-string*/ +define('can-string@1.1.0#can-string', function (require, exports, module) { + 'use strict'; + var strUndHash = /_|-/, strColons = /\=\=/, strWords = /([A-Z]+)([A-Z][a-z])/g, strLowUp = /([a-z\d])([A-Z])/g, strDash = /([a-z\d])([A-Z])/g, strQuote = /"/g, strSingleQuote = /'/g, strHyphenMatch = /-+(.)?/g, strCamelMatch = /[a-z][A-Z]/g, convertBadValues = function (content) { + var isInvalid = content === null || content === undefined || isNaN(content) && '' + content === 'NaN'; + return '' + (isInvalid ? '' : content); + }; + var string = { + esc: function (content) { + return convertBadValues(content).replace(/&/g, '&').replace(//g, '>').replace(strQuote, '"').replace(strSingleQuote, '''); + }, + capitalize: function (s) { + return s.charAt(0).toUpperCase() + s.slice(1); + }, + camelize: function (str) { + return convertBadValues(str).replace(strHyphenMatch, function (match, chr) { + return chr ? chr.toUpperCase() : ''; + }); + }, + hyphenate: function (str) { + return convertBadValues(str).replace(strCamelMatch, function (str) { + return str.charAt(0) + '-' + str.charAt(1).toLowerCase(); + }); + }, + pascalize: function (str) { + return string.capitalize(string.camelize(str)); + }, + underscore: function (s) { + return s.replace(strColons, '/').replace(strWords, '$1_$2').replace(strLowUp, '$1_$2').replace(strDash, '_').toLowerCase(); + }, + undHash: strUndHash + }; + module.exports = string; +}); +/*can-construct@3.5.6#can-construct*/ +define('can-construct@3.5.6#can-construct', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-log/dev/dev', + 'can-namespace', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var dev = require('can-log/dev/dev'); + var namespace = require('can-namespace'); + var canSymbol = require('can-symbol'); + var inSetupSymbol = canSymbol.for('can.initializing'); + var initializing = 0; + var Construct = function () { + if (arguments.length) { + return Construct.extend.apply(Construct, arguments); + } + }; + var canGetDescriptor; + try { + Object.getOwnPropertyDescriptor({}); + canGetDescriptor = true; + } catch (e) { + canGetDescriptor = false; + } + var getDescriptor = function (newProps, name) { + var descriptor = Object.getOwnPropertyDescriptor(newProps, name); + if (descriptor && (descriptor.get || descriptor.set)) { + return descriptor; + } + return null; + }, inheritGetterSetter = function (newProps, oldProps, addTo) { + addTo = addTo || newProps; + var descriptor; + for (var name in newProps) { + if (descriptor = getDescriptor(newProps, name)) { + this._defineProperty(addTo, oldProps, name, descriptor); + } else { + Construct._overwrite(addTo, oldProps, name, newProps[name]); + } + } + }, simpleInherit = function (newProps, oldProps, addTo) { + addTo = addTo || newProps; + for (var name in newProps) { + Construct._overwrite(addTo, oldProps, name, newProps[name]); + } + }, defineNonEnumerable = function (obj, prop, value) { + Object.defineProperty(obj, prop, { + configurable: true, + writable: true, + enumerable: false, + value: value + }); + }; + canReflect.assignMap(Construct, { + constructorExtends: true, + newInstance: function () { + var inst = this.instance(), args; + if (inst.setup) { + Object.defineProperty(inst, '__inSetup', { + configurable: true, + enumerable: false, + value: true, + writable: true + }); + Object.defineProperty(inst, inSetupSymbol, { + configurable: true, + enumerable: false, + value: true, + writable: true + }); + args = inst.setup.apply(inst, arguments); + if (args instanceof Construct.ReturnValue) { + return args.value; + } + inst.__inSetup = false; + inst[inSetupSymbol] = false; + } + if (inst.init) { + inst.init.apply(inst, args || arguments); + } + return inst; + }, + _inherit: canGetDescriptor ? inheritGetterSetter : simpleInherit, + _defineProperty: function (what, oldProps, propName, descriptor) { + Object.defineProperty(what, propName, descriptor); + }, + _overwrite: function (what, oldProps, propName, val) { + Object.defineProperty(what, propName, { + value: val, + configurable: true, + enumerable: true, + writable: true + }); + }, + setup: function (base) { + var defaults = base.defaults ? canReflect.serialize(base.defaults) : {}; + this.defaults = canReflect.assignDeepMap(defaults, this.defaults); + }, + instance: function () { + initializing = 1; + var inst = new this(); + initializing = 0; + return inst; + }, + extend: function (name, staticProperties, instanceProperties) { + var shortName = name, klass = staticProperties, proto = instanceProperties; + if (typeof shortName !== 'string') { + proto = klass; + klass = shortName; + shortName = null; + } + if (!proto) { + proto = klass; + klass = null; + } + proto = proto || {}; + var _super_class = this, _super = this.prototype, Constructor, prototype; + prototype = this.instance(); + Construct._inherit(proto, _super, prototype); + if (shortName) { + } else if (klass && klass.shortName) { + shortName = klass.shortName; + } else if (this.shortName) { + shortName = this.shortName; + } + function init() { + if (!initializing) { + return (!this || this.constructor !== Constructor) && arguments.length && Constructor.constructorExtends ? Constructor.extend.apply(Constructor, arguments) : Constructor.newInstance.apply(Constructor, arguments); + } + } + Constructor = typeof namedCtor === 'function' ? namedCtor(constructorName, init) : function () { + return init.apply(this, arguments); + }; + for (var propName in _super_class) { + if (_super_class.hasOwnProperty(propName)) { + Constructor[propName] = _super_class[propName]; + } + } + Construct._inherit(klass, _super_class, Constructor); + canReflect.assignMap(Constructor, { + constructor: Constructor, + prototype: prototype + }); + if (shortName !== undefined) { + if (Object.getOwnPropertyDescriptor) { + var desc = Object.getOwnPropertyDescriptor(Constructor, 'name'); + if (!desc || desc.configurable) { + Object.defineProperty(Constructor, 'name', { + writable: true, + value: shortName, + configurable: true + }); + } + } + Constructor.shortName = shortName; + } + defineNonEnumerable(Constructor.prototype, 'constructor', Constructor); + var t = [_super_class].concat(Array.prototype.slice.call(arguments)), args = Constructor.setup.apply(Constructor, t); + if (Constructor.init) { + Constructor.init.apply(Constructor, args || t); + } + return Constructor; + }, + ReturnValue: function (value) { + this.value = value; + } + }); + defineNonEnumerable(Construct.prototype, 'setup', function () { + }); + defineNonEnumerable(Construct.prototype, 'init', function () { + }); + module.exports = namespace.Construct = Construct; +}); +/*can-globals@1.2.2#can-globals-proto*/ +define('can-globals@1.2.2#can-globals-proto', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function dispatch(key) { + var handlers = this.eventHandlers[key]; + if (handlers) { + var handlersCopy = handlers.slice(); + var value = this.getKeyValue(key); + for (var i = 0; i < handlersCopy.length; i++) { + handlersCopy[i](value); + } + } + } + function Globals() { + this.eventHandlers = {}; + this.properties = {}; + } + Globals.prototype.define = function (key, value, enableCache) { + if (enableCache === undefined) { + enableCache = true; + } + if (!this.properties[key]) { + this.properties[key] = { + default: value, + value: value, + enableCache: enableCache + }; + } + return this; + }; + Globals.prototype.getKeyValue = function (key) { + var property = this.properties[key]; + if (property) { + if (typeof property.value === 'function') { + if (property.cachedValue) { + return property.cachedValue; + } + if (property.enableCache) { + property.cachedValue = property.value(); + return property.cachedValue; + } else { + return property.value(); + } + } + return property.value; + } + }; + Globals.prototype.makeExport = function (key) { + return function (value) { + if (arguments.length === 0) { + return this.getKeyValue(key); + } + if (typeof value === 'undefined' || value === null) { + this.deleteKeyValue(key); + } else { + if (typeof value === 'function') { + this.setKeyValue(key, function () { + return value; + }); + } else { + this.setKeyValue(key, value); + } + return value; + } + }.bind(this); + }; + Globals.prototype.offKeyValue = function (key, handler) { + if (this.properties[key]) { + var handlers = this.eventHandlers[key]; + if (handlers) { + var i = handlers.indexOf(handler); + handlers.splice(i, 1); + } + } + return this; + }; + Globals.prototype.onKeyValue = function (key, handler) { + if (this.properties[key]) { + if (!this.eventHandlers[key]) { + this.eventHandlers[key] = []; + } + this.eventHandlers[key].push(handler); + } + return this; + }; + Globals.prototype.deleteKeyValue = function (key) { + var property = this.properties[key]; + if (property !== undefined) { + property.value = property.default; + property.cachedValue = undefined; + dispatch.call(this, key); + } + return this; + }; + Globals.prototype.setKeyValue = function (key, value) { + if (!this.properties[key]) { + return this.define(key, value); + } + var property = this.properties[key]; + property.value = value; + property.cachedValue = undefined; + dispatch.call(this, key); + return this; + }; + Globals.prototype.reset = function () { + for (var key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + this.properties[key].value = this.properties[key].default; + this.properties[key].cachedValue = undefined; + dispatch.call(this, key); + } + } + return this; + }; + canReflect.assignSymbols(Globals.prototype, { + 'can.getKeyValue': Globals.prototype.getKeyValue, + 'can.setKeyValue': Globals.prototype.setKeyValue, + 'can.deleteKeyValue': Globals.prototype.deleteKeyValue, + 'can.onKeyValue': Globals.prototype.onKeyValue, + 'can.offKeyValue': Globals.prototype.offKeyValue + }); + module.exports = Globals; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#can-globals-instance*/ +define('can-globals@1.2.2#can-globals-instance', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './can-globals-proto' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var Globals = require('./can-globals-proto'); + var globals = new Globals(); + if (namespace.globals) { + throw new Error('You can\'t have two versions of can-globals, check your dependencies'); + } else { + module.exports = namespace.globals = globals; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#global/global*/ +define('can-globals@1.2.2#global/global', [ + 'require', + 'exports', + 'module', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals/can-globals-instance'); + globals.define('global', function () { + return typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope ? self : typeof process === 'object' && {}.toString.call(process) === '[object process]' ? global : window; + }); + module.exports = globals.makeExport('global'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#document/document*/ +define('can-globals@1.2.2#document/document', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + require('can-globals/global/global'); + var globals = require('can-globals/can-globals-instance'); + globals.define('document', function () { + return globals.getKeyValue('global').document; + }); + module.exports = globals.makeExport('document'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#is-node/is-node*/ +define('can-globals@1.2.2#is-node/is-node', [ + 'require', + 'exports', + 'module', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals/can-globals-instance'); + globals.define('isNode', function () { + return typeof process === 'object' && {}.toString.call(process) === '[object process]'; + }); + module.exports = globals.makeExport('isNode'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#is-browser-window/is-browser-window*/ +define('can-globals@1.2.2#is-browser-window/is-browser-window', [ + 'require', + 'exports', + 'module', + 'can-globals/can-globals-instance', + '../is-node/is-node' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals/can-globals-instance'); + require('../is-node/is-node'); + globals.define('isBrowserWindow', function () { + var isNode = globals.getKeyValue('isNode'); + return typeof window !== 'undefined' && typeof document !== 'undefined' && isNode === false; + }); + module.exports = globals.makeExport('isBrowserWindow'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-events@1.3.11#helpers/util*/ +define('can-dom-events@1.3.11#helpers/util', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-globals/is-browser-window/is-browser-window' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getCurrentDocument = require('can-globals/document/document'); + var isBrowserWindow = require('can-globals/is-browser-window/is-browser-window'); + function getTargetDocument(target) { + return target.ownerDocument || getCurrentDocument(); + } + function createEvent(target, eventData, bubbles, cancelable) { + var doc = getTargetDocument(target); + var event = doc.createEvent('HTMLEvents'); + var eventType; + if (typeof eventData === 'string') { + eventType = eventData; + } else { + eventType = eventData.type; + for (var prop in eventData) { + if (event[prop] === undefined) { + event[prop] = eventData[prop]; + } + } + } + if (bubbles === undefined) { + bubbles = true; + } + event.initEvent(eventType, bubbles, cancelable); + return event; + } + function isDomEventTarget(obj) { + if (!(obj && obj.nodeName)) { + return obj === window; + } + var nodeType = obj.nodeType; + return nodeType === 1 || nodeType === 9 || nodeType === 11; + } + function addDomContext(context, args) { + if (isDomEventTarget(context)) { + args = Array.prototype.slice.call(args, 0); + args.unshift(context); + } + return args; + } + function removeDomContext(context, args) { + if (!isDomEventTarget(context)) { + args = Array.prototype.slice.call(args, 0); + context = args.shift(); + } + return { + context: context, + args: args + }; + } + var fixSyntheticEventsOnDisabled = false; + (function () { + if (!isBrowserWindow()) { + return; + } + var testEventName = 'fix_synthetic_events_on_disabled_test'; + var input = document.createElement('input'); + input.disabled = true; + var timer = setTimeout(function () { + fixSyntheticEventsOnDisabled = true; + }, 50); + var onTest = function onTest() { + clearTimeout(timer); + input.removeEventListener(testEventName, onTest); + }; + input.addEventListener(testEventName, onTest); + try { + var event = document.create('HTMLEvents'); + event.initEvent(testEventName, false); + input.dispatchEvent(event); + } catch (e) { + onTest(); + fixSyntheticEventsOnDisabled = true; + } + }()); + function isDispatchingOnDisabled(element, event) { + var eventType = event.type; + var isInsertedOrRemoved = eventType === 'inserted' || eventType === 'removed'; + var isDisabled = !!element.disabled; + return isInsertedOrRemoved && isDisabled; + } + function forceEnabledForDispatch(element, event) { + return fixSyntheticEventsOnDisabled && isDispatchingOnDisabled(element, event); + } + module.exports = { + createEvent: createEvent, + addDomContext: addDomContext, + removeDomContext: removeDomContext, + isDomEventTarget: isDomEventTarget, + getTargetDocument: getTargetDocument, + forceEnabledForDispatch: forceEnabledForDispatch + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-events@1.3.11#helpers/make-event-registry*/ +define('can-dom-events@1.3.11#helpers/make-event-registry', function (require, exports, module) { + 'use strict'; + function EventRegistry() { + this._registry = {}; + } + module.exports = function makeEventRegistry() { + return new EventRegistry(); + }; + EventRegistry.prototype.has = function (eventType) { + return !!this._registry[eventType]; + }; + EventRegistry.prototype.get = function (eventType) { + return this._registry[eventType]; + }; + EventRegistry.prototype.add = function (event, eventType) { + if (!event) { + throw new Error('An EventDefinition must be provided'); + } + if (typeof event.addEventListener !== 'function') { + throw new TypeError('EventDefinition addEventListener must be a function'); + } + if (typeof event.removeEventListener !== 'function') { + throw new TypeError('EventDefinition removeEventListener must be a function'); + } + eventType = eventType || event.defaultEventType; + if (typeof eventType !== 'string') { + throw new TypeError('Event type must be a string, not ' + eventType); + } + if (this.has(eventType)) { + throw new Error('Event "' + eventType + '" is already registered'); + } + this._registry[eventType] = event; + var self = this; + return function remove() { + self._registry[eventType] = undefined; + }; + }; +}); +/*can-dom-events@1.3.11#helpers/-make-delegate-event-tree*/ +define('can-dom-events@1.3.11#helpers/-make-delegate-event-tree', [ + 'require', + 'exports', + 'module', + 'can-key-tree', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var KeyTree = require('can-key-tree'); + var canReflect = require('can-reflect'); + var useCapture = function (eventType) { + return eventType === 'focus' || eventType === 'blur'; + }; + function makeDelegator(domEvents) { + var Delegator = function Delegator(parentKey) { + this.element = parentKey; + this.events = {}; + this.delegated = {}; + }; + canReflect.assignSymbols(Delegator.prototype, { + 'can.setKeyValue': function (eventType, handlersBySelector) { + var handler = this.delegated[eventType] = function (ev) { + var cur = ev.target; + var propagate = true; + var origStopPropagation = ev.stopPropagation; + ev.stopPropagation = function () { + origStopPropagation.apply(this, arguments); + propagate = false; + }; + var origStopImmediatePropagation = ev.stopImmediatePropagation; + ev.stopImmediatePropagation = function () { + origStopImmediatePropagation.apply(this, arguments); + propagate = false; + }; + do { + var el = cur === document ? document.documentElement : cur; + var matches = el.matches || el.msMatchesSelector; + canReflect.each(handlersBySelector, function (handlers, selector) { + if (matches && matches.call(el, selector)) { + handlers.forEach(function (handler) { + handler.call(el, ev); + }); + } + }); + cur = cur.parentNode; + } while (cur && cur !== ev.currentTarget && propagate); + }; + this.events[eventType] = handlersBySelector; + domEvents.addEventListener(this.element, eventType, handler, useCapture(eventType)); + }, + 'can.getKeyValue': function (eventType) { + return this.events[eventType]; + }, + 'can.deleteKeyValue': function (eventType) { + domEvents.removeEventListener(this.element, eventType, this.delegated[eventType], useCapture(eventType)); + delete this.delegated[eventType]; + delete this.events[eventType]; + }, + 'can.getOwnEnumerableKeys': function () { + return Object.keys(this.events); + } + }); + return Delegator; + } + module.exports = function makeDelegateEventTree(domEvents) { + var Delegator = makeDelegator(domEvents); + return new KeyTree([ + Map, + Delegator, + Object, + Array + ]); + }; +}); +/*can-dom-events@1.3.11#can-dom-events*/ +define('can-dom-events@1.3.11#can-dom-events', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './helpers/util', + './helpers/make-event-registry', + './helpers/-make-delegate-event-tree' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var util = require('./helpers/util'); + var makeEventRegistry = require('./helpers/make-event-registry'); + var makeDelegateEventTree = require('./helpers/-make-delegate-event-tree'); + var domEvents = { + _eventRegistry: makeEventRegistry(), + addEvent: function (event, eventType) { + return this._eventRegistry.add(event, eventType); + }, + addEventListener: function (target, eventType) { + var hasCustomEvent = domEvents._eventRegistry.has(eventType); + if (hasCustomEvent) { + var event = domEvents._eventRegistry.get(eventType); + return event.addEventListener.apply(domEvents, arguments); + } + var eventArgs = Array.prototype.slice.call(arguments, 1); + return target.addEventListener.apply(target, eventArgs); + }, + removeEventListener: function (target, eventType) { + var hasCustomEvent = domEvents._eventRegistry.has(eventType); + if (hasCustomEvent) { + var event = domEvents._eventRegistry.get(eventType); + return event.removeEventListener.apply(domEvents, arguments); + } + var eventArgs = Array.prototype.slice.call(arguments, 1); + return target.removeEventListener.apply(target, eventArgs); + }, + addDelegateListener: function (root, eventType, selector, handler) { + domEvents._eventTree.add([ + root, + eventType, + selector, + handler + ]); + }, + removeDelegateListener: function (target, eventType, selector, handler) { + domEvents._eventTree.delete([ + target, + eventType, + selector, + handler + ]); + }, + dispatch: function (target, eventData, bubbles, cancelable) { + var event = util.createEvent(target, eventData, bubbles, cancelable); + var enableForDispatch = util.forceEnabledForDispatch(target, event); + if (enableForDispatch) { + target.disabled = false; + } + var ret = target.dispatchEvent(event); + if (enableForDispatch) { + target.disabled = true; + } + return ret; + } + }; + domEvents._eventTree = makeDelegateEventTree(domEvents); + module.exports = namespace.domEvents = domEvents; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-event-queue@1.1.8#dependency-record/merge*/ +define('can-event-queue@1.1.8#dependency-record/merge', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var mergeValueDependencies = function mergeValueDependencies(obj, source) { + var sourceValueDeps = source.valueDependencies; + if (sourceValueDeps) { + var destValueDeps = obj.valueDependencies; + if (!destValueDeps) { + destValueDeps = new Set(); + obj.valueDependencies = destValueDeps; + } + canReflect.eachIndex(sourceValueDeps, function (dep) { + destValueDeps.add(dep); + }); + } + }; + var mergeKeyDependencies = function mergeKeyDependencies(obj, source) { + var sourcekeyDeps = source.keyDependencies; + if (sourcekeyDeps) { + var destKeyDeps = obj.keyDependencies; + if (!destKeyDeps) { + destKeyDeps = new Map(); + obj.keyDependencies = destKeyDeps; + } + canReflect.eachKey(sourcekeyDeps, function (keys, obj) { + var entry = destKeyDeps.get(obj); + if (!entry) { + entry = new Set(); + destKeyDeps.set(obj, entry); + } + canReflect.eachIndex(keys, function (key) { + entry.add(key); + }); + }); + } + }; + module.exports = function mergeDependencyRecords(object, source) { + mergeKeyDependencies(object, source); + mergeValueDependencies(object, source); + return object; + }; +}); +/*can-event-queue@1.1.8#map/map*/ +define('can-event-queue@1.1.8#map/map', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + 'can-queues', + 'can-reflect', + 'can-symbol', + 'can-key-tree', + 'can-dom-events', + 'can-dom-events/helpers/util', + '../dependency-record/merge' +], function (require, exports, module) { + 'use strict'; + var canDev = require('can-log/dev/dev'); + var queues = require('can-queues'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var KeyTree = require('can-key-tree'); + var domEvents = require('can-dom-events'); + var isDomEventTarget = require('can-dom-events/helpers/util').isDomEventTarget; + var mergeDependencyRecords = require('../dependency-record/merge'); + var metaSymbol = canSymbol.for('can.meta'), dispatchBoundChangeSymbol = canSymbol.for('can.dispatchInstanceBoundChange'), dispatchInstanceOnPatchesSymbol = canSymbol.for('can.dispatchInstanceOnPatches'), onKeyValueSymbol = canSymbol.for('can.onKeyValue'), offKeyValueSymbol = canSymbol.for('can.offKeyValue'), onEventSymbol = canSymbol.for('can.onEvent'), offEventSymbol = canSymbol.for('can.offEvent'), onValueSymbol = canSymbol.for('can.onValue'), offValueSymbol = canSymbol.for('can.offValue'), inSetupSymbol = canSymbol.for('can.initializing'); + var legacyMapBindings; + function addHandlers(obj, meta) { + if (!meta.handlers) { + meta.handlers = new KeyTree([ + Object, + Object, + Object, + Array + ], { + onFirst: function () { + if (obj._eventSetup !== undefined) { + obj._eventSetup(); + } + var constructor = obj.constructor; + if (constructor[dispatchBoundChangeSymbol] !== undefined && obj instanceof constructor) { + constructor[dispatchBoundChangeSymbol](obj, true); + } + }, + onEmpty: function () { + if (obj._eventTeardown !== undefined) { + obj._eventTeardown(); + } + var constructor = obj.constructor; + if (constructor[dispatchBoundChangeSymbol] !== undefined && obj instanceof constructor) { + constructor[dispatchBoundChangeSymbol](obj, false); + } + } + }); + } + if (!meta.listenHandlers) { + meta.listenHandlers = new KeyTree([ + Map, + Map, + Object, + Array + ]); + } + } + var ensureMeta = function ensureMeta(obj) { + var meta = obj[metaSymbol]; + if (!meta) { + meta = {}; + canReflect.setKeyValue(obj, metaSymbol, meta); + } + addHandlers(obj, meta); + return meta; + }; + function stopListeningArgumentsToKeys(bindTarget, event, handler, queueName) { + if (arguments.length && canReflect.isPrimitive(bindTarget)) { + queueName = handler; + handler = event; + event = bindTarget; + bindTarget = this.context; + } + if (typeof event === 'function') { + queueName = handler; + handler = event; + event = undefined; + } + if (typeof handler === 'string') { + queueName = handler; + handler = undefined; + } + var keys = []; + if (bindTarget) { + keys.push(bindTarget); + if (event || handler || queueName) { + keys.push(event); + if (queueName || handler) { + keys.push(queueName || this.defaultQueue); + if (handler) { + keys.push(handler); + } + } + } + } + return keys; + } + var props = { + dispatch: function (event, args) { + if (this.__inSetup !== true && this[inSetupSymbol] !== true) { + if (typeof event === 'string') { + event = { type: event }; + } + var meta = ensureMeta(this); + var handlers = meta.handlers; + var handlersByType = event.type !== undefined && handlers.getNode([event.type]); + var dispatchConstructorPatches = event.patches && this.constructor[dispatchInstanceOnPatchesSymbol]; + var patchesNode = event.patches !== undefined && handlers.getNode([ + 'can.patches', + 'onKeyValue' + ]); + var keysNode = event.keyChanged !== undefined && handlers.getNode([ + 'can.keys', + 'onKeyValue' + ]); + var batch = dispatchConstructorPatches || handlersByType || patchesNode || keysNode; + if (batch) { + queues.batch.start(); + } + if (handlersByType) { + if (handlersByType.onKeyValue) { + queues.enqueueByQueue(handlersByType.onKeyValue, this, args, event.makeMeta, event.reasonLog); + } + if (handlersByType.event) { + event.batchNum = queues.batch.number(); + var eventAndArgs = [event].concat(args); + queues.enqueueByQueue(handlersByType.event, this, eventAndArgs, event.makeMeta, event.reasonLog); + } + } + if (keysNode) { + queues.enqueueByQueue(keysNode, this, [event.keyChanged], event.makeMeta, event.reasonLog); + } + if (patchesNode) { + queues.enqueueByQueue(patchesNode, this, [event.patches], event.makeMeta, event.reasonLog); + } + if (dispatchConstructorPatches) { + this.constructor[dispatchInstanceOnPatchesSymbol](this, event.patches); + } + if (batch) { + queues.batch.stop(); + } + } + return event; + }, + addEventListener: function (key, handler, queueName) { + ensureMeta(this).handlers.add([ + key, + 'event', + queueName || 'mutate', + handler + ]); + return this; + }, + removeEventListener: function (key, handler, queueName) { + if (key === undefined) { + var handlers = ensureMeta(this).handlers; + var keyHandlers = handlers.getNode([]); + Object.keys(keyHandlers).forEach(function (key) { + handlers.delete([ + key, + 'event' + ]); + }); + } else if (!handler && !queueName) { + ensureMeta(this).handlers.delete([ + key, + 'event' + ]); + } else if (!handler) { + ensureMeta(this).handlers.delete([ + key, + 'event', + queueName || 'mutate' + ]); + } else { + ensureMeta(this).handlers.delete([ + key, + 'event', + queueName || 'mutate', + handler + ]); + } + return this; + }, + one: function (event, handler) { + var one = function () { + legacyMapBindings.off.call(this, event, one); + return handler.apply(this, arguments); + }; + legacyMapBindings.on.call(this, event, one); + return this; + }, + listenTo: function (bindTarget, event, handler, queueName) { + if (canReflect.isPrimitive(bindTarget)) { + queueName = handler; + handler = event; + event = bindTarget; + bindTarget = this; + } + if (typeof event === 'function') { + queueName = handler; + handler = event; + event = undefined; + } + ensureMeta(this).listenHandlers.add([ + bindTarget, + event, + queueName || 'mutate', + handler + ]); + legacyMapBindings.on.call(bindTarget, event, handler, queueName || 'mutate'); + return this; + }, + stopListening: function () { + var keys = stopListeningArgumentsToKeys.apply({ + context: this, + defaultQueue: 'mutate' + }, arguments); + var listenHandlers = ensureMeta(this).listenHandlers; + function deleteHandler(bindTarget, event, queue, handler) { + legacyMapBindings.off.call(bindTarget, event, handler, queue); + } + listenHandlers.delete(keys, deleteHandler); + return this; + }, + on: function (eventName, handler, queue) { + var listenWithDOM = isDomEventTarget(this); + if (listenWithDOM) { + if (typeof handler === 'string') { + domEvents.addDelegateListener(this, eventName, handler, queue); + } else { + domEvents.addEventListener(this, eventName, handler, queue); + } + } else { + if (this[onEventSymbol]) { + this[onEventSymbol](eventName, handler, queue); + } else if ('addEventListener' in this) { + this.addEventListener(eventName, handler, queue); + } else if (this[onKeyValueSymbol]) { + canReflect.onKeyValue(this, eventName, handler, queue); + } else { + if (!eventName && this[onValueSymbol]) { + canReflect.onValue(this, handler, queue); + } else { + throw new Error('can-event-queue: Unable to bind ' + eventName); + } + } + } + return this; + }, + off: function (eventName, handler, queue) { + var listenWithDOM = isDomEventTarget(this); + if (listenWithDOM) { + if (typeof handler === 'string') { + domEvents.removeDelegateListener(this, eventName, handler, queue); + } else { + domEvents.removeEventListener(this, eventName, handler, queue); + } + } else { + if (this[offEventSymbol]) { + this[offEventSymbol](eventName, handler, queue); + } else if ('removeEventListener' in this) { + this.removeEventListener(eventName, handler, queue); + } else if (this[offKeyValueSymbol]) { + canReflect.offKeyValue(this, eventName, handler, queue); + } else { + if (!eventName && this[offValueSymbol]) { + canReflect.offValue(this, handler, queue); + } else { + throw new Error('can-event-queue: Unable to unbind ' + eventName); + } + } + } + return this; + } + }; + var symbols = { + 'can.onKeyValue': function (key, handler, queueName) { + ensureMeta(this).handlers.add([ + key, + 'onKeyValue', + queueName || 'mutate', + handler + ]); + }, + 'can.offKeyValue': function (key, handler, queueName) { + ensureMeta(this).handlers.delete([ + key, + 'onKeyValue', + queueName || 'mutate', + handler + ]); + }, + 'can.isBound': function () { + return !ensureMeta(this).handlers.isEmpty(); + }, + 'can.getWhatIChange': function getWhatIChange(key) { + }, + 'can.onPatches': function (handler, queue) { + var handlers = ensureMeta(this).handlers; + handlers.add([ + 'can.patches', + 'onKeyValue', + queue || 'notify', + handler + ]); + }, + 'can.offPatches': function (handler, queue) { + var handlers = ensureMeta(this).handlers; + handlers.delete([ + 'can.patches', + 'onKeyValue', + queue || 'notify', + handler + ]); + } + }; + function defineNonEnumerable(obj, prop, value) { + Object.defineProperty(obj, prop, { + enumerable: false, + value: value + }); + } + legacyMapBindings = function (obj) { + canReflect.assignMap(obj, props); + return canReflect.assignSymbols(obj, symbols); + }; + defineNonEnumerable(legacyMapBindings, 'addHandlers', addHandlers); + defineNonEnumerable(legacyMapBindings, 'stopListeningArgumentsToKeys', stopListeningArgumentsToKeys); + props.bind = props.addEventListener; + props.unbind = props.removeEventListener; + canReflect.assignMap(legacyMapBindings, props); + canReflect.assignSymbols(legacyMapBindings, symbols); + defineNonEnumerable(legacyMapBindings, 'start', function () { + console.warn('use can-queues.batch.start()'); + queues.batch.start(); + }); + defineNonEnumerable(legacyMapBindings, 'stop', function () { + console.warn('use can-queues.batch.stop()'); + queues.batch.stop(); + }); + defineNonEnumerable(legacyMapBindings, 'flush', function () { + console.warn('use can-queues.flush()'); + queues.flush(); + }); + defineNonEnumerable(legacyMapBindings, 'afterPreviousEvents', function (handler) { + console.warn('don\'t use afterPreviousEvents'); + queues.mutateQueue.enqueue(function afterPreviousEvents() { + queues.mutateQueue.enqueue(handler); + }); + queues.flush(); + }); + defineNonEnumerable(legacyMapBindings, 'after', function (handler) { + console.warn('don\'t use after'); + queues.mutateQueue.enqueue(handler); + queues.flush(); + }); + module.exports = legacyMapBindings; +}); +/*can-simple-map@4.3.3#can-simple-map*/ +define('can-simple-map@4.3.3#can-simple-map', [ + 'require', + 'exports', + 'module', + 'can-construct', + 'can-event-queue/map/map', + 'can-queues', + 'can-observation-recorder', + 'can-reflect', + 'can-log/dev/dev', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Construct = require('can-construct'); + var eventQueue = require('can-event-queue/map/map'); + var queues = require('can-queues'); + var ObservationRecorder = require('can-observation-recorder'); + var canReflect = require('can-reflect'); + var dev = require('can-log/dev/dev'); + var canSymbol = require('can-symbol'); + var ensureMeta = function ensureMeta(obj) { + var metaSymbol = canSymbol.for('can.meta'); + var meta = obj[metaSymbol]; + if (!meta) { + meta = {}; + canReflect.setKeyValue(obj, metaSymbol, meta); + } + return meta; + }; + var SimpleMap = Construct.extend('SimpleMap', { + setup: function (initialData) { + this._data = {}; + if (initialData && typeof initialData === 'object') { + this.attr(initialData); + } + }, + attr: function (prop, value) { + var self = this; + if (arguments.length === 0) { + ObservationRecorder.add(this, 'can.keys'); + var data = {}; + canReflect.eachKey(this._data, function (value, prop) { + ObservationRecorder.add(this, prop); + data[prop] = value; + }, this); + return data; + } else if (arguments.length > 1) { + var had = this._data.hasOwnProperty(prop); + var old = this._data[prop]; + this._data[prop] = value; + if (old !== value) { + var dispatched = { + keyChanged: !had ? prop : undefined, + type: prop + }; + this.dispatch(dispatched, [ + value, + old + ]); + } + } else if (typeof prop === 'object') { + queues.batch.start(); + canReflect.eachKey(prop, function (value, key) { + self.attr(key, value); + }); + queues.batch.stop(); + } else { + if (prop !== 'constructor') { + ObservationRecorder.add(this, prop); + return this._data[prop]; + } + return this.constructor; + } + }, + serialize: function () { + return canReflect.serialize(this, Map); + }, + get: function () { + return this.attr.apply(this, arguments); + }, + set: function () { + return this.attr.apply(this, arguments); + }, + log: function (key) { + } + }); + eventQueue(SimpleMap.prototype); + var simpleMapProto = { + 'can.isMapLike': true, + 'can.isListLike': false, + 'can.isValueLike': false, + 'can.getKeyValue': SimpleMap.prototype.get, + 'can.setKeyValue': SimpleMap.prototype.set, + 'can.deleteKeyValue': function (prop) { + var dispatched; + if (this._data.hasOwnProperty(prop)) { + var old = this._data[prop]; + delete this._data[prop]; + dispatched = { + keyChanged: prop, + type: prop + }; + this.dispatch(dispatched, [ + undefined, + old + ]); + } + }, + 'can.getOwnEnumerableKeys': function () { + ObservationRecorder.add(this, 'can.keys'); + return Object.keys(this._data); + }, + 'can.assignDeep': function (source) { + queues.batch.start(); + canReflect.assignMap(this, source); + queues.batch.stop(); + }, + 'can.updateDeep': function (source) { + queues.batch.start(); + canReflect.updateMap(this, source); + queues.batch.stop(); + }, + 'can.keyHasDependencies': function (key) { + return false; + }, + 'can.getKeyDependencies': function (key) { + return undefined; + }, + 'can.hasOwnKey': function (key) { + return this._data.hasOwnProperty(key); + } + }; + canReflect.assignSymbols(SimpleMap.prototype, simpleMapProto); + module.exports = SimpleMap; +}); +/*can-view-scope@4.13.6#template-context*/ +define('can-view-scope@4.13.6#template-context', [ + 'require', + 'exports', + 'module', + 'can-simple-map' +], function (require, exports, module) { + 'use strict'; + var SimpleMap = require('can-simple-map'); + var TemplateContext = function (options) { + options = options || {}; + this.vars = new SimpleMap(options.vars || {}); + this.helpers = new SimpleMap(options.helpers || {}); + this.partials = new SimpleMap(options.partials || {}); + this.tags = new SimpleMap(options.tags || {}); + }; + module.exports = TemplateContext; +}); +/*can-define-lazy-value@1.1.1#define-lazy-value*/ +define('can-define-lazy-value@1.1.1#define-lazy-value', function (require, exports, module) { + 'use strict'; + module.exports = function defineLazyValue(obj, prop, initializer, writable) { + Object.defineProperty(obj, prop, { + configurable: true, + get: function () { + Object.defineProperty(this, prop, { + value: undefined, + writable: true + }); + var value = initializer.call(this, obj, prop); + Object.defineProperty(this, prop, { + value: value, + writable: !!writable + }); + return value; + }, + set: function (value) { + Object.defineProperty(this, prop, { + value: value, + writable: !!writable + }); + return value; + } + }); + }; +}); +/*can-event-queue@1.1.8#value/value*/ +define('can-event-queue@1.1.8#value/value', [ + 'require', + 'exports', + 'module', + 'can-queues', + 'can-key-tree', + 'can-reflect', + 'can-define-lazy-value', + '../dependency-record/merge' +], function (require, exports, module) { + 'use strict'; + var queues = require('can-queues'); + var KeyTree = require('can-key-tree'); + var canReflect = require('can-reflect'); + var defineLazyValue = require('can-define-lazy-value'); + var mergeDependencyRecords = require('../dependency-record/merge'); + var properties = { + on: function (handler, queue) { + this.handlers.add([ + queue || 'mutate', + handler + ]); + }, + off: function (handler, queueName) { + if (handler === undefined) { + if (queueName === undefined) { + this.handlers.delete([]); + } else { + this.handlers.delete([queueName]); + } + } else { + this.handlers.delete([ + queueName || 'mutate', + handler + ]); + } + } + }; + var symbols = { + 'can.onValue': properties.on, + 'can.offValue': properties.off, + 'can.dispatch': function (value, old) { + var queuesArgs = []; + queuesArgs = [ + this.handlers.getNode([]), + this, + [ + value, + old + ] + ]; + queues.enqueueByQueue.apply(queues, queuesArgs); + }, + 'can.getWhatIChange': function getWhatIChange() { + }, + 'can.isBound': function isBound() { + return !this.handlers.isEmpty(); + } + }; + function defineLazyHandlers() { + return new KeyTree([ + Object, + Array + ], { + onFirst: this.onBound !== undefined && this.onBound.bind(this), + onEmpty: this.onUnbound !== undefined && this.onUnbound.bind(this) + }); + } + var mixinValueEventBindings = function (obj) { + canReflect.assign(obj, properties); + canReflect.assignSymbols(obj, symbols); + defineLazyValue(obj, 'handlers', defineLazyHandlers, true); + return obj; + }; + mixinValueEventBindings.addHandlers = function (obj, callbacks) { + console.warn('can-event-queue/value: Avoid using addHandlers. Add onBound and onUnbound methods instead.'); + obj.handlers = new KeyTree([ + Object, + Array + ], callbacks); + return obj; + }; + module.exports = mixinValueEventBindings; +}); +/*can-observation@4.2.0#recorder-dependency-helpers*/ +define('can-observation@4.2.0#recorder-dependency-helpers', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function addNewKeyDependenciesIfNotInOld(event) { + if (this.oldEventSet === undefined || this.oldEventSet['delete'](event) === false) { + canReflect.onKeyValue(this.observable, event, this.onDependencyChange, 'notify'); + } + } + function addObservablesNewKeyDependenciesIfNotInOld(eventSet, observable) { + eventSet.forEach(addNewKeyDependenciesIfNotInOld, { + onDependencyChange: this.onDependencyChange, + observable: observable, + oldEventSet: this.oldDependencies.keyDependencies.get(observable) + }); + } + function removeKeyDependencies(event) { + canReflect.offKeyValue(this.observable, event, this.onDependencyChange, 'notify'); + } + function removeObservablesKeyDependencies(oldEventSet, observable) { + oldEventSet.forEach(removeKeyDependencies, { + onDependencyChange: this.onDependencyChange, + observable: observable + }); + } + function addValueDependencies(observable) { + if (this.oldDependencies.valueDependencies.delete(observable) === false) { + canReflect.onValue(observable, this.onDependencyChange, 'notify'); + } + } + function removeValueDependencies(observable) { + canReflect.offValue(observable, this.onDependencyChange, 'notify'); + } + module.exports = { + updateObservations: function (observationData) { + observationData.newDependencies.keyDependencies.forEach(addObservablesNewKeyDependenciesIfNotInOld, observationData); + observationData.oldDependencies.keyDependencies.forEach(removeObservablesKeyDependencies, observationData); + observationData.newDependencies.valueDependencies.forEach(addValueDependencies, observationData); + observationData.oldDependencies.valueDependencies.forEach(removeValueDependencies, observationData); + }, + stopObserving: function (observationReciever, onDependencyChange) { + observationReciever.keyDependencies.forEach(removeObservablesKeyDependencies, { onDependencyChange: onDependencyChange }); + observationReciever.valueDependencies.forEach(removeValueDependencies, { onDependencyChange: onDependencyChange }); + } + }; +}); +/*can-observation@4.2.0#temporarily-bind*/ +define('can-observation@4.2.0#temporarily-bind', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var temporarilyBoundNoOperation = function () { + }; + var observables; + var unbindTemporarilyBoundValue = function () { + for (var i = 0, len = observables.length; i < len; i++) { + canReflect.offValue(observables[i], temporarilyBoundNoOperation); + } + observables = null; + }; + function temporarilyBind(compute) { + var computeInstance = compute.computeInstance || compute; + canReflect.onValue(computeInstance, temporarilyBoundNoOperation); + if (!observables) { + observables = []; + setTimeout(unbindTemporarilyBoundValue, 10); + } + observables.push(computeInstance); + } + module.exports = temporarilyBind; +}); +/*can-observation@4.2.0#can-observation*/ +define('can-observation@4.2.0#can-observation', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-reflect', + 'can-queues', + 'can-observation-recorder', + 'can-symbol', + 'can-log/dev/dev', + 'can-event-queue/value/value', + './recorder-dependency-helpers', + './temporarily-bind' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var ObservationRecorder = require('can-observation-recorder'); + var canSymbol = require('can-symbol'); + var dev = require('can-log/dev/dev'); + var valueEventBindings = require('can-event-queue/value/value'); + var recorderHelpers = require('./recorder-dependency-helpers'); + var temporarilyBind = require('./temporarily-bind'); + var dispatchSymbol = canSymbol.for('can.dispatch'); + var getChangesSymbol = canSymbol.for('can.getChangesDependencyRecord'); + var getValueDependenciesSymbol = canSymbol.for('can.getValueDependencies'); + function Observation(func, context, options) { + this.deriveQueue = queues.deriveQueue; + this.func = func; + this.context = context; + this.options = options || { + priority: 0, + isObservable: true + }; + this.bound = false; + this._value = undefined; + this.newDependencies = ObservationRecorder.makeDependenciesRecord(); + this.oldDependencies = null; + var self = this; + this.onDependencyChange = function (newVal) { + self.dependencyChange(this, newVal); + }; + this.update = this.update.bind(this); + } + valueEventBindings(Observation.prototype); + canReflect.assign(Observation.prototype, { + onBound: function () { + this.bound = true; + this.oldDependencies = this.newDependencies; + ObservationRecorder.start(this._name); + this._value = this.func.call(this.context); + this.newDependencies = ObservationRecorder.stop(); + recorderHelpers.updateObservations(this); + }, + dependencyChange: function (context, args) { + if (this.bound === true) { + var queuesArgs = []; + queuesArgs = [ + this.update, + this, + [], + { + priority: this.options.priority, + element: this.options.element + } + ]; + this.deriveQueue.enqueue.apply(this.deriveQueue, queuesArgs); + } + }, + update: function () { + if (this.bound === true) { + var oldValue = this._value; + this.oldValue = null; + this.onBound(); + if (oldValue !== this._value) { + this[dispatchSymbol](this._value, oldValue); + } + } + }, + onUnbound: function () { + this.bound = false; + recorderHelpers.stopObserving(this.newDependencies, this.onDependencyChange); + this.newDependencies = ObservationRecorder.makeDependenciesRecord(); + }, + get: function () { + if (this.options.isObservable && ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (this.bound === false) { + Observation.temporarilyBind(this); + } + } + if (this.bound === true) { + if (this.deriveQueue.tasksRemainingCount() > 0) { + Observation.updateChildrenAndSelf(this); + } + return this._value; + } else { + return this.func.call(this.context); + } + }, + hasDependencies: function () { + var newDependencies = this.newDependencies; + return this.bound ? newDependencies.valueDependencies.size + newDependencies.keyDependencies.size > 0 : undefined; + }, + log: function () { + } + }); + Object.defineProperty(Observation.prototype, 'value', { + get: function () { + return this.get(); + } + }); + var observationProto = { + 'can.getValue': Observation.prototype.get, + 'can.isValueLike': true, + 'can.isMapLike': false, + 'can.isListLike': false, + 'can.valueHasDependencies': Observation.prototype.hasDependencies, + 'can.getValueDependencies': function () { + if (this.bound === true) { + var deps = this.newDependencies, result = {}; + if (deps.keyDependencies.size) { + result.keyDependencies = deps.keyDependencies; + } + if (deps.valueDependencies.size) { + result.valueDependencies = deps.valueDependencies; + } + return result; + } + return undefined; + }, + 'can.getPriority': function () { + return this.options.priority; + }, + 'can.setPriority': function (priority) { + this.options.priority = priority; + }, + 'can.setElement': function (element) { + this.options.element = element; + this.deriveQueue = queues.domQueue || queues.deriveQueue; + } + }; + canReflect.assignSymbols(Observation.prototype, observationProto); + Observation.updateChildrenAndSelf = function (observation) { + if (observation.update !== undefined && observation.deriveQueue.isEnqueued(observation.update) === true) { + observation.deriveQueue.flushQueuedTask(observation.update); + return true; + } + if (observation[getValueDependenciesSymbol]) { + var childHasChanged = false; + var valueDependencies = observation[getValueDependenciesSymbol]().valueDependencies || []; + valueDependencies.forEach(function (observable) { + if (Observation.updateChildrenAndSelf(observable) === true) { + childHasChanged = true; + } + }); + return childHasChanged; + } else { + return false; + } + }; + var alias = { addAll: 'addMany' }; + [ + 'add', + 'addAll', + 'ignore', + 'trap', + 'trapsCount', + 'isRecording' + ].forEach(function (methodName) { + Observation[methodName] = function () { + var name = alias[methodName] ? alias[methodName] : methodName; + console.warn('can-observation: Call ' + name + '() on can-observation-recorder.'); + return ObservationRecorder[name].apply(this, arguments); + }; + }); + Observation.prototype.start = function () { + console.warn('can-observation: Use .on and .off to bind.'); + return this.onBound(); + }; + Observation.prototype.stop = function () { + console.warn('can-observation: Use .on and .off to bind.'); + return this.onUnbound(); + }; + Observation.temporarilyBind = temporarilyBind; + module.exports = namespace.Observation = Observation; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-cid@1.3.1#can-cid*/ +define('can-cid@1.3.1#can-cid', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var _cid = 0; + var domExpando = 'can' + new Date(); + var cid = function (object, name) { + var propertyName = object.nodeName ? domExpando : '_cid'; + if (!object[propertyName]) { + _cid++; + object[propertyName] = (name || '') + _cid; + } + return object[propertyName]; + }; + cid.domExpando = domExpando; + cid.get = function (object) { + var type = typeof object; + var isObject = type !== null && (type === 'object' || type === 'function'); + return isObject ? cid(object) : type + ':' + object; + }; + if (namespace.cid) { + throw new Error('You can\'t have two versions of can-cid, check your dependencies'); + } else { + module.exports = namespace.cid = cid; + } +}); +/*can-single-reference@1.3.0#can-single-reference*/ +define('can-single-reference@1.3.0#can-single-reference', [ + 'require', + 'exports', + 'module', + 'can-cid' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var CID = require('can-cid'); + var singleReference; + function getKeyName(key, extraKey) { + var keyName = extraKey ? CID(key) + ':' + extraKey : CID(key); + return keyName || key; + } + singleReference = { + set: function (obj, key, value, extraKey) { + obj[getKeyName(key, extraKey)] = value; + }, + getAndDelete: function (obj, key, extraKey) { + var keyName = getKeyName(key, extraKey); + var value = obj[keyName]; + delete obj[keyName]; + return value; + } + }; + module.exports = singleReference; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-scope@4.13.6#make-compute-like*/ +define('can-view-scope@4.13.6#make-compute-like', [ + 'require', + 'exports', + 'module', + 'can-single-reference', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var singleReference = require('can-single-reference'); + var canReflect = require('can-reflect'); + var Compute = function (newVal) { + if (arguments.length) { + return canReflect.setValue(this, newVal); + } else { + return canReflect.getValue(this); + } + }; + module.exports = function (observable) { + var compute = Compute.bind(observable); + compute.on = compute.bind = compute.addEventListener = function (event, handler) { + var translationHandler = function (newVal, oldVal) { + handler.call(compute, { type: 'change' }, newVal, oldVal); + }; + singleReference.set(handler, this, translationHandler); + observable.on(translationHandler); + }; + compute.off = compute.unbind = compute.removeEventListener = function (event, handler) { + observable.off(singleReference.getAndDelete(handler, this)); + }; + canReflect.assignSymbols(compute, { + 'can.getValue': function () { + return canReflect.getValue(observable); + }, + 'can.setValue': function (newVal) { + return canReflect.setValue(observable, newVal); + }, + 'can.onValue': function (handler, queue) { + return canReflect.onValue(observable, handler, queue); + }, + 'can.offValue': function (handler, queue) { + return canReflect.offValue(observable, handler, queue); + }, + 'can.valueHasDependencies': function () { + return canReflect.valueHasDependencies(observable); + }, + 'can.getPriority': function () { + return canReflect.getPriority(observable); + }, + 'can.setPriority': function (newPriority) { + canReflect.setPriority(observable, newPriority); + }, + 'can.isValueLike': true, + 'can.isFunctionLike': false + }); + compute.isComputed = true; + return compute; + }; +}); +/*can-reflect-dependencies@1.1.2#src/add-mutated-by*/ +define('can-reflect-dependencies@1.1.2#src/add-mutated-by', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var makeDependencyRecord = function makeDependencyRecord() { + return { + keyDependencies: new Map(), + valueDependencies: new Set() + }; + }; + var makeRootRecord = function makeRootRecord() { + return { + mutateDependenciesForKey: new Map(), + mutateDependenciesForValue: makeDependencyRecord() + }; + }; + module.exports = function (mutatedByMap) { + return function addMutatedBy(mutated, key, mutator) { + var gotKey = arguments.length === 3; + if (arguments.length === 2) { + mutator = key; + key = undefined; + } + if (!mutator.keyDependencies && !mutator.valueDependencies) { + var s = new Set(); + s.add(mutator); + mutator = { valueDependencies: s }; + } + var root = mutatedByMap.get(mutated); + if (!root) { + root = makeRootRecord(); + mutatedByMap.set(mutated, root); + } + if (gotKey && !root.mutateDependenciesForKey.get(key)) { + root.mutateDependenciesForKey.set(key, makeDependencyRecord()); + } + var dependencyRecord = gotKey ? root.mutateDependenciesForKey.get(key) : root.mutateDependenciesForValue; + if (mutator.valueDependencies) { + canReflect.addValues(dependencyRecord.valueDependencies, mutator.valueDependencies); + } + if (mutator.keyDependencies) { + canReflect.each(mutator.keyDependencies, function (keysSet, obj) { + var entry = dependencyRecord.keyDependencies.get(obj); + if (!entry) { + entry = new Set(); + dependencyRecord.keyDependencies.set(obj, entry); + } + canReflect.addValues(entry, keysSet); + }); + } + }; + }; +}); +/*can-reflect-dependencies@1.1.2#src/delete-mutated-by*/ +define('can-reflect-dependencies@1.1.2#src/delete-mutated-by', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + module.exports = function (mutatedByMap) { + return function deleteMutatedBy(mutated, key, mutator) { + var gotKey = arguments.length === 3; + var root = mutatedByMap.get(mutated); + if (arguments.length === 2) { + mutator = key; + key = undefined; + } + if (!mutator.keyDependencies && !mutator.valueDependencies) { + var s = new Set(); + s.add(mutator); + mutator = { valueDependencies: s }; + } + var dependencyRecord = gotKey ? root.mutateDependenciesForKey.get(key) : root.mutateDependenciesForValue; + if (mutator.valueDependencies) { + canReflect.removeValues(dependencyRecord.valueDependencies, mutator.valueDependencies); + } + if (mutator.keyDependencies) { + canReflect.each(mutator.keyDependencies, function (keysSet, obj) { + var entry = dependencyRecord.keyDependencies.get(obj); + if (entry) { + canReflect.removeValues(entry, keysSet); + if (!entry.size) { + dependencyRecord.keyDependencies.delete(obj); + } + } + }); + } + }; + }; +}); +/*can-reflect-dependencies@1.1.2#src/is-function*/ +define('can-reflect-dependencies@1.1.2#src/is-function', function (require, exports, module) { + 'use strict'; + module.exports = function isFunction(value) { + return typeof value === 'function'; + }; +}); +/*can-reflect-dependencies@1.1.2#src/get-dependency-data-of*/ +define('can-reflect-dependencies@1.1.2#src/get-dependency-data-of', [ + 'require', + 'exports', + 'module', + 'can-symbol', + 'can-reflect', + './is-function', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var isFunction = require('./is-function'); + var canAssign = require('can-assign'); + var getWhatIChangeSymbol = canSymbol.for('can.getWhatIChange'); + var getKeyDependenciesSymbol = canSymbol.for('can.getKeyDependencies'); + var getValueDependenciesSymbol = canSymbol.for('can.getValueDependencies'); + var getKeyDependencies = function getKeyDependencies(obj, key) { + if (isFunction(obj[getKeyDependenciesSymbol])) { + return canReflect.getKeyDependencies(obj, key); + } + }; + var getValueDependencies = function getValueDependencies(obj) { + if (isFunction(obj[getValueDependenciesSymbol])) { + return canReflect.getValueDependencies(obj); + } + }; + var getMutatedKeyDependencies = function getMutatedKeyDependencies(mutatedByMap, obj, key) { + var root = mutatedByMap.get(obj); + var dependencyRecord; + if (root && root.mutateDependenciesForKey.has(key)) { + dependencyRecord = root.mutateDependenciesForKey.get(key); + } + return dependencyRecord; + }; + var getMutatedValueDependencies = function getMutatedValueDependencies(mutatedByMap, obj) { + var result; + var root = mutatedByMap.get(obj); + if (root) { + var dependencyRecord = root.mutateDependenciesForValue; + if (dependencyRecord.keyDependencies.size) { + result = result || {}; + result.keyDependencies = dependencyRecord.keyDependencies; + } + if (dependencyRecord.valueDependencies.size) { + result = result || {}; + result.valueDependencies = dependencyRecord.valueDependencies; + } + } + return result; + }; + var getWhatIChange = function getWhatIChange(obj, key) { + if (isFunction(obj[getWhatIChangeSymbol])) { + var gotKey = arguments.length === 2; + return gotKey ? canReflect.getWhatIChange(obj, key) : canReflect.getWhatIChange(obj); + } + }; + var isEmptyRecord = function isEmptyRecord(record) { + return record == null || !Object.keys(record).length || record.keyDependencies && !record.keyDependencies.size && (record.valueDependencies && !record.valueDependencies.size); + }; + var getWhatChangesMe = function getWhatChangesMe(mutatedByMap, obj, key) { + var gotKey = arguments.length === 3; + var mutate = gotKey ? getMutatedKeyDependencies(mutatedByMap, obj, key) : getMutatedValueDependencies(mutatedByMap, obj); + var derive = gotKey ? getKeyDependencies(obj, key) : getValueDependencies(obj); + if (!isEmptyRecord(mutate) || !isEmptyRecord(derive)) { + return canAssign(canAssign({}, mutate ? { mutate: mutate } : null), derive ? { derive: derive } : null); + } + }; + module.exports = function (mutatedByMap) { + return function getDependencyDataOf(obj, key) { + var gotKey = arguments.length === 2; + var whatChangesMe = gotKey ? getWhatChangesMe(mutatedByMap, obj, key) : getWhatChangesMe(mutatedByMap, obj); + var whatIChange = gotKey ? getWhatIChange(obj, key) : getWhatIChange(obj); + if (whatChangesMe || whatIChange) { + return canAssign(canAssign({}, whatIChange ? { whatIChange: whatIChange } : null), whatChangesMe ? { whatChangesMe: whatChangesMe } : null); + } + }; + }; +}); +/*can-reflect-dependencies@1.1.2#can-reflect-dependencies*/ +define('can-reflect-dependencies@1.1.2#can-reflect-dependencies', [ + 'require', + 'exports', + 'module', + './src/add-mutated-by', + './src/delete-mutated-by', + './src/get-dependency-data-of' +], function (require, exports, module) { + 'use strict'; + var addMutatedBy = require('./src/add-mutated-by'); + var deleteMutatedBy = require('./src/delete-mutated-by'); + var getDependencyDataOf = require('./src/get-dependency-data-of'); + var mutatedByMap = new WeakMap(); + module.exports = { + addMutatedBy: addMutatedBy(mutatedByMap), + deleteMutatedBy: deleteMutatedBy(mutatedByMap), + getDependencyDataOf: getDependencyDataOf(mutatedByMap) + }; +}); +/*can-stache-helpers@1.2.0#can-stache-helpers*/ +define('can-stache-helpers@1.2.0#can-stache-helpers', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + if (namespace.stacheHelpers) { + throw new Error('You can\'t have two versions of can-stache-helpers, check your dependencies'); + } else { + module.exports = namespace.stacheHelpers = {}; + } +}); +/*can-simple-observable@2.5.0#log*/ +define('can-simple-observable@2.5.0#log', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var dev = require('can-log/dev/dev'); + var canReflect = require('can-reflect'); + function quoteString(x) { + return typeof x === 'string' ? JSON.stringify(x) : x; + } + module.exports = function log() { + }; +}); +/*can-simple-observable@2.5.0#can-simple-observable*/ +define('can-simple-observable@2.5.0#can-simple-observable', [ + 'require', + 'exports', + 'module', + './log', + 'can-namespace', + 'can-symbol', + 'can-reflect', + 'can-observation-recorder', + 'can-event-queue/value/value' +], function (require, exports, module) { + 'use strict'; + var log = require('./log'); + var ns = require('can-namespace'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var valueEventBindings = require('can-event-queue/value/value'); + var dispatchSymbol = canSymbol.for('can.dispatch'); + function SimpleObservable(initialValue) { + this._value = initialValue; + } + valueEventBindings(SimpleObservable.prototype); + canReflect.assignMap(SimpleObservable.prototype, { + log: log, + get: function () { + ObservationRecorder.add(this); + return this._value; + }, + set: function (value) { + var old = this._value; + this._value = value; + this[dispatchSymbol](value, old); + } + }); + Object.defineProperty(SimpleObservable.prototype, 'value', { + set: function (value) { + return this.set(value); + }, + get: function () { + return this.get(); + } + }); + var simpleObservableProto = { + 'can.getValue': SimpleObservable.prototype.get, + 'can.setValue': SimpleObservable.prototype.set, + 'can.isMapLike': false, + 'can.valueHasDependencies': function () { + return true; + } + }; + canReflect.assignSymbols(SimpleObservable.prototype, simpleObservableProto); + module.exports = ns.SimpleObservable = SimpleObservable; +}); +/*can-view-scope@4.13.6#scope-key-data*/ +define('can-view-scope@4.13.6#scope-key-data', [ + 'require', + 'exports', + 'module', + 'can-observation', + 'can-stache-key', + 'can-assign', + 'can-reflect', + 'can-symbol', + 'can-observation-recorder', + './make-compute-like', + 'can-reflect-dependencies', + 'can-event-queue/value/value', + 'can-stache-helpers', + 'can-simple-observable', + 'can-log/dev/dev' +], function (require, exports, module) { + 'use strict'; + var Observation = require('can-observation'); + var observeReader = require('can-stache-key'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var ObservationRecorder = require('can-observation-recorder'); + var makeComputeLike = require('./make-compute-like'); + var canReflectDeps = require('can-reflect-dependencies'); + var valueEventBindings = require('can-event-queue/value/value'); + var stacheHelpers = require('can-stache-helpers'); + var SimpleObservable = require('can-simple-observable'); + var dev = require('can-log/dev/dev'); + var dispatchSymbol = canSymbol.for('can.dispatch'); + var setElementSymbol = canSymbol.for('can.setElement'); + var getFastPathRoot = ObservationRecorder.ignore(function (computeData) { + if (computeData.reads && computeData.reads.length === 1) { + var root = computeData.root; + if (root && root[canSymbol.for('can.getValue')]) { + root = canReflect.getValue(root); + } + return root && canReflect.isObservableLike(root) && canReflect.isMapLike(root) && typeof root[computeData.reads[0].key] !== 'function' && root; + } + return; + }); + var isEventObject = function (obj) { + return obj && typeof obj.batchNum === 'number' && typeof obj.type === 'string'; + }; + function getMutated(scopeKeyData) { + var value = ObservationRecorder.peekValue(scopeKeyData._thisArg); + return !canReflect.isPrimitive(value) ? value : scopeKeyData.root; + } + function callMutateWithRightArgs(method, mutated, reads, mutator) { + if (reads.length) { + method.call(canReflectDeps, mutated, reads[reads.length - 1].key, mutator); + } else { + method.call(canReflectDeps, mutated, mutator); + } + } + var warnOnUndefinedProperty; + var ScopeKeyData = function (scope, key, options) { + this.startingScope = scope; + this.key = key; + this.read = this.read.bind(this); + this.dispatch = this.dispatch.bind(this); + if (key === 'debugger') { + this.startingScope = { _context: stacheHelpers }; + this.read = function () { + var helperOptions = { scope: scope }; + var debuggerHelper = stacheHelpers['debugger']; + return debuggerHelper(helperOptions); + }; + } + var observation = this.observation = new Observation(this.read, this); + this.options = assign({ observation: this.observation }, options); + this.fastPath = undefined; + this.root = undefined; + this.reads = undefined; + this.setRoot = undefined; + this._thisArg = new SimpleObservable(); + this.parentHasKey = undefined; + var valueDependencies = new Set(); + valueDependencies.add(observation); + this.dependencies = { valueDependencies: valueDependencies }; + this._latestValue = undefined; + }; + valueEventBindings(ScopeKeyData.prototype); + function fastOnBoundSet_Value() { + this._value = this.newVal; + } + function fastOnBoundSetValue() { + this.value = this.newVal; + } + assign(ScopeKeyData.prototype, { + constructor: ScopeKeyData, + dispatch: function dispatch(newVal) { + var old = this.value; + this._latestValue = this.value = newVal; + this[dispatchSymbol].call(this, this.value, old); + }, + onBound: function onBound() { + this.bound = true; + canReflect.onValue(this.observation, this.dispatch, 'notify'); + var fastPathRoot = getFastPathRoot(this); + if (fastPathRoot) { + this.toFastPath(fastPathRoot); + } + this._latestValue = this.value = ObservationRecorder.peekValue(this.observation); + }, + onUnbound: function onUnbound() { + this.bound = false; + canReflect.offValue(this.observation, this.dispatch, 'notify'); + this.toSlowPath(); + }, + set: function (newVal) { + var root = this.root || this.setRoot; + if (root) { + if (this.reads.length) { + observeReader.write(root, this.reads, newVal, this.options); + } else { + canReflect.setValue(root, newVal); + } + } else { + this.startingScope.set(this.key, newVal, this.options); + } + }, + get: function () { + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (!this.bound) { + Observation.temporarilyBind(this); + } + } + if (this.bound === true && this.fastPath === true) { + return this._latestValue; + } else { + return ObservationRecorder.peekValue(this.observation); + } + }, + toFastPath: function (fastPathRoot) { + var self = this, observation = this.observation; + this.fastPath = true; + observation.dependencyChange = function (target, newVal) { + if (isEventObject(newVal)) { + throw 'no event objects!'; + } + if (target === fastPathRoot && typeof newVal !== 'function') { + self._latestValue = newVal; + this.newVal = newVal; + } else { + self.toSlowPath(); + } + return Observation.prototype.dependencyChange.apply(this, arguments); + }; + if (observation.hasOwnProperty('_value')) { + observation.onBound = fastOnBoundSet_Value; + } else { + observation.onBound = fastOnBoundSetValue; + } + }, + toSlowPath: function () { + this.observation.dependencyChange = Observation.prototype.dependencyChange; + this.observation.onBound = Observation.prototype.onBound; + this.fastPath = false; + }, + read: function () { + var data; + if (this.root) { + data = observeReader.read(this.root, this.reads, this.options); + this.thisArg = data.parent; + return data.value; + } + data = this.startingScope.read(this.key, this.options); + this.scope = data.scope; + this.reads = data.reads; + this.root = data.rootObserve; + this.setRoot = data.setRoot; + this.thisArg = data.thisArg; + this.parentHasKey = data.parentHasKey; + return data.value; + }, + hasDependencies: function () { + if (!this.bound) { + Observation.temporarilyBind(this); + } + return canReflect.valueHasDependencies(this.observation); + } + }); + Object.defineProperty(ScopeKeyData.prototype, 'thisArg', { + get: function () { + return this._thisArg.get(); + }, + set: function (newVal) { + this._thisArg.set(newVal); + } + }); + var scopeKeyDataPrototype = { + 'can.getValue': ScopeKeyData.prototype.get, + 'can.setValue': ScopeKeyData.prototype.set, + 'can.valueHasDependencies': ScopeKeyData.prototype.hasDependencies, + 'can.getValueDependencies': function () { + return this.dependencies; + }, + 'can.getPriority': function () { + return canReflect.getPriority(this.observation); + }, + 'can.setPriority': function (newPriority) { + canReflect.setPriority(this.observation, newPriority); + }, + 'can.setElement': function (element) { + this.observation[setElementSymbol](element); + } + }; + canReflect.assignSymbols(ScopeKeyData.prototype, scopeKeyDataPrototype); + Object.defineProperty(ScopeKeyData.prototype, 'compute', { + get: function () { + var compute = makeComputeLike(this); + Object.defineProperty(this, 'compute', { + value: compute, + writable: false, + configurable: false + }); + return compute; + }, + configurable: true + }); + Object.defineProperty(ScopeKeyData.prototype, 'initialValue', { + get: function () { + if (!this.bound) { + Observation.temporarilyBind(this); + } + return ObservationRecorder.peekValue(this); + }, + set: function () { + throw new Error('initialValue should not be set'); + }, + configurable: true + }); + module.exports = ScopeKeyData; +}); +/*can-view-scope@4.13.6#compute_data*/ +define('can-view-scope@4.13.6#compute_data', [ + 'require', + 'exports', + 'module', + './scope-key-data' +], function (require, exports, module) { + 'use strict'; + var ScopeKeyData = require('./scope-key-data'); + module.exports = function (scope, key, options) { + return new ScopeKeyData(scope, key, options || { args: [] }); + }; +}); +/*can-view-scope@4.13.6#let-context*/ +define('can-view-scope@4.13.6#let-context', [ + 'require', + 'exports', + 'module', + 'can-simple-map' +], function (require, exports, module) { + var SimpleMap = require('can-simple-map'); + function objectCreateWithSymbolsAndSpecificProperties(obj, propertiesToKeep) { + var newObj = {}; + if ('getOwnPropertySymbols' in Object) { + Object.getOwnPropertySymbols(obj).forEach(function (key) { + newObj[key] = obj[key]; + }); + } + Object.getOwnPropertyNames(obj).forEach(function (key) { + if (propertiesToKeep.indexOf(key) >= 0 || key.indexOf('@@symbol') === 0) { + newObj[key] = obj[key]; + } + }); + return Object.create(newObj); + } + var LetContext = SimpleMap.extend('LetContext', {}); + LetContext.prototype = objectCreateWithSymbolsAndSpecificProperties(SimpleMap.prototype, [ + 'setup', + 'attr', + 'serialize', + 'get', + 'set', + 'log', + 'dispatch', + 'constructorExtends', + 'newInstance', + '_inherit', + '_defineProperty', + '_overwrite', + 'instance', + 'extend', + 'ReturnValue', + 'setup', + 'init' + ]); + LetContext.prototype.constructor = LetContext; + module.exports = LetContext; +}); +/*can-view-scope@4.13.6#can-view-scope*/ +define('can-view-scope@4.13.6#can-view-scope', [ + 'require', + 'exports', + 'module', + 'can-stache-key', + 'can-observation-recorder', + './template-context', + './compute_data', + 'can-assign', + 'can-namespace', + 'can-reflect', + 'can-log/dev/dev', + 'can-define-lazy-value', + 'can-stache-helpers', + './let-context' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var stacheKey = require('can-stache-key'); + var ObservationRecorder = require('can-observation-recorder'); + var TemplateContext = require('./template-context'); + var makeComputeData = require('./compute_data'); + var assign = require('can-assign'); + var namespace = require('can-namespace'); + var canReflect = require('can-reflect'); + var canLog = require('can-log/dev/dev'); + var defineLazyValue = require('can-define-lazy-value'); + var stacheHelpers = require('can-stache-helpers'); + var LetContext = require('./let-context'); + function canHaveProperties(obj) { + return obj != null; + } + function returnFalse() { + return false; + } + function Scope(context, parent, meta) { + this._context = context; + this._parent = parent; + this._meta = meta || {}; + this.__cache = {}; + } + var parentContextSearch = /(\.\.\/)|(\.\/)|(this[\.@])/g; + assign(Scope, { + read: stacheKey.read, + TemplateContext: TemplateContext, + keyInfo: function (attr) { + if (attr === './') { + attr = 'this'; + } + var info = { remainingKey: attr }; + info.isScope = attr === 'scope'; + if (info.isScope) { + return info; + } + var firstSix = attr.substr(0, 6); + info.isInScope = firstSix === 'scope.' || firstSix === 'scope@'; + if (info.isInScope) { + info.remainingKey = attr.substr(6); + return info; + } else if (firstSix === 'scope/') { + info.walkScope = true; + info.remainingKey = attr.substr(6); + return info; + } else if (attr.substr(0, 7) === '@scope/') { + info.walkScope = true; + info.remainingKey = attr.substr(7); + return info; + } + info.parentContextWalkCount = 0; + info.remainingKey = attr.replace(parentContextSearch, function (token, parentContext, dotSlash, thisContext, index) { + info.isContextBased = true; + if (parentContext !== undefined) { + info.parentContextWalkCount++; + } + return ''; + }); + if (info.remainingKey === '..') { + info.parentContextWalkCount++; + info.remainingKey = 'this'; + } else if (info.remainingKey === '.' || info.remainingKey === '') { + info.remainingKey = 'this'; + } + if (info.remainingKey === 'this') { + info.isContextBased = true; + } + return info; + }, + isTemplateContextOrCanNotHaveProperties: function (currentScope) { + var currentContext = currentScope._context; + if (currentContext instanceof TemplateContext) { + return true; + } else if (!canHaveProperties(currentContext)) { + return true; + } + return false; + }, + shouldSkipIfSpecial: function (currentScope) { + var isSpecialContext = currentScope._meta.special === true; + if (isSpecialContext === true) { + return true; + } + if (Scope.isTemplateContextOrCanNotHaveProperties(currentScope)) { + return true; + } + return false; + }, + shouldSkipEverythingButSpecial: function (currentScope) { + var isSpecialContext = currentScope._meta.special === true; + if (isSpecialContext === false) { + return true; + } + if (Scope.isTemplateContextOrCanNotHaveProperties(currentScope)) { + return true; + } + return false; + }, + makeShouldExitOnSecondNormalContext: function () { + var foundNormalContext = false; + return function shouldExitOnSecondNormalContext(currentScope) { + var isNormalContext = !currentScope.isSpecial(); + var shouldExit = isNormalContext && foundNormalContext; + if (isNormalContext) { + foundNormalContext = true; + } + return shouldExit; + }; + }, + makeShouldExitAfterFirstNormalContext: function () { + var foundNormalContext = false; + return function shouldExitAfterFirstNormalContext(currentScope) { + if (foundNormalContext) { + return true; + } + var isNormalContext = !currentScope.isSpecial(); + if (isNormalContext) { + foundNormalContext = true; + } + return false; + }; + }, + makeShouldSkipSpecialContexts: function (parentContextWalkCount) { + var walkCount = parentContextWalkCount || 0; + return function shouldSkipSpecialContexts(currentScope) { + if (walkCount < 0 && currentScope._meta.notContext) { + return false; + } + if (currentScope.isSpecial()) { + return true; + } + walkCount--; + if (walkCount < 0) { + return false; + } + return true; + }; + } + }); + assign(Scope.prototype, { + add: function (context, meta) { + if (context !== this._context) { + return new this.constructor(context, this, meta); + } else { + return this; + } + }, + find: function (attr, options) { + var keyReads = stacheKey.reads(attr); + var howToRead = { + shouldExit: returnFalse, + shouldSkip: Scope.shouldSkipIfSpecial, + shouldLookForHelper: true, + read: stacheKey.read + }; + var result = this._walk(keyReads, options, howToRead); + return result.value; + }, + readFromSpecialContext: function (key) { + return this._walk([{ + key: key, + at: false + }], { special: true }, { + shouldExit: returnFalse, + shouldSkip: Scope.shouldSkipEverythingButSpecial, + shouldLookForHelper: false, + read: stacheKey.read + }); + }, + readFromTemplateContext: function (key, readOptions) { + var keyReads = stacheKey.reads(key); + return stacheKey.read(this.templateContext, keyReads, readOptions); + }, + read: function (attr, options) { + options = options || {}; + return this.readKeyInfo(Scope.keyInfo(attr), options || {}); + }, + readKeyInfo: function (keyInfo, options) { + var readValue, keyReads, howToRead = { read: options.read || stacheKey.read }; + if (keyInfo.isScope) { + return { value: this }; + } else if (keyInfo.isInScope) { + keyReads = stacheKey.reads(keyInfo.remainingKey); + readValue = stacheKey.read(this, keyReads, options); + if (typeof readValue.value === 'undefined' && !readValue.parentHasKey) { + readValue = this.readFromTemplateContext(keyInfo.remainingKey, options); + } + return assign(readValue, { thisArg: keyReads.length > 0 ? readValue.parent : undefined }); + } else if (keyInfo.isContextBased) { + if (keyInfo.remainingKey !== 'this') { + keyReads = stacheKey.reads(keyInfo.remainingKey); + } else { + keyReads = []; + } + howToRead.shouldExit = Scope.makeShouldExitOnSecondNormalContext(); + howToRead.shouldSkip = Scope.makeShouldSkipSpecialContexts(keyInfo.parentContextWalkCount); + howToRead.shouldLookForHelper = true; + return this._walk(keyReads, options, howToRead); + } else if (keyInfo.walkScope) { + howToRead.shouldExit = returnFalse; + howToRead.shouldSkip = Scope.shouldSkipIfSpecial; + howToRead.shouldLookForHelper = true; + keyReads = stacheKey.reads(keyInfo.remainingKey); + return this._walk(keyReads, options, howToRead); + } else { + keyReads = stacheKey.reads(keyInfo.remainingKey); + var isSpecialRead = options && options.special === true; + howToRead.shouldExit = Scope.makeShouldExitOnSecondNormalContext(); + howToRead.shouldSkip = isSpecialRead ? Scope.shouldSkipEverythingButSpecial : Scope.shouldSkipIfSpecial; + howToRead.shouldLookForHelper = isSpecialRead ? false : true; + return this._walk(keyReads, options, howToRead); + } + }, + _walk: function (keyReads, options, howToRead) { + var currentScope = this, currentContext, undefinedObserves = [], currentObserve, currentReads, setObserveDepth = -1, currentSetReads, currentSetObserve, readOptions = assign({ + foundObservable: function (observe, nameIndex) { + currentObserve = observe; + currentReads = keyReads.slice(nameIndex); + }, + earlyExit: function (parentValue, nameIndex) { + var isVariableScope = currentScope._meta.variable === true, updateSetObservable = false; + if (isVariableScope === true && nameIndex === 0) { + updateSetObservable = canReflect.hasKey(parentValue, keyReads[nameIndex].key); + } else { + updateSetObservable = nameIndex > setObserveDepth || nameIndex === setObserveDepth && (typeof parentValue === 'object' && canReflect.hasOwnKey(parentValue, keyReads[nameIndex].key)); + } + if (updateSetObservable) { + currentSetObserve = currentObserve; + currentSetReads = currentReads; + setObserveDepth = nameIndex; + } + } + }, options); + var isRecording = ObservationRecorder.isRecording(), readAContext = false; + while (currentScope) { + if (howToRead.shouldSkip(currentScope) === true) { + currentScope = currentScope._parent; + continue; + } + if (howToRead.shouldExit(currentScope) === true) { + break; + } + readAContext = true; + currentContext = currentScope._context; + var getObserves = ObservationRecorder.trap(); + var data = howToRead.read(currentContext, keyReads, readOptions); + var observes = getObserves(); + if (data.value !== undefined || data.parentHasKey) { + if (!observes.length && isRecording) { + currentObserve = data.parent; + currentReads = keyReads.slice(keyReads.length - 1); + } else { + ObservationRecorder.addMany(observes); + } + return { + scope: currentScope, + rootObserve: currentObserve, + value: data.value, + reads: currentReads, + thisArg: data.parent, + parentHasKey: data.parentHasKey + }; + } else { + undefinedObserves.push.apply(undefinedObserves, observes); + } + currentScope = currentScope._parent; + } + if (howToRead.shouldLookForHelper) { + var helper = this.getHelperOrPartial(keyReads); + if (helper && helper.value) { + return { value: helper.value }; + } + } + ObservationRecorder.addMany(undefinedObserves); + return { + setRoot: currentSetObserve, + reads: currentSetReads, + value: undefined, + noContextAvailable: !readAContext + }; + }, + getDataForScopeSet: function getDataForScopeSet(key, options) { + var keyInfo = Scope.keyInfo(key); + var firstSearchedContext; + var opts = assign({ + read: function (context, keys) { + if (firstSearchedContext === undefined && !(context instanceof LetContext)) { + firstSearchedContext = context; + } + if (keys.length > 1) { + var parentKeys = keys.slice(0, keys.length - 1); + var parent = stacheKey.read(context, parentKeys, options).value; + if (parent != null && canReflect.hasKey(parent, keys[keys.length - 1].key)) { + return { + parent: parent, + parentHasKey: true, + value: undefined + }; + } else { + return {}; + } + } else if (keys.length === 1) { + if (canReflect.hasKey(context, keys[0].key)) { + return { + parent: context, + parentHasKey: true, + value: undefined + }; + } else { + return {}; + } + } else { + return { value: context }; + } + } + }, options); + var readData = this.readKeyInfo(keyInfo, opts); + if (keyInfo.remainingKey === 'this') { + return { + parent: readData.value, + how: 'setValue' + }; + } + var parent; + var props = keyInfo.remainingKey.split('.'); + var propName = props.pop(); + if (readData.thisArg) { + parent = readData.thisArg; + } else if (firstSearchedContext) { + parent = firstSearchedContext; + } + if (parent === undefined) { + return { error: 'Attempting to set a value at ' + key + ' where the context is undefined.' }; + } + if (!canReflect.isObservableLike(parent) && canReflect.isObservableLike(parent[propName])) { + if (canReflect.isMapLike(parent[propName])) { + return { + parent: parent, + key: propName, + how: 'updateDeep', + warn: 'can-view-scope: Merging data into "' + propName + '" because its parent is non-observable' + }; + } else if (canReflect.isValueLike(parent[propName])) { + return { + parent: parent, + key: propName, + how: 'setValue' + }; + } else { + return { + parent: parent, + how: 'write', + key: propName, + passOptions: true + }; + } + } else { + return { + parent: parent, + how: 'write', + key: propName, + passOptions: true + }; + } + }, + getHelper: function (keyReads) { + console.warn('.getHelper is deprecated, use .getHelperOrPartial'); + return this.getHelperOrPartial(keyReads); + }, + getHelperOrPartial: function (keyReads) { + var scope = this, context, helper; + while (scope) { + context = scope._context; + if (context instanceof TemplateContext) { + helper = stacheKey.read(context.helpers, keyReads, { proxyMethods: false }); + if (helper.value !== undefined) { + return helper; + } + helper = stacheKey.read(context.partials, keyReads, { proxyMethods: false }); + if (helper.value !== undefined) { + return helper; + } + } + scope = scope._parent; + } + return stacheKey.read(stacheHelpers, keyReads, { proxyMethods: false }); + }, + get: function (key, options) { + options = assign({ isArgument: true }, options); + var res = this.read(key, options); + return res.value; + }, + peek: ObservationRecorder.ignore(function (key, options) { + return this.get(key, options); + }), + peak: ObservationRecorder.ignore(function (key, options) { + return this.peek(key, options); + }), + getScope: function (tester) { + var scope = this; + while (scope) { + if (tester(scope)) { + return scope; + } + scope = scope._parent; + } + }, + getContext: function (tester) { + var res = this.getScope(tester); + return res && res._context; + }, + getTemplateContext: function () { + var lastScope; + var templateContext = this.getScope(function (scope) { + lastScope = scope; + return scope._context instanceof TemplateContext; + }); + if (!templateContext) { + templateContext = new Scope(new TemplateContext()); + lastScope._parent = templateContext; + } + return templateContext; + }, + addTemplateContext: function () { + return this.add(new TemplateContext()); + }, + addLetContext: function (values) { + return this.add(new LetContext(values || {}), { variable: true }); + }, + getRoot: function () { + var cur = this, child = this; + while (cur._parent) { + child = cur; + cur = cur._parent; + } + if (cur._context instanceof TemplateContext) { + cur = child; + } + return cur._context; + }, + getViewModel: function () { + var vmScope = this.getScope(function (scope) { + return scope._meta.viewModel; + }); + return vmScope && vmScope._context; + }, + getTop: function () { + var top; + this.getScope(function (scope) { + if (scope._meta.viewModel) { + top = scope; + } + return false; + }); + return top && top._context; + }, + getPathsForKey: function getPathsForKey(key) { + }, + hasKey: function hasKey(key) { + var reads = stacheKey.reads(key); + var readValue; + if (reads[0].key === 'scope') { + readValue = stacheKey.read(this, reads.slice(1), key); + } else { + readValue = stacheKey.read(this._context, reads, key); + } + return readValue.foundLastParent && readValue.parentHasKey; + }, + set: function (key, value, options) { + options = options || {}; + var data = this.getDataForScopeSet(key, options); + var parent = data.parent; + if (data.warn) { + canLog.warn(data.warn); + } + switch (data.how) { + case 'set': + parent.set(data.key, value, data.passOptions ? options : undefined); + break; + case 'write': + stacheKey.write(parent, data.key, value, options); + break; + case 'setValue': + canReflect.setValue('key' in data ? parent[data.key] : parent, value); + break; + case 'setKeyValue': + canReflect.setKeyValue(parent, data.key, value); + break; + case 'updateDeep': + canReflect.updateDeep(parent[data.key], value); + break; + } + }, + attr: ObservationRecorder.ignore(function (key, value, options) { + canLog.warn('can-view-scope::attr is deprecated, please use peek, get or set'); + options = assign({ isArgument: true }, options); + if (arguments.length === 2) { + return this.set(key, value, options); + } else { + return this.get(key, options); + } + }), + computeData: function (key, options) { + return makeComputeData(this, key, options); + }, + compute: function (key, options) { + return this.computeData(key, options).compute; + }, + cloneFromRef: function () { + var scopes = []; + var scope = this, context, parent; + while (scope) { + context = scope._context; + if (context instanceof TemplateContext) { + parent = scope._parent; + break; + } + scopes.unshift(scope); + scope = scope._parent; + } + if (parent) { + scopes.forEach(function (scope) { + parent = parent.add(scope._context, scope._meta); + }); + return parent; + } else { + return this; + } + }, + isSpecial: function () { + return this._meta.notContext || this._meta.special || this._context instanceof TemplateContext || this._meta.variable; + } + }); + Scope.prototype._read = Scope.prototype._walk; + canReflect.assignSymbols(Scope.prototype, { 'can.hasKey': Scope.prototype.hasKey }); + var templateContextPrimitives = [ + 'filename', + 'lineNumber' + ]; + templateContextPrimitives.forEach(function (key) { + Object.defineProperty(Scope.prototype, key, { + get: function () { + return this.readFromTemplateContext(key).value; + }, + set: function (val) { + this.templateContext[key] = val; + } + }); + }); + defineLazyValue(Scope.prototype, 'templateContext', function () { + return this.getTemplateContext()._context; + }); + defineLazyValue(Scope.prototype, 'root', function () { + canLog.warn('`scope.root` is deprecated. Use either `scope.top`: https://canjs.com/doc/can-stache/keys/scope.html#scope_top or `scope.vm`: https://canjs.com/doc/can-stache/keys/scope.html#scope_vm instead.'); + return this.getRoot(); + }); + defineLazyValue(Scope.prototype, 'vm', function () { + return this.getViewModel(); + }); + defineLazyValue(Scope.prototype, 'top', function () { + return this.getTop(); + }); + defineLazyValue(Scope.prototype, 'helpers', function () { + return stacheHelpers; + }); + var specialKeywords = [ + 'index', + 'key', + 'element', + 'event', + 'viewModel', + 'arguments', + 'helperOptions', + 'args' + ]; + specialKeywords.forEach(function (key) { + Object.defineProperty(Scope.prototype, key, { + get: function () { + return this.readFromSpecialContext(key).value; + } + }); + }); + namespace.view = namespace.view || {}; + module.exports = namespace.view.Scope = Scope; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#location/location*/ +define('can-globals@1.2.2#location/location', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + require('can-globals/global/global'); + var globals = require('can-globals/can-globals-instance'); + globals.define('location', function () { + return globals.getKeyValue('global').location; + }); + module.exports = globals.makeExport('location'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#mutation-observer/mutation-observer*/ +define('can-globals@1.2.2#mutation-observer/mutation-observer', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + require('can-globals/global/global'); + var globals = require('can-globals/can-globals-instance'); + globals.define('MutationObserver', function () { + var GLOBAL = globals.getKeyValue('global'); + return GLOBAL.MutationObserver || GLOBAL.WebKitMutationObserver || GLOBAL.MozMutationObserver; + }); + module.exports = globals.makeExport('MutationObserver'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#custom-elements/custom-elements*/ +define('can-globals@1.2.2#custom-elements/custom-elements', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-globals/can-globals-instance' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + require('can-globals/global/global'); + var globals = require('can-globals/can-globals-instance'); + globals.define('customElements', function () { + var GLOBAL = globals.getKeyValue('global'); + return GLOBAL.customElements; + }); + module.exports = globals.makeExport('customElements'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#can-globals*/ +define('can-globals@1.2.2#can-globals', [ + 'require', + 'exports', + 'module', + 'can-globals/can-globals-instance', + './global/global', + './document/document', + './location/location', + './mutation-observer/mutation-observer', + './is-browser-window/is-browser-window', + './is-node/is-node', + './custom-elements/custom-elements' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals/can-globals-instance'); + require('./global/global'); + require('./document/document'); + require('./location/location'); + require('./mutation-observer/mutation-observer'); + require('./is-browser-window/is-browser-window'); + require('./is-node/is-node'); + require('./custom-elements/custom-elements'); + module.exports = globals; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-mutate@2.0.8#-util*/ +define('can-dom-mutate@2.0.8#-util', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + function eliminate(array, item) { + var index = array.indexOf(item); + if (index >= 0) { + array.splice(index, 1); + } + } + function wasNotInSet(item, set) { + var inSet = set.has(item); + if (inSet === false) { + set.add(item); + } + return !inSet; + } + function contains(parent, child) { + if (child && child.nodeType === Node.TEXT_NODE) { + return contains(parent, child.parentNode); + } + if (parent.contains) { + return parent.contains(child); + } + if (parent.nodeType === Node.DOCUMENT_NODE && parent.documentElement) { + return contains(parent.documentElement, child); + } else { + child = child.parentNode; + if (child === parent) { + return true; + } + return false; + } + } + function isDocumentElement(node) { + return getDocument().documentElement === node; + } + function isFragment(node) { + return !!(node && node.nodeType === 11); + } + function isElementNode(node) { + return !!(node && node.nodeType === 1); + } + function getChildren(parentNode) { + var nodes = []; + var node = parentNode.firstChild; + while (node) { + nodes.push(node); + node = node.nextSibling; + } + return nodes; + } + function getParents(node) { + var nodes; + if (isFragment(node)) { + nodes = getChildren(node); + } else { + nodes = [node]; + } + return nodes; + } + function getNodesLegacyB(node) { + var skip, tmp; + var depth = 0; + var items = isFragment(node) ? [] : [node]; + if (node.firstChild == null) { + return items; + } + do { + if (!skip && (tmp = node.firstChild)) { + depth++; + items.push(tmp); + } else if (tmp = node.nextSibling) { + skip = false; + items.push(tmp); + } else { + tmp = node.parentNode; + depth--; + skip = true; + } + node = tmp; + } while (depth > 0); + return items; + } + function treeWalkerFilterFunction() { + return NodeFilter.FILTER_ACCEPT; + } + var treeWalkerFilter = treeWalkerFilterFunction; + treeWalkerFilter.acceptNode = treeWalkerFilterFunction; + function getNodesWithTreeWalker(rootNode) { + var result = isFragment(rootNode) ? [] : [rootNode]; + var walker = isElementNode(rootNode) && getDocument().createTreeWalker(rootNode, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT, treeWalkerFilter, false); + var node; + while (node = walker && walker.nextNode()) { + result.push(node); + } + return result; + } + function getAllNodes(node) { + if (getDocument().createTreeWalker !== undefined) { + return getNodesWithTreeWalker(node); + } else { + return getNodesLegacyB(node); + } + } + function subscription(fn) { + return function _subscription() { + var disposal = fn.apply(this, arguments); + var isDisposed = false; + return function _disposal() { + if (isDisposed) { + var fnName = fn.name || fn.displayName || 'an anonymous function'; + var message = 'Disposal function returned by ' + fnName + ' called more than once.'; + throw new Error(message); + } + disposal.apply(this, arguments); + isDisposed = true; + }; + }; + } + module.exports = { + eliminate: eliminate, + getDocument: getDocument, + isDocumentElement: isDocumentElement, + isFragment: isFragment, + getParents: getParents, + getAllNodes: getAllNodes, + getChildren: getChildren, + subscription: subscription, + wasNotInSet: wasNotInSet, + contains: contains + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-mutate@2.0.8#-is-connected*/ +define('can-dom-mutate@2.0.8#-is-connected', [ + 'require', + 'exports', + 'module', + 'can-globals', + './-util' +], function (require, exports, module) { + (function (global, require, exports, module) { + var globals = require('can-globals'); + var util = require('./-util'); + var contains = util.contains; + var mutate = {}; + var isConnected; + function getIsConnectedFromNode(node) { + return node.isConnected; + } + function getIsConnectedFromDocument(node) { + var doc = node.ownerDocument; + return doc === null || doc === node || contains(doc, node); + } + function setIsConnected(doc) { + if (doc) { + var node = doc.createTextNode(''); + isConnected = 'isConnected' in node.constructor.prototype ? getIsConnectedFromNode : getIsConnectedFromDocument; + if (mutate) { + mutate.isConnected = isConnected; + } + } else { + mutate.isConnected = getIsConnectedFromNode; + } + } + setIsConnected(globals.getKeyValue('document')); + globals.onKeyValue('document', setIsConnected); + module.exports = mutate; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-mutate@2.0.8#can-dom-mutate*/ +define('can-dom-mutate@2.0.8#can-dom-mutate', [ + 'require', + 'exports', + 'module', + 'can-globals', + 'can-globals/global/global', + 'can-globals/mutation-observer/mutation-observer', + 'can-namespace', + 'can-globals/document/document', + './-util', + './-is-connected' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals'); + var getRoot = require('can-globals/global/global'); + var getMutationObserver = require('can-globals/mutation-observer/mutation-observer'); + var namespace = require('can-namespace'); + var DOCUMENT = require('can-globals/document/document'); + var util = require('./-util'); + var eliminate = util.eliminate; + var subscription = util.subscription; + var isDocumentElement = util.isDocumentElement; + var getAllNodes = util.getAllNodes; + var domMutate, dispatchNodeInserted, dispatchNodeConnected, dispatchGlobalConnected, dispatchNodeRemoved, dispatchNodeDisconnected, dispatchGlobalDisconnected, dispatchAttributeChange, dispatchGlobalAttributeChange; + var dataStore = new WeakMap(); + var isConnected = require('./-is-connected'); + var queue; + function getRelatedData(node, key) { + var data = dataStore.get(node); + if (data) { + return data[key]; + } + } + function setRelatedData(node, key, targetListenersMap) { + var data = dataStore.get(node); + if (!data) { + data = {}; + dataStore.set(node, data); + } + data[key] = targetListenersMap; + } + function deleteRelatedData(node, key) { + var data = dataStore.get(node); + return delete data[key]; + } + function toMutationEvent(node, mutation) { + return { + target: node, + sourceMutation: mutation + }; + } + function getDocumentListeners(target, key) { + var doc = DOCUMENT(); + var data = getRelatedData(doc, key); + if (data) { + return data.listeners; + } + } + function getTargetListeners(target, key) { + var doc = DOCUMENT(); + var targetListenersMap = getRelatedData(doc, key); + if (!targetListenersMap) { + return; + } + return targetListenersMap.get(target); + } + function addTargetListener(target, key, listener) { + var doc = DOCUMENT(); + var targetListenersMap = getRelatedData(doc, key); + if (!targetListenersMap) { + targetListenersMap = new WeakMap(); + setRelatedData(doc, key, targetListenersMap); + } + var targetListeners = targetListenersMap.get(target); + if (!targetListeners) { + targetListeners = []; + targetListenersMap.set(target, targetListeners); + } + targetListeners.push(listener); + } + function removeTargetListener(target, key, listener) { + var doc = DOCUMENT(); + var targetListenersMap = getRelatedData(doc, key); + if (!targetListenersMap) { + return; + } + var targetListeners = targetListenersMap.get(target); + if (!targetListeners) { + return; + } + eliminate(targetListeners, listener); + if (targetListeners.length === 0) { + targetListenersMap['delete'](target); + if (targetListenersMap.size === 0) { + deleteRelatedData(doc, key); + } + } + } + var promise = Promise.resolve(); + function nextTick(handler) { + promise.then(handler); + } + function flushCallbacks(callbacks, arg) { + var callbacksCount = callbacks.length; + var safeCallbacks = callbacks.slice(0); + for (var c = 0; c < callbacksCount; c++) { + safeCallbacks[c](arg); + } + } + function dispatch(getListeners, targetKey) { + return function dispatchEvents(event) { + var targetListeners = getListeners(event.target, targetKey); + if (targetListeners) { + flushCallbacks(targetListeners, event); + } + }; + } + var count = 0; + function observeMutations(target, observerKey, config, handler) { + var observerData = getRelatedData(target, observerKey); + if (!observerData) { + observerData = { observingCount: 0 }; + setRelatedData(target, observerKey, observerData); + } + var setupObserver = function () { + if (observerData.observer) { + observerData.observer.disconnect(); + observerData.observer = null; + } + var MutationObserver = getMutationObserver(); + if (MutationObserver) { + var Node = getRoot().Node; + var isRealNode = !!(Node && target instanceof Node); + if (isRealNode) { + var targetObserver = new MutationObserver(handler); + targetObserver.id = count++; + targetObserver.observe(target, config); + observerData.observer = targetObserver; + } + } + }; + if (observerData.observingCount === 0) { + globals.onKeyValue('MutationObserver', setupObserver); + setupObserver(); + } + observerData.observingCount++; + return function stopObservingMutations() { + var observerData = getRelatedData(target, observerKey); + if (observerData) { + observerData.observingCount--; + if (observerData.observingCount <= 0) { + if (observerData.observer) { + observerData.observer.disconnect(); + } + deleteRelatedData(target, observerKey); + globals.offKeyValue('MutationObserver', setupObserver); + } + } + }; + } + var treeMutationConfig = { + subtree: true, + childList: true + }; + var attributeMutationConfig = { + attributes: true, + attributeOldValue: true + }; + function addNodeListener(listenerKey, observerKey, isAttributes) { + return subscription(function _addNodeListener(target, listener) { + if (target.nodeType === 11) { + return Function.prototype; + } + var stopObserving; + if (isAttributes) { + stopObserving = observeMutations(target, observerKey, attributeMutationConfig, queue.enqueueAndFlushMutations); + } else { + stopObserving = observeMutations(DOCUMENT(), observerKey, treeMutationConfig, queue.enqueueAndFlushMutations); + } + addTargetListener(target, listenerKey, listener); + return function removeNodeListener() { + if (stopObserving) { + stopObserving(); + } + removeTargetListener(target, listenerKey, listener); + }; + }); + } + function addGlobalListener(globalDataKey, addNodeListener) { + return subscription(function addGlobalGroupListener(documentElement, listener) { + if (!isDocumentElement(documentElement)) { + throw new Error('Global mutation listeners must pass a documentElement'); + } + var doc = DOCUMENT(); + var documentData = getRelatedData(doc, globalDataKey); + if (!documentData) { + documentData = { listeners: [] }; + setRelatedData(doc, globalDataKey, documentData); + } + var listeners = documentData.listeners; + if (listeners.length === 0) { + documentData.removeListener = addNodeListener(doc, function () { + }); + } + listeners.push(listener); + return function removeGlobalGroupListener() { + var documentData = getRelatedData(doc, globalDataKey); + if (!documentData) { + return; + } + var listeners = documentData.listeners; + eliminate(listeners, listener); + if (listeners.length === 0) { + documentData.removeListener(); + deleteRelatedData(doc, globalDataKey); + } + }; + }); + } + var domMutationPrefix = 'domMutation'; + var connectedDataKey = domMutationPrefix + 'ConnectedData'; + var disconnectedDataKey = domMutationPrefix + 'DisconnectedData'; + var insertedDataKey = domMutationPrefix + 'InsertedData'; + var removedDataKey = domMutationPrefix + 'RemovedData'; + var attributeChangeDataKey = domMutationPrefix + 'AttributeChangeData'; + var documentConnectedDataKey = domMutationPrefix + 'DocumentConnectedData'; + var documentDisconnectedDataKey = domMutationPrefix + 'DocumentDisconnectedData'; + var documentAttributeChangeDataKey = domMutationPrefix + 'DocumentAttributeChangeData'; + var treeDataKey = domMutationPrefix + 'TreeData'; + var attributeDataKey = domMutationPrefix + 'AttributeData'; + dispatchNodeInserted = dispatch(getTargetListeners, insertedDataKey); + dispatchNodeConnected = dispatch(getTargetListeners, connectedDataKey); + dispatchGlobalConnected = dispatch(getDocumentListeners, documentConnectedDataKey); + dispatchNodeRemoved = dispatch(getTargetListeners, removedDataKey); + dispatchNodeDisconnected = dispatch(getTargetListeners, disconnectedDataKey); + dispatchGlobalDisconnected = dispatch(getDocumentListeners, documentDisconnectedDataKey); + dispatchAttributeChange = dispatch(getTargetListeners, attributeChangeDataKey); + dispatchGlobalAttributeChange = dispatch(getDocumentListeners, documentAttributeChangeDataKey); + var addNodeConnectedListener = addNodeListener(connectedDataKey, treeDataKey); + var addNodeDisconnectedListener = addNodeListener(disconnectedDataKey, treeDataKey); + var addNodeInsertedListener = addNodeListener(insertedDataKey, treeDataKey); + var addNodeRemovedListener = addNodeListener(removedDataKey, treeDataKey); + var addNodeAttributeChangeListener = addNodeListener(attributeChangeDataKey, attributeDataKey, true); + var addConnectedListener = addGlobalListener(documentConnectedDataKey, addNodeConnectedListener); + var addDisconnectedListener = addGlobalListener(documentDisconnectedDataKey, addNodeDisconnectedListener); + var addAttributeChangeListener = addGlobalListener(documentAttributeChangeDataKey, addNodeAttributeChangeListener); + function dispatchTreeMutation(mutation, processedState) { + var wasConnected = mutation.isConnected === true || mutation.isConnected === undefined; + var removedCount = mutation.removedNodes.length; + for (var r = 0; r < removedCount; r++) { + var removedNodes = getAllNodes(mutation.removedNodes[r]); + removedNodes.forEach(function (node) { + var event = toMutationEvent(node, mutation); + if (util.wasNotInSet(node, processedState.removed)) { + dispatchNodeRemoved(event); + } + if (wasConnected && util.wasNotInSet(node, processedState.disconnected)) { + dispatchNodeDisconnected(event); + dispatchGlobalDisconnected(event); + } + }); + } + var addedCount = mutation.addedNodes.length; + for (var a = 0; a < addedCount; a++) { + var insertedNodes = getAllNodes(mutation.addedNodes[a]); + insertedNodes.forEach(function (node) { + var event = toMutationEvent(node, mutation); + if (util.wasNotInSet(node, processedState.inserted)) { + dispatchNodeInserted(event); + } + if (wasConnected && util.wasNotInSet(node, processedState.connected)) { + dispatchNodeConnected(event); + dispatchGlobalConnected(event); + } + }); + } + } + var FLUSHING_MUTATIONS = []; + var IS_FLUSHING = false; + var IS_FLUSH_PENDING = false; + var ENQUEUED_MUTATIONS = []; + queue = { + enqueueAndFlushMutations: function (mutations) { + if (IS_FLUSH_PENDING) { + FLUSHING_MUTATIONS.push.apply(FLUSHING_MUTATIONS, ENQUEUED_MUTATIONS); + IS_FLUSH_PENDING = false; + ENQUEUED_MUTATIONS = []; + } + FLUSHING_MUTATIONS.push.apply(FLUSHING_MUTATIONS, mutations); + if (IS_FLUSHING) { + return; + } + IS_FLUSHING = true; + var index = 0; + var processedState = { + connected: new Set(), + disconnected: new Set(), + inserted: new Set(), + removed: new Set() + }; + while (index < FLUSHING_MUTATIONS.length) { + var mutation = FLUSHING_MUTATIONS[index]; + if (mutation.type === 'childList') { + dispatchTreeMutation(mutation, processedState); + } else if (mutation.type === 'attributes') { + dispatchAttributeChange(mutation); + } + index++; + } + FLUSHING_MUTATIONS = []; + IS_FLUSHING = false; + }, + enqueueMutationsAndFlushAsync: function (mutations) { + ENQUEUED_MUTATIONS.push.apply(ENQUEUED_MUTATIONS, mutations); + if (!IS_FLUSH_PENDING) { + IS_FLUSH_PENDING = true; + nextTick(function () { + if (IS_FLUSH_PENDING) { + IS_FLUSH_PENDING = false; + var pending = ENQUEUED_MUTATIONS; + ENQUEUED_MUTATIONS = []; + queue.enqueueAndFlushMutations(pending); + } else { + } + }); + } + } + }; + domMutate = { + dispatchNodeInsertion: function (node, target) { + queue.enqueueMutationsAndFlushAsync([{ + type: 'childList', + target: target, + addedNodes: [node], + isConnected: isConnected.isConnected(target), + removedNodes: [] + }]); + }, + dispatchNodeRemoval: function (node, target) { + queue.enqueueMutationsAndFlushAsync([{ + type: 'childList', + target: target, + addedNodes: [], + removedNodes: [node], + isConnected: isConnected.isConnected(target) + }]); + }, + dispatchNodeAttributeChange: function (target, attributeName, oldValue) { + queue.enqueueMutationsAndFlushAsync([{ + type: 'attributes', + target: target, + attributeName: attributeName, + oldValue: oldValue + }]); + }, + onNodeConnected: addNodeConnectedListener, + onNodeInsertion: function () { + console.warn('can-dom-mutate: Use onNodeConnected instead of onNodeInsertion'); + return addNodeConnectedListener.apply(this, arguments); + }, + onNodeDisconnected: addNodeDisconnectedListener, + onNodeRemoval: function () { + console.warn('can-dom-mutate: Use onNodeDisconnected instead of onNodeRemoval'); + return addNodeDisconnectedListener.apply(this, arguments); + }, + onNodeAttributeChange: addNodeAttributeChangeListener, + onDisconnected: addDisconnectedListener, + onRemoval: function () { + console.warn('can-dom-mutate: Use onDisconnected instead of onRemoval'); + return addDisconnectedListener.apply(this, arguments); + }, + onConnected: addConnectedListener, + onInsertion: function () { + console.warn('can-dom-mutate: Use onConnected instead of onInsertion'); + return addConnectedListener.apply(this, arguments); + }, + onAttributeChange: addAttributeChangeListener, + flushRecords: function (doc) { + doc = doc || DOCUMENT(); + var data = dataStore.get(doc), records = []; + if (data) { + if (data.domMutationTreeData && data.domMutationTreeData.observer) { + records = data.domMutationTreeData.observer.takeRecords(); + } + } + queue.enqueueAndFlushMutations(records); + }, + onNodeInserted: addNodeInsertedListener, + onNodeRemoved: addNodeRemovedListener + }; + module.exports = namespace.domMutate = domMutate; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-mutate@2.0.8#node/node*/ +define('can-dom-mutate@2.0.8#node/node', [ + 'require', + 'exports', + 'module', + 'can-globals', + 'can-namespace', + '../can-dom-mutate', + '../-util', + '../-is-connected' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('can-globals'); + var namespace = require('can-namespace'); + var domMutate = require('../can-dom-mutate'); + var util = require('../-util'); + var getParents = util.getParents; + var contains = util.contains; + var isConnected = require('../-is-connected'); + var compat = { + replaceChild: function (newChild, oldChild) { + var newChildren = getParents(newChild); + var result = this.replaceChild(newChild, oldChild); + domMutate.dispatchNodeRemoval(oldChild, this); + for (var i = 0; i < newChildren.length; i++) { + domMutate.dispatchNodeInsertion(newChildren[i], this); + } + return result; + }, + setAttribute: function (name, value) { + var oldAttributeValue = this.getAttribute(name); + var result = this.setAttribute(name, value); + var newAttributeValue = this.getAttribute(name); + if (oldAttributeValue !== newAttributeValue) { + domMutate.dispatchNodeAttributeChange(this, name, oldAttributeValue); + } + return result; + }, + setAttributeNS: function (namespace, name, value) { + var oldAttributeValue = this.getAttribute(name); + var result = this.setAttributeNS(namespace, name, value); + var newAttributeValue = this.getAttribute(name); + if (oldAttributeValue !== newAttributeValue) { + domMutate.dispatchNodeAttributeChange(this, name, oldAttributeValue); + } + return result; + }, + removeAttribute: function (name) { + var oldAttributeValue = this.getAttribute(name); + var result = this.removeAttribute(name); + if (oldAttributeValue) { + domMutate.dispatchNodeAttributeChange(this, name, oldAttributeValue); + } + return result; + } + }; + var compatData = [ + [ + 'appendChild', + 'Insertion' + ], + [ + 'insertBefore', + 'Insertion' + ], + [ + 'removeChild', + 'Removal' + ] + ]; + compatData.forEach(function (pair) { + var nodeMethod = pair[0]; + var dispatchMethod = 'dispatchNode' + pair[1]; + compat[nodeMethod] = function (node) { + var nodes = getParents(node); + var result = this[nodeMethod].apply(this, arguments); + for (var i = 0; i < nodes.length; i++) { + domMutate[dispatchMethod](nodes[i], this); + } + return result; + }; + }); + var normal = {}; + var nodeMethods = [ + 'appendChild', + 'insertBefore', + 'removeChild', + 'replaceChild', + 'setAttribute', + 'setAttributeNS', + 'removeAttribute' + ]; + nodeMethods.forEach(function (methodName) { + normal[methodName] = function () { + if (isConnected.isConnected(this)) { + return this[methodName].apply(this, arguments); + } else { + return compat[methodName].apply(this, arguments); + } + }; + }); + var mutate = {}; + function setMutateStrategy(observer) { + var strategy = observer ? normal : compat; + for (var key in strategy) { + mutate[key] = strategy[key]; + } + } + var mutationObserverKey = 'MutationObserver'; + setMutateStrategy(globals.getKeyValue(mutationObserverKey)); + globals.onKeyValue(mutationObserverKey, setMutateStrategy); + module.exports = namespace.domMutateNode = domMutate.node = mutate; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-mutate@2.0.8#node*/ +define('can-dom-mutate@2.0.8#node', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './node/node' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var node = require('./node/node'); + module.exports = namespace.node = node; +}); +/*can-child-nodes@1.2.1#can-child-nodes*/ +define('can-child-nodes@1.2.1#can-child-nodes', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + function childNodes(node) { + var childNodes = node.childNodes; + if ('length' in childNodes) { + return childNodes; + } else { + var cur = node.firstChild; + var nodes = []; + while (cur) { + nodes.push(cur); + cur = cur.nextSibling; + } + return nodes; + } + } + module.exports = namespace.childNodes = childNodes; +}); +/*can-fragment@1.3.1#can-fragment*/ +define('can-fragment@1.3.1#can-fragment', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-namespace', + 'can-reflect', + 'can-child-nodes', + 'can-symbol' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + var namespace = require('can-namespace'); + var canReflect = require('can-reflect'); + var childNodes = require('can-child-nodes'); + var canSymbol = require('can-symbol'); + var fragmentRE = /^\s*<(\w+)[^>]*>/, toString = {}.toString, toDOMSymbol = canSymbol.for('can.toDOM'); + function makeFragment(html, name, doc) { + if (name === undefined) { + name = fragmentRE.test(html) && RegExp.$1; + } + if (html && toString.call(html.replace) === '[object Function]') { + html = html.replace(/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, '<$1>'); + } + var container = doc.createElement('div'), temp = doc.createElement('div'); + if (name === 'tbody' || name === 'tfoot' || name === 'thead' || name === 'colgroup') { + temp.innerHTML = '' + html + '
      '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild; + } else if (name === 'col') { + temp.innerHTML = '' + html + '
      '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild.firstChild; + } else if (name === 'tr') { + temp.innerHTML = '' + html + '
      '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild.firstChild; + } else if (name === 'td' || name === 'th') { + temp.innerHTML = '' + html + '
      '; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild.firstChild.firstChild; + } else if (name === 'option') { + temp.innerHTML = ''; + container = temp.firstChild.nodeType === 3 ? temp.lastChild : temp.firstChild; + } else { + container.innerHTML = '' + html; + } + return [].slice.call(childNodes(container)); + } + function fragment(html, doc) { + if (html && html.nodeType === 11) { + return html; + } + if (!doc) { + doc = getDocument(); + } else if (doc.length) { + doc = doc[0]; + } + var parts = makeFragment(html, undefined, doc), frag = (doc || document).createDocumentFragment(); + for (var i = 0, length = parts.length; i < length; i++) { + frag.appendChild(parts[i]); + } + return frag; + } + var makeFrag = function (item, doc) { + var document = doc || getDocument(); + var frag; + if (!item || typeof item === 'string') { + frag = fragment(item == null ? '' : '' + item, document); + } else if (typeof item[toDOMSymbol] === 'function') { + return makeFrag(item[toDOMSymbol]()); + } else if (item.nodeType === 11) { + return item; + } else if (typeof item.nodeType === 'number') { + frag = document.createDocumentFragment(); + frag.appendChild(item); + return frag; + } else if (canReflect.isListLike(item)) { + frag = document.createDocumentFragment(); + canReflect.eachIndex(item, function (item) { + frag.appendChild(makeFrag(item)); + }); + } else { + frag = fragment('' + item, document); + } + if (!childNodes(frag).length) { + frag.appendChild(document.createTextNode('')); + } + return frag; + }; + module.exports = namespace.fragment = namespace.frag = makeFrag; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-callbacks@5.0.0#can-view-callbacks*/ +define('can-view-callbacks@5.0.0#can-view-callbacks', [ + 'require', + 'exports', + 'module', + 'can-observation-recorder', + 'can-log/dev/dev', + 'can-globals/global/global', + 'can-globals/document/document', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-namespace', + 'can-fragment', + 'can-globals', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var ObservationRecorder = require('can-observation-recorder'); + var dev = require('can-log/dev/dev'); + var getGlobal = require('can-globals/global/global'); + var getDocument = require('can-globals/document/document'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var namespace = require('can-namespace'); + var makeFrag = require('can-fragment'); + var globals = require('can-globals'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var callbackMapSymbol = canSymbol.for('can.callbackMap'); + var initializeSymbol = canSymbol.for('can.initialize'); + var tags = {}; + var automountEnabled = function () { + var document = globals.getKeyValue('document'); + if (document == null || document.documentElement == null) { + return false; + } + return document.documentElement.getAttribute('data-can-automount') !== 'false'; + }; + var renderedElements = new WeakMap(); + var mountElement = function (node) { + var tagName = node.tagName && node.tagName.toLowerCase(); + var tagHandler = tags[tagName]; + if (tagHandler) { + callbacks.tagHandler(node, tagName, {}); + } + }; + var mutationObserverEnabled = false; + var disableMutationObserver; + var enableMutationObserver = function () { + var docEl = getDocument().documentElement; + if (mutationObserverEnabled) { + if (mutationObserverEnabled === docEl) { + return; + } + disableMutationObserver(); + } + var undoOnInsertionHandler = domMutate.onConnected(docEl, function (mutation) { + mountElement(mutation.target); + }); + mutationObserverEnabled = true; + disableMutationObserver = function () { + undoOnInsertionHandler(); + mutationObserverEnabled = false; + }; + }; + var renderTagsInDocument = function (tagName) { + var nodes = getDocument().getElementsByTagName(tagName); + for (var i = 0, node; (node = nodes[i]) !== undefined; i++) { + mountElement(node); + } + }; + var attr = function (attributeName, attrHandler) { + if (attrHandler) { + if (typeof attributeName === 'string') { + attributes[attributeName] = attrHandler; + } else { + regExpAttributes.push({ + match: attributeName, + handler: attrHandler + }); + } + } else { + var cb = attributes[attributeName]; + if (!cb) { + for (var i = 0, len = regExpAttributes.length; i < len; i++) { + var attrMatcher = regExpAttributes[i]; + if (attrMatcher.match.test(attributeName)) { + return attrMatcher.handler; + } + } + } + return cb; + } + }; + var attrs = function (attrMap) { + var map = canReflect.getKeyValue(attrMap, callbackMapSymbol) || attrMap; + if (attrMaps.has(map)) { + return; + } else { + attrMaps.set(map, true); + } + canReflect.eachKey(map, function (callback, exp) { + attr(exp, callback); + }); + }; + var attributes = {}, regExpAttributes = [], attrMaps = new WeakMap(), automaticCustomElementCharacters = /[-\:]/; + var defaultCallback = function () { + }; + var tag = function (tagName, tagHandler) { + if (tagHandler) { + var validCustomElementName = automaticCustomElementCharacters.test(tagName), tagExists = typeof tags[tagName.toLowerCase()] !== 'undefined', customElementExists; + tags[tagName.toLowerCase()] = tagHandler; + if (automountEnabled()) { + var customElements = globals.getKeyValue('customElements'); + if (customElements) { + customElementExists = customElements.get(tagName.toLowerCase()); + if (validCustomElementName && !customElementExists) { + var CustomElement = function () { + return Reflect.construct(HTMLElement, [], CustomElement); + }; + CustomElement.prototype = Object.create(HTMLElement.prototype); + CustomElement.prototype.constructor = CustomElement; + CustomElement.prototype.connectedCallback = function () { + callbacks.tagHandler(this, tagName.toLowerCase(), {}); + }; + customElements.define(tagName, CustomElement); + } + } else { + enableMutationObserver(); + renderTagsInDocument(tagName); + } + } else if (mutationObserverEnabled) { + disableMutationObserver(); + } + } else { + var cb; + if (tagHandler === null) { + delete tags[tagName.toLowerCase()]; + } else { + cb = tags[tagName.toLowerCase()]; + } + if (!cb && automaticCustomElementCharacters.test(tagName)) { + cb = defaultCallback; + } + return cb; + } + }; + var callbacks = { + _tags: tags, + _attributes: attributes, + _regExpAttributes: regExpAttributes, + defaultCallback: defaultCallback, + tag: tag, + attr: attr, + attrs: attrs, + tagHandler: function (el, tagName, tagData) { + if (renderedElements.has(el)) { + return; + } + var scope = tagData.scope, helperTagCallback = scope && scope.templateContext.tags.get(tagName), tagCallback = helperTagCallback || tags[tagName] || el[initializeSymbol], res; + if (tagCallback) { + res = ObservationRecorder.ignore(tagCallback)(el, tagData); + renderedElements.set(el, true); + } else { + res = scope; + } + if (res && tagData.subtemplate) { + if (scope !== res) { + scope = scope.add(res); + } + var result = tagData.subtemplate(scope, tagData.options); + var frag = typeof result === 'string' ? makeFrag(result) : result; + domMutateNode.appendChild.call(el, frag); + } + } + }; + namespace.view = namespace.view || {}; + if (namespace.view.callbacks) { + throw new Error('You can\'t have two versions of can-view-callbacks, check your dependencies'); + } else { + module.exports = namespace.view.callbacks = callbacks; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-bind@1.5.1#can-bind*/ +define('can-bind@1.5.1#can-bind', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + 'can-namespace', + 'can-queues', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var namespace = require('can-namespace'); + var queues = require('can-queues'); + var canAssign = require('can-assign'); + var getChangesSymbol = canSymbol.for('can.getChangesDependencyRecord'); + var getValueSymbol = canSymbol.for('can.getValue'); + var onValueSymbol = canSymbol.for('can.onValue'); + var onEmitSymbol = canSymbol.for('can.onEmit'); + var offEmitSymbol = canSymbol.for('can.offEmit'); + var setValueSymbol = canSymbol.for('can.setValue'); + var canElementSymbol = canSymbol.for('can.element'); + function defaultSetValue(newValue, observable) { + canReflect.setValue(observable, newValue); + } + function onEmit(listenToObservable, updateFunction, queue) { + return listenToObservable[onEmitSymbol](updateFunction, queue); + } + function offEmit(listenToObservable, updateFunction, queue) { + return listenToObservable[offEmitSymbol](updateFunction, queue); + } + function turnOffListeningAndUpdate(listenToObservable, updateObservable, updateFunction, queue) { + var offValueOrOffEmitFn; + if (listenToObservable[onValueSymbol]) { + offValueOrOffEmitFn = canReflect.offValue; + } else if (listenToObservable[onEmitSymbol]) { + offValueOrOffEmitFn = offEmit; + } + if (offValueOrOffEmitFn) { + offValueOrOffEmitFn(listenToObservable, updateFunction, queue); + } + } + function turnOnListeningAndUpdate(listenToObservable, updateObservable, updateFunction, queue) { + var onValueOrOnEmitFn; + if (listenToObservable[onValueSymbol]) { + onValueOrOnEmitFn = canReflect.onValue; + } else if (listenToObservable[onEmitSymbol]) { + onValueOrOnEmitFn = onEmit; + } + if (onValueOrOnEmitFn) { + onValueOrOnEmitFn(listenToObservable, updateFunction, queue); + } + } + function Semaphore(binding, type) { + this.value = 0; + this._binding = binding; + this._type = type; + } + canAssign(Semaphore.prototype, { + decrement: function () { + this.value -= 1; + }, + increment: function (args) { + this._incremented = true; + this.value += 1; + } + }); + function Bind(options) { + this._options = options; + if (options.queue === undefined) { + if (options.element) { + options.queue = 'dom'; + } else { + options.queue = 'domUI'; + } + } + if (options.cycles > 0 === false) { + options.cycles = 0; + } + options.onInitDoNotUpdateChild = typeof options.onInitDoNotUpdateChild === 'boolean' ? options.onInitDoNotUpdateChild : false; + options.onInitDoNotUpdateParent = typeof options.onInitDoNotUpdateParent === 'boolean' ? options.onInitDoNotUpdateParent : false; + options.onInitSetUndefinedParentIfChildIsDefined = typeof options.onInitSetUndefinedParentIfChildIsDefined === 'boolean' ? options.onInitSetUndefinedParentIfChildIsDefined : true; + var childSemaphore = new Semaphore(this, 'child'); + var parentSemaphore = new Semaphore(this, 'parent'); + var childToParent = true; + if (typeof options.childToParent === 'boolean') { + childToParent = options.childToParent; + } else if (options.child[getValueSymbol] == null) { + childToParent = false; + } else if (options.setParent === undefined && options.parent[setValueSymbol] == null) { + childToParent = false; + } + var parentToChild = true; + if (typeof options.parentToChild === 'boolean') { + parentToChild = options.parentToChild; + } else if (options.parent[getValueSymbol] == null) { + parentToChild = false; + } else if (options.setChild === undefined && options.child[setValueSymbol] == null) { + parentToChild = false; + } + if (childToParent === false && parentToChild === false) { + throw new Error('Neither the child nor parent will be updated; this is a no-way binding'); + } + this._childToParent = childToParent; + this._parentToChild = parentToChild; + if (options.setChild === undefined) { + options.setChild = defaultSetValue; + } + if (options.setParent === undefined) { + options.setParent = defaultSetValue; + } + if (options.priority !== undefined) { + canReflect.setPriority(options.child, options.priority); + canReflect.setPriority(options.parent, options.priority); + } + var allowedUpdates = options.cycles * 2; + var allowedChildUpdates = allowedUpdates + (options.sticky === 'childSticksToParent' ? 1 : 0); + var allowedParentUpdates = allowedUpdates + (options.sticky === 'parentSticksToChild' ? 1 : 0); + this._bindingState = { + child: false, + parent: false + }; + this._updateChild = function (newValue) { + updateValue.call(this, { + bindingState: this._bindingState, + newValue: newValue, + debugObservableName: 'child', + debugPartnerName: 'parent', + observable: options.child, + setValue: options.setChild, + semaphore: childSemaphore, + allowedUpdates: allowedChildUpdates, + sticky: options.sticky === 'parentSticksToChild', + partner: options.parent, + setPartner: options.setParent, + partnerSemaphore: parentSemaphore + }); + }.bind(this); + this._updateParent = function (newValue) { + updateValue.call(this, { + bindingState: this._bindingState, + newValue: newValue, + debugObservableName: 'parent', + debugPartnerName: 'child', + observable: options.parent, + setValue: options.setParent, + semaphore: parentSemaphore, + allowedUpdates: allowedParentUpdates, + sticky: options.sticky === 'childSticksToParent', + partner: options.child, + setPartner: options.setChild, + partnerSemaphore: childSemaphore + }); + }.bind(this); + if (options.element) { + this._updateChild[canElementSymbol] = this._updateParent[canElementSymbol] = options.element; + } + } + Object.defineProperty(Bind.prototype, 'parentValue', { + get: function () { + return canReflect.getValue(this._options.parent); + } + }); + canAssign(Bind.prototype, { + start: function () { + var childValue; + var options = this._options; + var parentValue; + this.startParent(); + this.startChild(); + if (this._childToParent === true && this._parentToChild === true) { + parentValue = canReflect.getValue(options.parent); + if (parentValue === undefined) { + childValue = canReflect.getValue(options.child); + if (childValue === undefined) { + if (options.onInitDoNotUpdateChild === false) { + this._updateChild(parentValue); + } + } else if (options.onInitDoNotUpdateParent === false && options.onInitSetUndefinedParentIfChildIsDefined === true) { + this._updateParent(childValue); + } + } else { + if (options.onInitDoNotUpdateChild === false) { + this._updateChild(parentValue); + } + } + } else if (this._childToParent === true) { + if (options.onInitDoNotUpdateParent === false) { + childValue = canReflect.getValue(options.child); + this._updateParent(childValue); + } + } else if (this._parentToChild === true) { + if (options.onInitDoNotUpdateChild === false) { + parentValue = canReflect.getValue(options.parent); + this._updateChild(parentValue); + } + } + }, + startChild: function () { + if (this._bindingState.child === false && this._childToParent === true) { + var options = this._options; + this._bindingState.child = true; + turnOnListeningAndUpdate(options.child, options.parent, this._updateParent, options.queue); + } + }, + startParent: function () { + if (this._bindingState.parent === false && this._parentToChild === true) { + var options = this._options; + this._bindingState.parent = true; + turnOnListeningAndUpdate(options.parent, options.child, this._updateChild, options.queue); + } + }, + stop: function () { + var bindingState = this._bindingState; + var options = this._options; + if (bindingState.parent === true && this._parentToChild === true) { + bindingState.parent = false; + turnOffListeningAndUpdate(options.parent, options.child, this._updateChild, options.queue); + } + if (bindingState.child === true && this._childToParent === true) { + bindingState.child = false; + turnOffListeningAndUpdate(options.child, options.parent, this._updateParent, options.queue); + } + } + }); + [ + 'parent', + 'child' + ].forEach(function (property) { + Object.defineProperty(Bind.prototype, property, { + get: function () { + return this._options[property]; + } + }); + }); + function updateValue(args) { + var bindingState = args.bindingState; + if (bindingState.child === false && bindingState.parent === false) { + return; + } + var semaphore = args.semaphore; + if (semaphore.value + args.partnerSemaphore.value <= args.allowedUpdates) { + queues.batch.start(); + semaphore.increment(args); + args.setValue(args.newValue, args.observable); + queues.mutateQueue.enqueue(semaphore.decrement, semaphore, []); + queues.batch.stop(); + if (args.sticky) { + var observableValue = canReflect.getValue(args.observable); + if (observableValue !== canReflect.getValue(args.partner)) { + args.setPartner(observableValue, args.partner); + } + } + } else { + } + } + module.exports = namespace.Bind = Bind; +}); +/*can-stache@5.1.1#expressions/arg*/ +define('can-stache@5.1.1#expressions/arg', function (require, exports, module) { + 'use strict'; + var Arg = function (expression, modifiers) { + this.expr = expression; + this.modifiers = modifiers || {}; + this.isCompute = false; + }; + Arg.prototype.value = function () { + return this.expr.value.apply(this.expr, arguments); + }; + module.exports = Arg; +}); +/*can-stache@5.1.1#expressions/literal*/ +define('can-stache@5.1.1#expressions/literal', function (require, exports, module) { + 'use strict'; + var Literal = function (value) { + this._value = value; + }; + Literal.prototype.value = function () { + return this._value; + }; + module.exports = Literal; +}); +/*can-simple-observable@2.5.0#settable/settable*/ +define('can-simple-observable@2.5.0#settable/settable', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation-recorder', + '../can-simple-observable', + 'can-observation', + 'can-queues', + '../log', + 'can-event-queue/value/value' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var SimpleObservable = require('../can-simple-observable'); + var Observation = require('can-observation'); + var queues = require('can-queues'); + var log = require('../log'); + var valueEventBindings = require('can-event-queue/value/value'); + var peek = ObservationRecorder.ignore(canReflect.getValue.bind(canReflect)); + function SettableObservable(fn, context, initialValue) { + this.lastSetValue = new SimpleObservable(initialValue); + function observe() { + return fn.call(context, this.lastSetValue.get()); + } + this.handler = this.handler.bind(this); + this.observation = new Observation(observe, this); + } + valueEventBindings(SettableObservable.prototype); + canReflect.assignMap(SettableObservable.prototype, { + log: log, + constructor: SettableObservable, + handler: function (newVal) { + var old = this._value, reasonLog; + this._value = newVal; + queues.enqueueByQueue(this.handlers.getNode([]), this, [ + newVal, + old + ], null, reasonLog); + }, + onBound: function () { + if (!this.bound) { + this.bound = true; + this.activate(); + } + }, + activate: function () { + canReflect.onValue(this.observation, this.handler, 'notify'); + this._value = peek(this.observation); + }, + onUnbound: function () { + this.bound = false; + canReflect.offValue(this.observation, this.handler, 'notify'); + }, + set: function (newVal) { + var oldVal = this.lastSetValue.get(); + if (canReflect.isObservableLike(oldVal) && canReflect.isValueLike(oldVal) && !canReflect.isObservableLike(newVal)) { + canReflect.setValue(oldVal, newVal); + } else { + if (newVal !== oldVal) { + this.lastSetValue.set(newVal); + } + } + }, + get: function () { + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (!this.bound) { + this.onBound(); + } + } + if (this.bound === true) { + return this._value; + } else { + return this.observation.get(); + } + }, + hasDependencies: function () { + return canReflect.valueHasDependencies(this.observation); + }, + getValueDependencies: function () { + return canReflect.getValueDependencies(this.observation); + } + }); + Object.defineProperty(SettableObservable.prototype, 'value', { + set: function (value) { + return this.set(value); + }, + get: function () { + return this.get(); + } + }); + canReflect.assignSymbols(SettableObservable.prototype, { + 'can.getValue': SettableObservable.prototype.get, + 'can.setValue': SettableObservable.prototype.set, + 'can.isMapLike': false, + 'can.getPriority': function () { + return canReflect.getPriority(this.observation); + }, + 'can.setPriority': function (newPriority) { + canReflect.setPriority(this.observation, newPriority); + }, + 'can.valueHasDependencies': SettableObservable.prototype.hasDependencies, + 'can.getValueDependencies': SettableObservable.prototype.getValueDependencies + }); + module.exports = SettableObservable; +}); +/*can-simple-observable@2.5.0#setter/setter*/ +define('can-simple-observable@2.5.0#setter/setter', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation', + '../settable/settable', + 'can-event-queue/value/value', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var SettableObservable = require('../settable/settable'); + var valueEventBindings = require('can-event-queue/value/value'); + var canSymbol = require('can-symbol'); + var setElementSymbol = canSymbol.for('can.setElement'); + function SetterObservable(getter, setter) { + this.setter = setter; + this.observation = new Observation(getter); + this.handler = this.handler.bind(this); + } + SetterObservable.prototype = Object.create(SettableObservable.prototype); + SetterObservable.prototype.constructor = SetterObservable; + SetterObservable.prototype.set = function (newVal) { + this.setter(newVal); + }; + SetterObservable.prototype.hasDependencies = function () { + return canReflect.valueHasDependencies(this.observation); + }; + canReflect.assignSymbols(SetterObservable.prototype, { + 'can.setValue': SetterObservable.prototype.set, + 'can.valueHasDependencies': SetterObservable.prototype.hasDependencies, + 'can.setElement': function (el) { + this.observation[setElementSymbol](el); + } + }); + module.exports = SetterObservable; +}); +/*can-stache@5.1.1#src/expression-helpers*/ +define('can-stache@5.1.1#src/expression-helpers', [ + 'require', + 'exports', + 'module', + '../expressions/arg', + '../expressions/literal', + 'can-reflect', + 'can-stache-key', + 'can-observation', + 'can-observation-recorder', + 'can-view-scope/make-compute-like', + 'can-simple-observable/setter/setter' +], function (require, exports, module) { + 'use strict'; + var Arg = require('../expressions/arg'); + var Literal = require('../expressions/literal'); + var canReflect = require('can-reflect'); + var stacheKey = require('can-stache-key'); + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var makeComputeLike = require('can-view-scope/make-compute-like'); + var SetterObservable = require('can-simple-observable/setter/setter'); + function getObservableValue_fromDynamicKey_fromObservable(key, root, helperOptions, readOptions) { + var getKeys = function () { + return stacheKey.reads(('' + canReflect.getValue(key)).replace(/\./g, '\\.')); + }; + var parentHasKey; + var computeValue = new SetterObservable(function getDynamicKey() { + var readData = stacheKey.read(canReflect.getValue(root), getKeys()); + parentHasKey = readData.parentHasKey; + return readData.value; + }, function setDynamicKey(newVal) { + stacheKey.write(canReflect.getValue(root), getKeys(), newVal); + }); + Observation.temporarilyBind(computeValue); + computeValue.initialValue = ObservationRecorder.peekValue(computeValue); + computeValue.parentHasKey = parentHasKey; + return computeValue; + } + function convertToArgExpression(expr) { + if (!(expr instanceof Arg) && !(expr instanceof Literal)) { + return new Arg(expr); + } else { + return expr; + } + } + function toComputeOrValue(value) { + if (canReflect.isObservableLike(value)) { + if (canReflect.isValueLike(value) && canReflect.valueHasDependencies(value) === false) { + return canReflect.getValue(value); + } + if (value.compute) { + return value.compute; + } else { + return makeComputeLike(value); + } + } + return value; + } + function toCompute(value) { + if (value) { + if (value.isComputed) { + return value; + } + if (value.compute) { + return value.compute; + } else { + return makeComputeLike(value); + } + } + return value; + } + module.exports = { + getObservableValue_fromDynamicKey_fromObservable: getObservableValue_fromDynamicKey_fromObservable, + convertToArgExpression: convertToArgExpression, + toComputeOrValue: toComputeOrValue, + toCompute: toCompute + }; +}); +/*can-stache@5.1.1#expressions/hashes*/ +define('can-stache@5.1.1#expressions/hashes', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation', + '../src/expression-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var expressionHelpers = require('../src/expression-helpers'); + var Hashes = function (hashes) { + this.hashExprs = hashes; + }; + Hashes.prototype.value = function (scope, helperOptions) { + var hash = {}; + for (var prop in this.hashExprs) { + var val = expressionHelpers.convertToArgExpression(this.hashExprs[prop]), value = val.value.apply(val, arguments); + hash[prop] = { + call: !val.modifiers || !val.modifiers.compute, + value: value + }; + } + return new Observation(function () { + var finalHash = {}; + for (var prop in hash) { + finalHash[prop] = hash[prop].call ? canReflect.getValue(hash[prop].value) : expressionHelpers.toComputeOrValue(hash[prop].value); + } + return finalHash; + }); + }; + module.exports = Hashes; +}); +/*can-stache@5.1.1#expressions/bracket*/ +define('can-stache@5.1.1#expressions/bracket', [ + 'require', + 'exports', + 'module', + '../src/expression-helpers' +], function (require, exports, module) { + 'use strict'; + var expressionHelpers = require('../src/expression-helpers'); + var Bracket = function (key, root, originalKey) { + this.root = root; + this.key = key; + }; + Bracket.prototype.value = function (scope, helpers) { + var root = this.root ? this.root.value(scope, helpers) : scope.peek('this'); + return expressionHelpers.getObservableValue_fromDynamicKey_fromObservable(this.key.value(scope, helpers), root, scope, helpers, {}); + }; + Bracket.prototype.closingTag = function () { + }; + module.exports = Bracket; +}); +/*can-stache@5.1.1#src/set-identifier*/ +define('can-stache@5.1.1#src/set-identifier', function (require, exports, module) { + 'use strict'; + module.exports = function SetIdentifier(value) { + this.value = value; + }; +}); +/*can-stache@5.1.1#expressions/call*/ +define('can-stache@5.1.1#expressions/call', [ + 'require', + 'exports', + 'module', + './hashes', + '../src/set-identifier', + 'can-symbol', + 'can-simple-observable/setter/setter', + '../src/expression-helpers', + 'can-reflect', + 'can-assign', + 'can-view-scope', + 'can-observation' +], function (require, exports, module) { + 'use strict'; + var Hashes = require('./hashes'); + var SetIdentifier = require('../src/set-identifier'); + var canSymbol = require('can-symbol'); + var SetterObservable = require('can-simple-observable/setter/setter'); + var expressionHelpers = require('../src/expression-helpers'); + var canReflect = require('can-reflect'); + var assign = require('can-assign'); + var sourceTextSymbol = canSymbol.for('can-stache.sourceText'); + var isViewSymbol = canSymbol.for('can.isView'); + var Scope = require('can-view-scope'); + var Observation = require('can-observation'); + var Call = function (methodExpression, argExpressions) { + this.methodExpr = methodExpression; + this.argExprs = argExpressions.map(expressionHelpers.convertToArgExpression); + }; + Call.prototype.args = function (scope, ignoreArgLookup) { + var hashExprs = {}; + var args = []; + var gotIgnoreFunction = typeof ignoreArgLookup === 'function'; + for (var i = 0, len = this.argExprs.length; i < len; i++) { + var arg = this.argExprs[i]; + if (arg.expr instanceof Hashes) { + assign(hashExprs, arg.expr.hashExprs); + } + if (!gotIgnoreFunction || !ignoreArgLookup(i)) { + var value = arg.value.apply(arg, arguments); + args.push({ + call: !arg.modifiers || !arg.modifiers.compute, + value: value + }); + } + } + return function (doNotWrapArguments) { + var finalArgs = []; + if (canReflect.size(hashExprs) > 0) { + finalArgs.hashExprs = hashExprs; + } + for (var i = 0, len = args.length; i < len; i++) { + if (doNotWrapArguments) { + finalArgs[i] = args[i].value; + } else { + finalArgs[i] = args[i].call ? canReflect.getValue(args[i].value) : expressionHelpers.toCompute(args[i].value); + } + } + return finalArgs; + }; + }; + Call.prototype.value = function (scope, helperOptions) { + var callExpression = this; + var method = this.methodExpr.value(scope, { proxyMethods: false }); + Observation.temporarilyBind(method); + var func = canReflect.getValue(method); + var getArgs = callExpression.args(scope, func && func.ignoreArgLookup); + var computeFn = function (newVal) { + var func = canReflect.getValue(method); + if (typeof func === 'function') { + if (canReflect.isObservableLike(func)) { + func = canReflect.getValue(func); + } + var args = getArgs(func.isLiveBound); + if (func.requiresOptionsArgument) { + if (args.hashExprs && helperOptions && helperOptions.exprData) { + helperOptions.exprData.hashExprs = args.hashExprs; + } + if (helperOptions !== undefined) { + args.push(helperOptions); + } + } + if (func[isViewSymbol] === true) { + if (!(args[0] instanceof Scope)) { + args[0] = scope.getTemplateContext().add(args[0]); + } + } + if (arguments.length) { + args.unshift(new SetIdentifier(newVal)); + } + return func.apply(method.thisArg || scope.peek('this'), args); + } + }; + if (helperOptions && helperOptions.doNotWrapInObservation) { + return computeFn(); + } else { + var computeValue = new SetterObservable(computeFn, computeFn); + return computeValue; + } + }; + Call.prototype.closingTag = function () { + return this.methodExpr.key; + }; + module.exports = Call; +}); +/*can-stache@5.1.1#expressions/helper*/ +define('can-stache@5.1.1#expressions/helper', [ + 'require', + 'exports', + 'module', + './literal', + './hashes', + 'can-assign', + 'can-log/dev/dev', + '../src/expression-helpers', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var Literal = require('./literal'); + var Hashes = require('./hashes'); + var assign = require('can-assign'); + var dev = require('can-log/dev/dev'); + var expressionHelpers = require('../src/expression-helpers'); + var canReflect = require('can-reflect'); + var Helper = function (methodExpression, argExpressions, hashExpressions) { + this.methodExpr = methodExpression; + this.argExprs = argExpressions; + this.hashExprs = hashExpressions; + this.mode = null; + }; + Helper.prototype.args = function (scope) { + var args = []; + for (var i = 0, len = this.argExprs.length; i < len; i++) { + var arg = this.argExprs[i]; + args.push(expressionHelpers.toComputeOrValue(arg.value.apply(arg, arguments))); + } + return args; + }; + Helper.prototype.hash = function (scope) { + var hash = {}; + for (var prop in this.hashExprs) { + var val = this.hashExprs[prop]; + hash[prop] = expressionHelpers.toComputeOrValue(val.value.apply(val, arguments)); + } + return hash; + }; + Helper.prototype.value = function (scope, helperOptions) { + var methodKey = this.methodExpr instanceof Literal ? '' + this.methodExpr._value : this.methodExpr.key, helperInstance = this, helperFn = scope.computeData(methodKey, { proxyMethods: false }), initialValue = helperFn && helperFn.initialValue, thisArg = helperFn && helperFn.thisArg; + if (typeof initialValue === 'function') { + helperFn = function helperFn() { + var args = helperInstance.args(scope), helperOptionArg = assign(assign({}, helperOptions), { + hash: helperInstance.hash(scope), + exprData: helperInstance + }); + args.push(helperOptionArg); + return initialValue.apply(thisArg || scope.peek('this'), args); + }; + } + return helperFn; + }; + Helper.prototype.closingTag = function () { + return this.methodExpr.key; + }; + module.exports = Helper; +}); +/*can-stache@5.1.1#expressions/lookup*/ +define('can-stache@5.1.1#expressions/lookup', [ + 'require', + 'exports', + 'module', + '../src/expression-helpers', + 'can-reflect', + 'can-symbol', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var expressionHelpers = require('../src/expression-helpers'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var sourceTextSymbol = canSymbol.for('can-stache.sourceText'); + var assign = require('can-assign'); + var Lookup = function (key, root, sourceText) { + this.key = key; + this.rootExpr = root; + canReflect.setKeyValue(this, sourceTextSymbol, sourceText); + }; + Lookup.prototype.value = function (scope, readOptions) { + if (this.rootExpr) { + return expressionHelpers.getObservableValue_fromDynamicKey_fromObservable(this.key, this.rootExpr.value(scope), scope, {}, {}); + } else { + return scope.computeData(this.key, assign({ warnOnMissingKey: true }, readOptions)); + } + }; + module.exports = Lookup; +}); +/*can-stache@5.1.1#src/key-observable*/ +define('can-stache@5.1.1#src/key-observable', [ + 'require', + 'exports', + 'module', + 'can-simple-observable/settable/settable', + 'can-stache-key' +], function (require, exports, module) { + 'use strict'; + var SettableObservable = require('can-simple-observable/settable/settable'); + var stacheKey = require('can-stache-key'); + function KeyObservable(root, key) { + key = '' + key; + this.key = key; + this.root = root; + SettableObservable.call(this, function () { + return stacheKey.get(this, key); + }, root); + } + KeyObservable.prototype = Object.create(SettableObservable.prototype); + KeyObservable.prototype.set = function (newVal) { + stacheKey.set(this.root, this.key, newVal); + }; + module.exports = KeyObservable; +}); +/*can-stache@5.1.1#src/utils*/ +define('can-stache@5.1.1#src/utils', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'can-observation-recorder', + 'can-stache-key', + 'can-reflect', + './key-observable', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Scope = require('can-view-scope'); + var ObservationRecorder = require('can-observation-recorder'); + var observationReader = require('can-stache-key'); + var canReflect = require('can-reflect'); + var KeyObservable = require('./key-observable'); + var canSymbol = require('can-symbol'); + var isViewSymbol = canSymbol.for('can.isView'); + var createNoOpRenderer = function (metadata) { + return function noop() { + if (metadata) { + metadata.rendered = true; + } + }; + }; + module.exports = { + last: function (arr) { + return arr != null && arr[arr.length - 1]; + }, + emptyHandler: function () { + }, + jsonParse: function (str) { + if (str[0] === '\'') { + return str.substr(1, str.length - 2); + } else if (str === 'undefined') { + return undefined; + } else { + return JSON.parse(str); + } + }, + mixins: { + last: function () { + return this.stack[this.stack.length - 1]; + }, + add: function (chars) { + this.last().add(chars); + }, + subSectionDepth: function () { + return this.stack.length - 1; + } + }, + createRenderers: function (helperOptions, scope, truthyRenderer, falseyRenderer, isStringOnly) { + helperOptions.fn = truthyRenderer ? this.makeRendererConvertScopes(truthyRenderer, scope, isStringOnly, helperOptions.metadata) : createNoOpRenderer(helperOptions.metadata); + helperOptions.inverse = falseyRenderer ? this.makeRendererConvertScopes(falseyRenderer, scope, isStringOnly, helperOptions.metadata) : createNoOpRenderer(helperOptions.metadata); + helperOptions.isSection = !!(truthyRenderer || falseyRenderer); + }, + makeRendererConvertScopes: function (renderer, parentScope, observeObservables, metadata) { + var convertedRenderer = function (newScope, newOptions) { + if (newScope !== undefined && !(newScope instanceof Scope)) { + if (parentScope) { + newScope = parentScope.add(newScope); + } else { + newScope = new Scope(newScope || {}); + } + } + if (metadata) { + metadata.rendered = true; + } + var result = renderer(newScope || parentScope); + return result; + }; + return observeObservables ? convertedRenderer : ObservationRecorder.ignore(convertedRenderer); + }, + makeView: function (renderer) { + var view = ObservationRecorder.ignore(function (scope) { + if (!(scope instanceof Scope)) { + scope = new Scope(scope); + } + return renderer(scope); + }); + view[isViewSymbol] = true; + return view; + }, + getItemsStringContent: function (items, isObserveList, helperOptions) { + var txt = '', len = observationReader.get(items, 'length'), isObservable = canReflect.isObservableLike(items); + for (var i = 0; i < len; i++) { + var item = isObservable ? new KeyObservable(items, i) : items[i]; + txt += helperOptions.fn(item); + } + return txt; + }, + getItemsFragContent: function (items, helperOptions, scope) { + var result = [], len = observationReader.get(items, 'length'), isObservable = canReflect.isObservableLike(items), hashExprs = helperOptions.exprData && helperOptions.exprData.hashExprs, hashOptions; + if (canReflect.size(hashExprs) > 0) { + hashOptions = {}; + canReflect.eachKey(hashExprs, function (exprs, key) { + hashOptions[exprs.key] = key; + }); + } + for (var i = 0; i < len; i++) { + var aliases = {}; + var item = isObservable ? new KeyObservable(items, i) : items[i]; + if (canReflect.size(hashOptions) > 0) { + if (hashOptions.value) { + aliases[hashOptions.value] = item; + } + if (hashOptions.index) { + aliases[hashOptions.index] = i; + } + } + result.push(helperOptions.fn(scope.add(aliases, { notContext: true }).add({ index: i }, { special: true }).add(item))); + } + return result; + } + }; +}); +/*can-stache@5.1.1#src/expression*/ +define('can-stache@5.1.1#src/expression', [ + 'require', + 'exports', + 'module', + '../expressions/arg', + '../expressions/literal', + '../expressions/hashes', + '../expressions/bracket', + '../expressions/call', + '../expressions/helper', + '../expressions/lookup', + './set-identifier', + '../src/expression-helpers', + './utils', + 'can-assign', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Arg = require('../expressions/arg'); + var Literal = require('../expressions/literal'); + var Hashes = require('../expressions/hashes'); + var Bracket = require('../expressions/bracket'); + var Call = require('../expressions/call'); + var Helper = require('../expressions/helper'); + var Lookup = require('../expressions/lookup'); + var SetIdentifier = require('./set-identifier'); + var expressionHelpers = require('../src/expression-helpers'); + var utils = require('./utils'); + var assign = require('can-assign'); + var last = utils.last; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var sourceTextSymbol = canSymbol.for('can-stache.sourceText'); + var Hash = function () { + }; + var keyRegExp = /[\w\.\\\-_@\/\&%]+/, tokensRegExp = /('.*?'|".*?"|=|[\w\.\\\-_@\/*%\$]+|[\(\)]|,|\~|\[|\]\s*|\s*(?=\[))/g, bracketSpaceRegExp = /\]\s+/, literalRegExp = /^('.*?'|".*?"|-?[0-9]+\.?[0-9]*|true|false|null|undefined)$/; + var isTokenKey = function (token) { + return keyRegExp.test(token); + }; + var testDot = /^[\.@]\w/; + var isAddingToExpression = function (token) { + return isTokenKey(token) && testDot.test(token); + }; + var ensureChildren = function (type) { + if (!type.children) { + type.children = []; + } + return type; + }; + var Stack = function () { + this.root = { + children: [], + type: 'Root' + }; + this.current = this.root; + this.stack = [this.root]; + }; + assign(Stack.prototype, { + top: function () { + return last(this.stack); + }, + isRootTop: function () { + return this.top() === this.root; + }, + popTo: function (types) { + this.popUntil(types); + this.pop(); + }, + pop: function () { + if (!this.isRootTop()) { + this.stack.pop(); + } + }, + first: function (types) { + var curIndex = this.stack.length - 1; + while (curIndex > 0 && types.indexOf(this.stack[curIndex].type) === -1) { + curIndex--; + } + return this.stack[curIndex]; + }, + firstParent: function (types) { + var curIndex = this.stack.length - 2; + while (curIndex > 0 && types.indexOf(this.stack[curIndex].type) === -1) { + curIndex--; + } + return this.stack[curIndex]; + }, + popUntil: function (types) { + while (types.indexOf(this.top().type) === -1 && !this.isRootTop()) { + this.stack.pop(); + } + return this.top(); + }, + addTo: function (types, type) { + var cur = this.popUntil(types); + ensureChildren(cur).children.push(type); + }, + addToAndPush: function (types, type) { + this.addTo(types, type); + this.stack.push(type); + }, + push: function (type) { + this.stack.push(type); + }, + topLastChild: function () { + return last(this.top().children); + }, + replaceTopLastChild: function (type) { + var children = ensureChildren(this.top()).children; + children.pop(); + children.push(type); + return type; + }, + replaceTopLastChildAndPush: function (type) { + this.replaceTopLastChild(type); + this.stack.push(type); + }, + replaceTopAndPush: function (type) { + var children; + if (this.top() === this.root) { + children = ensureChildren(this.top()).children; + } else { + this.stack.pop(); + children = ensureChildren(this.top()).children; + } + children.pop(); + children.push(type); + this.stack.push(type); + return type; + } + }); + var convertKeyToLookup = function (key) { + var lastPath = key.lastIndexOf('./'); + var lastDot = key.lastIndexOf('.'); + if (lastDot > lastPath) { + return key.substr(0, lastDot) + '@' + key.substr(lastDot + 1); + } + var firstNonPathCharIndex = lastPath === -1 ? 0 : lastPath + 2; + var firstNonPathChar = key.charAt(firstNonPathCharIndex); + if (firstNonPathChar === '.' || firstNonPathChar === '@') { + return key.substr(0, firstNonPathCharIndex) + '@' + key.substr(firstNonPathCharIndex + 1); + } else { + return key.substr(0, firstNonPathCharIndex) + '@' + key.substr(firstNonPathCharIndex); + } + }; + var convertToAtLookup = function (ast) { + if (ast.type === 'Lookup') { + canReflect.setKeyValue(ast, sourceTextSymbol, ast.key); + ast.key = convertKeyToLookup(ast.key); + } + return ast; + }; + var convertToHelperIfTopIsLookup = function (stack) { + var top = stack.top(); + if (top && top.type === 'Lookup') { + var base = stack.stack[stack.stack.length - 2]; + if (base.type !== 'Helper' && base) { + stack.replaceTopAndPush({ + type: 'Helper', + method: top + }); + } + } + }; + var expression = { + toComputeOrValue: expressionHelpers.toComputeOrValue, + convertKeyToLookup: convertKeyToLookup, + Literal: Literal, + Lookup: Lookup, + Arg: Arg, + Hash: Hash, + Hashes: Hashes, + Call: Call, + Helper: Helper, + Bracket: Bracket, + SetIdentifier: SetIdentifier, + tokenize: function (expression) { + var tokens = []; + (expression.trim() + ' ').replace(tokensRegExp, function (whole, arg) { + if (bracketSpaceRegExp.test(arg)) { + tokens.push(arg[0]); + tokens.push(arg.slice(1)); + } else { + tokens.push(arg); + } + }); + return tokens; + }, + lookupRules: { + 'default': function (ast, methodType, isArg) { + return ast.type === 'Helper' ? Helper : Lookup; + }, + 'method': function (ast, methodType, isArg) { + return Lookup; + } + }, + methodRules: { + 'default': function (ast) { + return ast.type === 'Call' ? Call : Helper; + }, + 'call': function (ast) { + return Call; + } + }, + parse: function (expressionString, options) { + options = options || {}; + var ast = this.ast(expressionString); + if (!options.lookupRule) { + options.lookupRule = 'default'; + } + if (typeof options.lookupRule === 'string') { + options.lookupRule = expression.lookupRules[options.lookupRule]; + } + if (!options.methodRule) { + options.methodRule = 'default'; + } + if (typeof options.methodRule === 'string') { + options.methodRule = expression.methodRules[options.methodRule]; + } + var expr = this.hydrateAst(ast, options, options.baseMethodType || 'Helper'); + return expr; + }, + hydrateAst: function (ast, options, methodType, isArg) { + var hashes; + if (ast.type === 'Lookup') { + var LookupRule = options.lookupRule(ast, methodType, isArg); + var lookup = new LookupRule(ast.key, ast.root && this.hydrateAst(ast.root, options, methodType), ast[sourceTextSymbol]); + return lookup; + } else if (ast.type === 'Literal') { + return new Literal(ast.value); + } else if (ast.type === 'Arg') { + return new Arg(this.hydrateAst(ast.children[0], options, methodType, isArg), { compute: true }); + } else if (ast.type === 'Hash') { + throw new Error(''); + } else if (ast.type === 'Hashes') { + hashes = {}; + ast.children.forEach(function (hash) { + hashes[hash.prop] = this.hydrateAst(hash.children[0], options, methodType, true); + }, this); + return new Hashes(hashes); + } else if (ast.type === 'Call' || ast.type === 'Helper') { + hashes = {}; + var args = [], children = ast.children, ExpressionType = options.methodRule(ast); + if (children) { + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (child.type === 'Hashes' && ast.type === 'Helper' && ExpressionType !== Call) { + child.children.forEach(function (hash) { + hashes[hash.prop] = this.hydrateAst(hash.children[0], options, ast.type, true); + }, this); + } else { + args.push(this.hydrateAst(child, options, ast.type, true)); + } + } + } + return new ExpressionType(this.hydrateAst(ast.method, options, ast.type), args, hashes); + } else if (ast.type === 'Bracket') { + var originalKey; + return new Bracket(this.hydrateAst(ast.children[0], options), ast.root ? this.hydrateAst(ast.root, options) : undefined, originalKey); + } + }, + ast: function (expression) { + var tokens = this.tokenize(expression); + return this.parseAst(tokens, { index: 0 }); + }, + parseAst: function (tokens, cursor) { + var stack = new Stack(), top, firstParent, lastToken; + while (cursor.index < tokens.length) { + var token = tokens[cursor.index], nextToken = tokens[cursor.index + 1]; + cursor.index++; + if (nextToken === '=') { + top = stack.top(); + if (top && top.type === 'Lookup') { + firstParent = stack.firstParent([ + 'Call', + 'Helper', + 'Hash' + ]); + if (firstParent.type === 'Call' || firstParent.type === 'Root') { + stack.popUntil(['Call']); + top = stack.top(); + stack.replaceTopAndPush({ + type: 'Helper', + method: top.type === 'Root' ? last(top.children) : top + }); + } + } + firstParent = stack.first([ + 'Call', + 'Helper', + 'Hashes', + 'Root' + ]); + var hash = { + type: 'Hash', + prop: token + }; + if (firstParent.type === 'Hashes') { + stack.addToAndPush(['Hashes'], hash); + } else { + stack.addToAndPush([ + 'Helper', + 'Call', + 'Root' + ], { + type: 'Hashes', + children: [hash] + }); + stack.push(hash); + } + cursor.index++; + } else if (literalRegExp.test(token)) { + convertToHelperIfTopIsLookup(stack); + firstParent = stack.first([ + 'Helper', + 'Call', + 'Hash', + 'Bracket' + ]); + if (firstParent.type === 'Hash' && (firstParent.children && firstParent.children.length > 0)) { + stack.addTo([ + 'Helper', + 'Call', + 'Bracket' + ], { + type: 'Literal', + value: utils.jsonParse(token) + }); + } else if (firstParent.type === 'Bracket' && (firstParent.children && firstParent.children.length > 0)) { + stack.addTo([ + 'Helper', + 'Call', + 'Hash' + ], { + type: 'Literal', + value: utils.jsonParse(token) + }); + } else { + stack.addTo([ + 'Helper', + 'Call', + 'Hash', + 'Bracket' + ], { + type: 'Literal', + value: utils.jsonParse(token) + }); + } + } else if (keyRegExp.test(token)) { + lastToken = stack.topLastChild(); + firstParent = stack.first([ + 'Helper', + 'Call', + 'Hash', + 'Bracket' + ]); + if (lastToken && (lastToken.type === 'Call' || lastToken.type === 'Bracket') && isAddingToExpression(token)) { + stack.replaceTopLastChildAndPush({ + type: 'Lookup', + root: lastToken, + key: token.slice(1) + }); + } else if (firstParent.type === 'Bracket') { + if (!(firstParent.children && firstParent.children.length > 0)) { + stack.addToAndPush(['Bracket'], { + type: 'Lookup', + key: token + }); + } else { + if (stack.first([ + 'Helper', + 'Call', + 'Hash', + 'Arg' + ]).type === 'Helper' && token[0] !== '.') { + stack.addToAndPush(['Helper'], { + type: 'Lookup', + key: token + }); + } else { + stack.replaceTopAndPush({ + type: 'Lookup', + key: token.slice(1), + root: firstParent + }); + } + } + } else { + convertToHelperIfTopIsLookup(stack); + stack.addToAndPush([ + 'Helper', + 'Call', + 'Hash', + 'Arg', + 'Bracket' + ], { + type: 'Lookup', + key: token + }); + } + } else if (token === '~') { + convertToHelperIfTopIsLookup(stack); + stack.addToAndPush([ + 'Helper', + 'Call', + 'Hash' + ], { + type: 'Arg', + key: token + }); + } else if (token === '(') { + top = stack.top(); + lastToken = stack.topLastChild(); + if (top.type === 'Lookup') { + stack.replaceTopAndPush({ + type: 'Call', + method: convertToAtLookup(top) + }); + } else if (lastToken && lastToken.type === 'Call') { + stack.replaceTopAndPush({ + type: 'Call', + method: lastToken + }); + } else { + throw new Error('Unable to understand expression ' + tokens.join('')); + } + } else if (token === ')') { + stack.popTo(['Call']); + } else if (token === ',') { + var call = stack.first(['Call']); + if (call.type !== 'Call') { + stack.popUntil(['Hash']); + } else { + stack.popUntil(['Call']); + } + } else if (token === '[') { + top = stack.top(); + lastToken = stack.topLastChild(); + if (lastToken && (lastToken.type === 'Call' || lastToken.type === 'Bracket')) { + stack.replaceTopLastChildAndPush({ + type: 'Bracket', + root: lastToken + }); + } else if (top.type === 'Lookup' || top.type === 'Bracket') { + var bracket = { + type: 'Bracket', + root: top + }; + stack.replaceTopAndPush(bracket); + } else if (top.type === 'Call') { + stack.addToAndPush(['Call'], { type: 'Bracket' }); + } else if (top === ' ') { + stack.popUntil([ + 'Lookup', + 'Call' + ]); + convertToHelperIfTopIsLookup(stack); + stack.addToAndPush([ + 'Helper', + 'Call', + 'Hash' + ], { type: 'Bracket' }); + } else { + stack.replaceTopAndPush({ type: 'Bracket' }); + } + } else if (token === ']') { + stack.pop(); + } else if (token === ' ') { + stack.push(token); + } + } + return stack.root.children[0]; + } + }; + module.exports = expression; +}); +/*can-view-model@4.0.3#can-view-model*/ +define('can-view-model@4.0.3#can-view-model', [ + 'require', + 'exports', + 'module', + 'can-simple-map', + 'can-namespace', + 'can-globals/document/document', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var SimpleMap = require('can-simple-map'); + var ns = require('can-namespace'); + var getDocument = require('can-globals/document/document'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var viewModelSymbol = canSymbol.for('can.viewModel'); + module.exports = ns.viewModel = function (el, attr, val) { + if (typeof el === 'string') { + el = getDocument().querySelector(el); + } else if (canReflect.isListLike(el) && !el.nodeType) { + el = el[0]; + } + if (canReflect.isObservableLike(attr) && canReflect.isMapLike(attr)) { + el[viewModelSymbol] = attr; + return; + } + var scope = el[viewModelSymbol]; + if (!scope) { + scope = new SimpleMap(); + el[viewModelSymbol] = scope; + } + switch (arguments.length) { + case 0: + case 1: + return scope; + case 2: + return canReflect.getKeyValue(scope, attr); + default: + canReflect.setKeyValue(scope, attr, val); + return el; + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-dom-data@1.0.3#can-dom-data*/ +define('can-dom-data@1.0.3#can-dom-data', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var isEmptyObject = function (obj) { + for (var prop in obj) { + return false; + } + return true; + }; + var data = new WeakMap(); + var deleteNode = function (node) { + var nodeDeleted = false; + if (data.has(node)) { + nodeDeleted = true; + data.delete(node); + } + return nodeDeleted; + }; + var setData = function (node, name, value) { + var store = data.get(node); + if (store === undefined) { + store = {}; + data.set(node, store); + } + if (name !== undefined) { + store[name] = value; + } + return store; + }; + var domData = { + _data: data, + get: function (node, key) { + var store = data.get(node); + return key === undefined ? store : store && store[key]; + }, + set: setData, + clean: function (node, prop) { + var itemData = data.get(node); + if (itemData && itemData[prop]) { + delete itemData[prop]; + } + if (isEmptyObject(itemData)) { + deleteNode(node); + } + }, + delete: deleteNode + }; + if (namespace.domData) { + throw new Error('You can\'t have two versions of can-dom-data, check your dependencies'); + } else { + module.exports = namespace.domData = domData; + } +}); +/*can-attribute-encoder@1.1.4#can-attribute-encoder*/ +define('can-attribute-encoder@1.1.4#can-attribute-encoder', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-log/dev/dev' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var dev = require('can-log/dev/dev'); + function each(items, callback) { + for (var i = 0; i < items.length; i++) { + callback(items[i], i); + } + } + function makeMap(str) { + var obj = {}, items = str.split(','); + each(items, function (name) { + obj[name] = true; + }); + return obj; + } + var caseMattersAttributes = makeMap('allowReorder,attributeName,attributeType,autoReverse,baseFrequency,baseProfile,calcMode,clipPathUnits,contentScriptType,contentStyleType,diffuseConstant,edgeMode,externalResourcesRequired,filterRes,filterUnits,glyphRef,gradientTransform,gradientUnits,kernelMatrix,kernelUnitLength,keyPoints,keySplines,keyTimes,lengthAdjust,limitingConeAngle,markerHeight,markerUnits,markerWidth,maskContentUnits,maskUnits,patternContentUnits,patternTransform,patternUnits,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,preserveAspectRatio,primitiveUnits,repeatCount,repeatDur,requiredExtensions,requiredFeatures,specularConstant,specularExponent,spreadMethod,startOffset,stdDeviation,stitchTiles,surfaceScale,systemLanguage,tableValues,textLength,viewBox,viewTarget,xChannelSelector,yChannelSelector,controlsList'); + function camelCaseToSpinalCase(match, lowerCaseChar, upperCaseChar) { + return lowerCaseChar + '-' + upperCaseChar.toLowerCase(); + } + function startsWith(allOfIt, startsWith) { + return allOfIt.indexOf(startsWith) === 0; + } + function endsWith(allOfIt, endsWith) { + return allOfIt.length - allOfIt.lastIndexOf(endsWith) === endsWith.length; + } + var regexes = { + leftParens: /\(/g, + rightParens: /\)/g, + leftBrace: /\{/g, + rightBrace: /\}/g, + camelCase: /([a-z]|[0-9]|^)([A-Z])/g, + forwardSlash: /\//g, + space: /\s/g, + uppercase: /[A-Z]/g, + uppercaseDelimiterThenChar: /:u:([a-z])/g, + caret: /\^/g, + dollar: /\$/g, + at: /@/g + }; + var delimiters = { + prependUppercase: ':u:', + replaceSpace: ':s:', + replaceForwardSlash: ':f:', + replaceLeftParens: ':lp:', + replaceRightParens: ':rp:', + replaceLeftBrace: ':lb:', + replaceRightBrace: ':rb:', + replaceCaret: ':c:', + replaceDollar: ':d:', + replaceAt: ':at:' + }; + var encoder = {}; + encoder.encode = function (name) { + var encoded = name; + if (!caseMattersAttributes[encoded] && encoded.match(regexes.camelCase)) { + if (startsWith(encoded, 'on:') || endsWith(encoded, ':to') || endsWith(encoded, ':from') || endsWith(encoded, ':bind') || endsWith(encoded, ':raw')) { + encoded = encoded.replace(regexes.uppercase, function (char) { + return delimiters.prependUppercase + char.toLowerCase(); + }); + } else if (startsWith(encoded, '(') || startsWith(encoded, '{')) { + encoded = encoded.replace(regexes.camelCase, camelCaseToSpinalCase); + } + } + encoded = encoded.replace(regexes.space, delimiters.replaceSpace).replace(regexes.forwardSlash, delimiters.replaceForwardSlash).replace(regexes.leftParens, delimiters.replaceLeftParens).replace(regexes.rightParens, delimiters.replaceRightParens).replace(regexes.leftBrace, delimiters.replaceLeftBrace).replace(regexes.rightBrace, delimiters.replaceRightBrace).replace(regexes.caret, delimiters.replaceCaret).replace(regexes.dollar, delimiters.replaceDollar).replace(regexes.at, delimiters.replaceAt); + return encoded; + }; + encoder.decode = function (name) { + var decoded = name; + if (!caseMattersAttributes[decoded] && regexes.uppercaseDelimiterThenChar.test(decoded)) { + if (startsWith(decoded, 'on:') || endsWith(decoded, ':to') || endsWith(decoded, ':from') || endsWith(decoded, ':bind') || endsWith(decoded, ':raw')) { + decoded = decoded.replace(regexes.uppercaseDelimiterThenChar, function (match, char) { + return char.toUpperCase(); + }); + } + } + decoded = decoded.replace(delimiters.replaceLeftParens, '(').replace(delimiters.replaceRightParens, ')').replace(delimiters.replaceLeftBrace, '{').replace(delimiters.replaceRightBrace, '}').replace(delimiters.replaceForwardSlash, '/').replace(delimiters.replaceSpace, ' ').replace(delimiters.replaceCaret, '^').replace(delimiters.replaceDollar, '$').replace(delimiters.replaceAt, '@'); + return decoded; + }; + if (namespace.encoder) { + throw new Error('You can\'t have two versions of can-attribute-encoder, check your dependencies'); + } else { + module.exports = namespace.encoder = encoder; + } +}); +/*can-attribute-observable@2.0.2#event*/ +define('can-attribute-observable@2.0.2#event', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-dom-events', + 'can-dom-events/helpers/util' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var domEvents = require('can-dom-events'); + var isDomEventTarget = require('can-dom-events/helpers/util').isDomEventTarget; + var canEvent = { + on: function on(eventName, handler, queue) { + if (isDomEventTarget(this)) { + domEvents.addEventListener(this, eventName, handler, queue); + } else { + canReflect.onKeyValue(this, eventName, handler, queue); + } + }, + off: function off(eventName, handler, queue) { + if (isDomEventTarget(this)) { + domEvents.removeEventListener(this, eventName, handler, queue); + } else { + canReflect.offKeyValue(this, eventName, handler, queue); + } + }, + one: function one(event, handler, queue) { + var one = function () { + canEvent.off.call(this, event, one, queue); + return handler.apply(this, arguments); + }; + canEvent.on.call(this, event, one, queue); + return this; + } + }; + module.exports = canEvent; +}); +/*can-diff@1.5.0#list/list*/ +define('can-diff@1.5.0#list/list', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var slice = [].slice; + function defaultIdentity(a, b) { + return a === b; + } + function makeIdentityFromMapSchema(typeSchema) { + if (typeSchema.identity && typeSchema.identity.length) { + return function identityCheck(a, b) { + var aId = canReflect.getIdentity(a, typeSchema), bId = canReflect.getIdentity(b, typeSchema); + return aId === bId; + }; + } else { + return defaultIdentity; + } + } + function makeIdentityFromListSchema(listSchema) { + return listSchema.values != null ? makeIdentityFromMapSchema(canReflect.getSchema(listSchema.values)) : defaultIdentity; + } + function makeIdentity(oldList, oldListLength) { + var listSchema = canReflect.getSchema(oldList), typeSchema; + if (listSchema != null) { + if (listSchema.values != null) { + typeSchema = canReflect.getSchema(listSchema.values); + } else { + return defaultIdentity; + } + } + if (typeSchema == null && oldListLength > 0) { + typeSchema = canReflect.getSchema(canReflect.getKeyValue(oldList, 0)); + } + if (typeSchema) { + return makeIdentityFromMapSchema(typeSchema); + } else { + return defaultIdentity; + } + } + function reverseDiff(oldDiffStopIndex, newDiffStopIndex, oldList, newList, identity) { + var oldIndex = oldList.length - 1, newIndex = newList.length - 1; + while (oldIndex > oldDiffStopIndex && newIndex > newDiffStopIndex) { + var oldItem = oldList[oldIndex], newItem = newList[newIndex]; + if (identity(oldItem, newItem, oldIndex)) { + oldIndex--; + newIndex--; + continue; + } else { + return [{ + type: 'splice', + index: newDiffStopIndex, + deleteCount: oldIndex - oldDiffStopIndex + 1, + insert: slice.call(newList, newDiffStopIndex, newIndex + 1) + }]; + } + } + return [{ + type: 'splice', + index: newDiffStopIndex, + deleteCount: oldIndex - oldDiffStopIndex + 1, + insert: slice.call(newList, newDiffStopIndex, newIndex + 1) + }]; + } + module.exports = function (oldList, newList, schemaOrIdentity) { + var oldIndex = 0, newIndex = 0, oldLength = canReflect.size(oldList), newLength = canReflect.size(newList), patches = []; + var schemaType = typeof schemaOrIdentity, identity; + if (schemaType === 'function') { + identity = schemaOrIdentity; + } else if (schemaOrIdentity != null) { + if (schemaOrIdentity.type === 'map') { + identity = makeIdentityFromMapSchema(schemaOrIdentity); + } else { + identity = makeIdentityFromListSchema(schemaOrIdentity); + } + } else { + identity = makeIdentity(oldList, oldLength); + } + while (oldIndex < oldLength && newIndex < newLength) { + var oldItem = oldList[oldIndex], newItem = newList[newIndex]; + if (identity(oldItem, newItem, oldIndex)) { + oldIndex++; + newIndex++; + continue; + } + if (newIndex + 1 < newLength && identity(oldItem, newList[newIndex + 1], oldIndex)) { + patches.push({ + index: newIndex, + deleteCount: 0, + insert: [newList[newIndex]], + type: 'splice' + }); + oldIndex++; + newIndex += 2; + continue; + } else if (oldIndex + 1 < oldLength && identity(oldList[oldIndex + 1], newItem, oldIndex + 1)) { + patches.push({ + index: newIndex, + deleteCount: 1, + insert: [], + type: 'splice' + }); + oldIndex += 2; + newIndex++; + continue; + } else { + patches.push.apply(patches, reverseDiff(oldIndex, newIndex, oldList, newList, identity)); + return patches; + } + } + if (newIndex === newLength && oldIndex === oldLength) { + return patches; + } + patches.push({ + type: 'splice', + index: newIndex, + deleteCount: oldLength - oldIndex, + insert: slice.call(newList, newIndex) + }); + return patches; + }; +}); +/*can-attribute-observable@2.0.2#behaviors*/ +define('can-attribute-observable@2.0.2#behaviors', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-globals/global/global', + 'can-dom-data', + 'can-log/dev/dev', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-globals/mutation-observer/mutation-observer', + 'can-diff/list/list', + 'can-queues' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + var global = require('can-globals/global/global')(); + var setData = require('can-dom-data'); + var dev = require('can-log/dev/dev'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var getMutationObserver = require('can-globals/mutation-observer/mutation-observer'); + var diff = require('can-diff/list/list'); + var queues = require('can-queues'); + var xmlnsAttrNamespaceURI = 'http://www.w3.org/2000/xmlns/'; + var xlinkHrefAttrNamespaceURI = 'http://www.w3.org/1999/xlink'; + var attrsNamespacesURI = { + 'xmlns': xmlnsAttrNamespaceURI, + 'xlink:href': xlinkHrefAttrNamespaceURI + }; + var formElements = { + 'INPUT': true, + 'TEXTAREA': true, + 'SELECT': true, + 'BUTTON': true + }, toString = function (value) { + if (value == null) { + return ''; + } else { + return '' + value; + } + }, isSVG = function (el) { + return el.namespaceURI === 'http://www.w3.org/2000/svg'; + }, truthy = function () { + return true; + }, getSpecialTest = function (special) { + return special && special.test || truthy; + }, propProp = function (prop, obj) { + obj = obj || {}; + obj.get = function () { + return this[prop]; + }; + obj.set = function (value) { + if (this[prop] !== value) { + this[prop] = value; + } + }; + return obj; + }, booleanProp = function (prop) { + return { + isBoolean: true, + set: function (value) { + if (prop in this) { + this[prop] = value; + } else { + domMutateNode.setAttribute.call(this, prop, ''); + } + }, + remove: function () { + this[prop] = false; + } + }; + }, setupMO = function (el, callback) { + var attrMO = setData.get(el, 'attrMO'); + if (!attrMO) { + var onMutation = function () { + callback.call(el); + }; + var MO = getMutationObserver(); + if (MO) { + var observer = new MO(onMutation); + observer.observe(el, { + childList: true, + subtree: true + }); + setData.set(el, 'attrMO', observer); + } else { + setData.set(el, 'attrMO', true); + setData.set(el, 'canBindingCallback', { onMutation: onMutation }); + } + } + }, _findOptionToSelect = function (parent, value) { + var child = parent.firstChild; + while (child) { + if (child.nodeName === 'OPTION' && value === child.value) { + return child; + } + if (child.nodeName === 'OPTGROUP') { + var groupChild = _findOptionToSelect(child, value); + if (groupChild) { + return groupChild; + } + } + child = child.nextSibling; + } + }, setChildOptions = function (el, value) { + var option; + if (value != null) { + option = _findOptionToSelect(el, value); + } + if (option) { + option.selected = true; + } else { + el.selectedIndex = -1; + } + }, forEachOption = function (parent, fn) { + var child = parent.firstChild; + while (child) { + if (child.nodeName === 'OPTION') { + fn(child); + } + if (child.nodeName === 'OPTGROUP') { + forEachOption(child, fn); + } + child = child.nextSibling; + } + }, collectSelectedOptions = function (parent) { + var selectedValues = []; + forEachOption(parent, function (option) { + if (option.selected) { + selectedValues.push(option.value); + } + }); + return selectedValues; + }, markSelectedOptions = function (parent, values) { + forEachOption(parent, function (option) { + option.selected = values.indexOf(option.value) !== -1; + }); + }, setChildOptionsOnChange = function (select, aEL) { + var handler = setData.get(select, 'attrSetChildOptions'); + if (handler) { + return Function.prototype; + } + handler = function () { + setChildOptions(select, select.value); + }; + setData.set(select, 'attrSetChildOptions', handler); + aEL.call(select, 'change', handler); + return function (rEL) { + setData.clean(select, 'attrSetChildOptions'); + rEL.call(select, 'change', handler); + }; + }, behaviorRules = new Map(), isPropWritable = function (el, prop) { + var desc = Object.getOwnPropertyDescriptor(el, prop); + if (desc) { + return desc.writable || desc.set; + } else { + var proto = Object.getPrototypeOf(el); + if (proto) { + return isPropWritable(proto, prop); + } + } + return false; + }, cacheRule = function (el, attrOrPropName, rule) { + var rulesForElementType; + rulesForElementType = behaviorRules.get(el.prototype); + if (!rulesForElementType) { + rulesForElementType = {}; + behaviorRules.set(el.constructor, rulesForElementType); + } + rulesForElementType[attrOrPropName] = rule; + return rule; + }; + var specialAttributes = { + checked: { + get: function () { + return this.checked; + }, + set: function (val) { + var notFalse = !!val || val === '' || arguments.length === 0; + this.checked = notFalse; + if (notFalse && this.type === 'radio') { + this.defaultChecked = true; + } + }, + remove: function () { + this.checked = false; + }, + test: function () { + return this.nodeName === 'INPUT'; + } + }, + 'class': { + get: function () { + if (isSVG(this)) { + return this.getAttribute('class'); + } + return this.className; + }, + set: function (val) { + val = val || ''; + if (isSVG(this)) { + domMutateNode.setAttribute.call(this, 'class', '' + val); + } else { + this.className = val; + } + } + }, + disabled: booleanProp('disabled'), + focused: { + get: function () { + return this === document.activeElement; + }, + set: function (val) { + var cur = attr.get(this, 'focused'); + var docEl = this.ownerDocument.documentElement; + var element = this; + function focusTask() { + if (val) { + element.focus(); + } else { + element.blur(); + } + } + if (cur !== val) { + if (!docEl.contains(element)) { + var connectionDisposal = domMutate.onNodeConnected(element, function () { + connectionDisposal(); + focusTask(); + }); + } else { + queues.enqueueByQueue({ mutate: [focusTask] }, null, []); + } + } + return true; + }, + addEventListener: function (eventName, handler, aEL) { + aEL.call(this, 'focus', handler); + aEL.call(this, 'blur', handler); + return function (rEL) { + rEL.call(this, 'focus', handler); + rEL.call(this, 'blur', handler); + }; + }, + test: function () { + return this.nodeName === 'INPUT'; + } + }, + 'for': propProp('htmlFor'), + innertext: propProp('innerText'), + innerhtml: propProp('innerHTML'), + innerHTML: propProp('innerHTML', { + addEventListener: function (eventName, handler, aEL) { + var handlers = []; + var el = this; + [ + 'change', + 'blur' + ].forEach(function (eventName) { + var localHandler = function () { + handler.apply(this, arguments); + }; + domEvents.addEventListener(el, eventName, localHandler); + handlers.push([ + eventName, + localHandler + ]); + }); + return function (rEL) { + handlers.forEach(function (info) { + rEL.call(el, info[0], info[1]); + }); + }; + } + }), + required: booleanProp('required'), + readonly: booleanProp('readOnly'), + selected: { + get: function () { + return this.selected; + }, + set: function (val) { + val = !!val; + setData.set(this, 'lastSetValue', val); + this.selected = val; + }, + addEventListener: function (eventName, handler, aEL) { + var option = this; + var select = this.parentNode; + var lastVal = option.selected; + var localHandler = function (changeEvent) { + var curVal = option.selected; + lastVal = setData.get(option, 'lastSetValue') || lastVal; + if (curVal !== lastVal) { + lastVal = curVal; + domEvents.dispatch(option, eventName); + } + }; + var removeChangeHandler = setChildOptionsOnChange(select, aEL); + domEvents.addEventListener(select, 'change', localHandler); + aEL.call(option, eventName, handler); + return function (rEL) { + removeChangeHandler(rEL); + domEvents.removeEventListener(select, 'change', localHandler); + rEL.call(option, eventName, handler); + }; + }, + test: function () { + return this.nodeName === 'OPTION' && this.parentNode && this.parentNode.nodeName === 'SELECT'; + } + }, + style: { + set: function () { + var el = global.document && getDocument().createElement('div'); + if (el && el.style && 'cssText' in el.style) { + return function (val) { + this.style.cssText = val || ''; + }; + } else { + return function (val) { + domMutateNode.setAttribute.call(this, 'style', val); + }; + } + }() + }, + textcontent: propProp('textContent'), + value: { + get: function () { + var value = this.value; + if (this.nodeName === 'SELECT') { + if ('selectedIndex' in this && this.selectedIndex === -1) { + value = undefined; + } + } + return value; + }, + set: function (value) { + var providedValue = value; + var nodeName = this.nodeName.toLowerCase(); + if (nodeName === 'input' || nodeName === 'textarea') { + value = toString(value); + } + if (this.value !== value || nodeName === 'option') { + this.value = value; + } + if (nodeName === 'input' || nodeName === 'textarea') { + this.defaultValue = value; + } + if (nodeName === 'select') { + setData.set(this, 'attrValueLastVal', value); + setChildOptions(this, value === null ? value : this.value); + var docEl = this.ownerDocument.documentElement; + if (!docEl.contains(this)) { + var select = this; + var connectionDisposal = domMutate.onNodeConnected(select, function () { + connectionDisposal(); + setChildOptions(select, value === null ? value : select.value); + }); + } + setupMO(this, function () { + var value = setData.get(this, 'attrValueLastVal'); + attr.set(this, 'value', value); + domEvents.dispatch(this, 'change'); + }); + } + }, + test: function () { + return formElements[this.nodeName]; + } + }, + values: { + get: function () { + return collectSelectedOptions(this); + }, + set: function (values) { + values = values || []; + markSelectedOptions(this, values); + setData.set(this, 'stickyValues', attr.get(this, 'values')); + setupMO(this, function () { + var previousValues = setData.get(this, 'stickyValues'); + attr.set(this, 'values', previousValues); + var currentValues = setData.get(this, 'stickyValues'); + var changes = diff(previousValues.slice().sort(), currentValues.slice().sort()); + if (changes.length) { + domEvents.dispatch(this, 'values'); + } + }); + }, + addEventListener: function (eventName, handler, aEL) { + var localHandler = function () { + domEvents.dispatch(this, 'values'); + }; + domEvents.addEventListener(this, 'change', localHandler); + aEL.call(this, eventName, handler); + return function (rEL) { + domEvents.removeEventListener(this, 'change', localHandler); + rEL.call(this, eventName, handler); + }; + } + } + }; + var attr = { + rules: behaviorRules, + specialAttributes: specialAttributes, + getRule: function (el, attrOrPropName) { + var special = specialAttributes[attrOrPropName]; + if (special) { + return special; + } + var rulesForElementType = behaviorRules.get(el.constructor); + var cached = rulesForElementType && rulesForElementType[attrOrPropName]; + if (cached) { + return cached; + } + if (!(attrOrPropName in el)) { + return this.attribute(attrOrPropName); + } + var newRule = isPropWritable(el, attrOrPropName) ? this.property(attrOrPropName) : this.attribute(attrOrPropName); + return cacheRule(el, attrOrPropName, newRule); + }, + attribute: function (attrName) { + return { + get: function () { + return this.getAttribute(attrName); + }, + set: function (val) { + if (attrsNamespacesURI[attrName]) { + domMutateNode.setAttributeNS.call(this, attrsNamespacesURI[attrName], attrName, val); + } else { + domMutateNode.setAttribute.call(this, attrName, val); + } + } + }; + }, + property: function (propName) { + return { + get: function () { + return this[propName]; + }, + set: function (val) { + this[propName] = val; + } + }; + }, + findSpecialListener: function (attributeName) { + return specialAttributes[attributeName] && specialAttributes[attributeName].addEventListener; + }, + setAttrOrProp: function (el, attrName, val) { + return this.set(el, attrName, val); + }, + set: function (el, attrName, val) { + var rule = this.getRule(el, attrName); + var setter = rule && rule.set; + if (setter) { + return setter.call(el, val); + } + }, + get: function (el, attrName) { + var rule = this.getRule(el, attrName); + var getter = rule && rule.get; + if (getter) { + return rule.test ? rule.test.call(el) && getter.call(el) : getter.call(el); + } + }, + remove: function (el, attrName) { + attrName = attrName.toLowerCase(); + var special = specialAttributes[attrName]; + var setter = special && special.set; + var remover = special && special.remove; + var test = getSpecialTest(special); + if (typeof remover === 'function' && test.call(el)) { + remover.call(el); + } else if (typeof setter === 'function' && test.call(el)) { + setter.call(el, undefined); + } else { + domMutateNode.removeAttribute.call(el, attrName); + } + } + }; + module.exports = attr; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-attribute-observable@2.0.2#get-event-name*/ +define('can-attribute-observable@2.0.2#get-event-name', [ + 'require', + 'exports', + 'module', + './behaviors' +], function (require, exports, module) { + 'use strict'; + var attr = require('./behaviors'); + var isRadioInput = function isRadioInput(el) { + return el.nodeName.toLowerCase() === 'input' && el.type === 'radio'; + }; + module.exports = function getEventName(el, prop) { + var event = 'change'; + if (isRadioInput(el) && prop === 'checked') { + event = 'can-attribute-observable-radiochange'; + } + if (attr.findSpecialListener(prop)) { + event = prop; + } + return event; + }; +}); +/*can-event-dom-radiochange@2.2.1#can-event-dom-radiochange*/ +define('can-event-dom-radiochange@2.2.1#can-event-dom-radiochange', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-namespace' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + var namespace = require('can-namespace'); + function getRoot() { + return getDocument().documentElement; + } + function findParentForm(el) { + while (el) { + if (el.nodeName === 'FORM') { + break; + } + el = el.parentNode; + } + return el; + } + function shouldReceiveEventFromRadio(source, dest) { + var name = source.getAttribute('name'); + return name && name === dest.getAttribute('name') && findParentForm(source) === findParentForm(dest); + } + function isRadioInput(el) { + return el.nodeName === 'INPUT' && el.type === 'radio'; + } + function attachRootListener(domEvents, eventTypeTargets) { + var root = getRoot(); + var newListener = function (event) { + var target = event.target; + if (!isRadioInput(target)) { + return; + } + for (var eventType in eventTypeTargets) { + var newEvent = { type: eventType }; + var listeningNodes = eventTypeTargets[eventType]; + listeningNodes.forEach(function (el) { + if (shouldReceiveEventFromRadio(target, el)) { + domEvents.dispatch(el, newEvent, false); + } + }); + } + }; + domEvents.addEventListener(root, 'change', newListener); + return newListener; + } + function detachRootListener(domEvents, listener) { + var root = getRoot(); + domEvents.removeEventListener(root, 'change', listener); + } + var radioChangeEvent = { + defaultEventType: 'radiochange', + addEventListener: function (target, eventType, handler) { + if (!isRadioInput(target)) { + throw new Error('Listeners for ' + eventType + ' must be radio inputs'); + } + var eventTypeTrackedRadios = radioChangeEvent._eventTypeTrackedRadios; + if (!eventTypeTrackedRadios) { + eventTypeTrackedRadios = radioChangeEvent._eventTypeTrackedRadios = {}; + if (!radioChangeEvent._rootListener) { + radioChangeEvent._rootListener = attachRootListener(this, eventTypeTrackedRadios); + } + } + var trackedRadios = radioChangeEvent._eventTypeTrackedRadios[eventType]; + if (!trackedRadios) { + trackedRadios = radioChangeEvent._eventTypeTrackedRadios[eventType] = new Set(); + } + trackedRadios.add(target); + target.addEventListener(eventType, handler); + }, + removeEventListener: function (target, eventType, handler) { + target.removeEventListener(eventType, handler); + var eventTypeTrackedRadios = radioChangeEvent._eventTypeTrackedRadios; + if (!eventTypeTrackedRadios) { + return; + } + var trackedRadios = eventTypeTrackedRadios[eventType]; + if (!trackedRadios) { + return; + } + trackedRadios.delete(target); + if (trackedRadios.size === 0) { + delete eventTypeTrackedRadios[eventType]; + for (var key in eventTypeTrackedRadios) { + if (eventTypeTrackedRadios.hasOwnProperty(key)) { + return; + } + } + delete radioChangeEvent._eventTypeTrackedRadios; + detachRootListener(this, radioChangeEvent._rootListener); + delete radioChangeEvent._rootListener; + } + } + }; + module.exports = namespace.domEventRadioChange = radioChangeEvent; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-attribute-observable@2.0.2#can-attribute-observable*/ +define('can-attribute-observable@2.0.2#can-attribute-observable', [ + 'require', + 'exports', + 'module', + 'can-queues', + './event', + 'can-reflect', + 'can-observation', + './behaviors', + './get-event-name', + 'can-reflect-dependencies', + 'can-observation-recorder', + 'can-simple-observable/settable/settable', + 'can-assign', + 'can-symbol', + 'can-dom-events', + 'can-event-dom-radiochange' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var queues = require('can-queues'); + var canEvent = require('./event'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var attr = require('./behaviors'); + var getEventName = require('./get-event-name'); + var canReflectDeps = require('can-reflect-dependencies'); + var ObservationRecorder = require('can-observation-recorder'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var canAssign = require('can-assign'); + var canSymbol = require('can-symbol'); + var onValueSymbol = canSymbol.for('can.onValue'); + var offValueSymbol = canSymbol.for('can.offValue'); + var onEmitSymbol = canSymbol.for('can.onEmit'); + var offEmitSymbol = canSymbol.for('can.offEmit'); + var domEvents = require('can-dom-events'); + var radioChangeEvent = require('can-event-dom-radiochange'); + var internalRadioChangeEventType = 'can-attribute-observable-radiochange'; + domEvents.addEvent(radioChangeEvent, internalRadioChangeEventType); + var isSelect = function isSelect(el) { + return el.nodeName.toLowerCase() === 'select'; + }; + var isMultipleSelect = function isMultipleSelect(el, prop) { + return isSelect(el) && prop === 'value' && el.multiple; + }; + var slice = Array.prototype.slice; + function canUtilAEL() { + var args = slice.call(arguments, 0); + args.unshift(this); + return domEvents.addEventListener.apply(null, args); + } + function canUtilREL() { + var args = slice.call(arguments, 0); + args.unshift(this); + return domEvents.removeEventListener.apply(null, args); + } + function AttributeObservable(el, prop, bindingData, event) { + if (typeof bindingData === 'string') { + event = bindingData; + bindingData = undefined; + } + this.el = el; + this.bound = false; + this.prop = isMultipleSelect(el, prop) ? 'values' : prop; + this.event = event || getEventName(el, prop); + this.handler = this.handler.bind(this); + if (event !== undefined) { + this[onValueSymbol] = null; + this[offValueSymbol] = null; + this[onEmitSymbol] = AttributeObservable.prototype.on; + this[offEmitSymbol] = AttributeObservable.prototype.off; + } + } + AttributeObservable.prototype = Object.create(SettableObservable.prototype); + canAssign(AttributeObservable.prototype, { + constructor: AttributeObservable, + get: function get() { + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (!this.bound) { + Observation.temporarilyBind(this); + } + } + var value = attr.get(this.el, this.prop); + if (typeof value === 'function') { + value = value.bind(this.el); + } + return value; + }, + set: function set(newVal) { + var setterDispatchedEvents = attr.setAttrOrProp(this.el, this.prop, newVal); + if (!setterDispatchedEvents) { + this._value = newVal; + } + return newVal; + }, + handler: function handler(newVal, event) { + var old = this._value; + var queuesArgs = []; + this._value = attr.get(this.el, this.prop); + if (event !== undefined || this._value !== old) { + queuesArgs = [ + this.handlers.getNode([]), + this, + [ + newVal, + old + ] + ]; + queues.enqueueByQueue.apply(queues, queuesArgs); + } + }, + onBound: function onBound() { + var observable = this; + observable.bound = true; + observable._handler = function (event) { + observable.handler(attr.get(observable.el, observable.prop), event); + }; + if (observable.event === internalRadioChangeEventType) { + canEvent.on.call(observable.el, 'change', observable._handler); + } + var specialBinding = attr.findSpecialListener(observable.prop); + if (specialBinding) { + observable._specialDisposal = specialBinding.call(observable.el, observable.prop, observable._handler, canUtilAEL); + } + canEvent.on.call(observable.el, observable.event, observable._handler); + this._value = attr.get(this.el, this.prop); + }, + onUnbound: function onUnbound() { + var observable = this; + observable.bound = false; + if (observable.event === internalRadioChangeEventType) { + canEvent.off.call(observable.el, 'change', observable._handler); + } + if (observable._specialDisposal) { + observable._specialDisposal.call(observable.el, canUtilREL); + observable._specialDisposal = null; + } + canEvent.off.call(observable.el, observable.event, observable._handler); + }, + valueHasDependencies: function valueHasDependencies() { + return true; + }, + getValueDependencies: function getValueDependencies() { + var m = new Map(); + var s = new Set(); + s.add(this.prop); + m.set(this.el, s); + return { keyDependencies: m }; + } + }); + canReflect.assignSymbols(AttributeObservable.prototype, { + 'can.isMapLike': false, + 'can.getValue': AttributeObservable.prototype.get, + 'can.setValue': AttributeObservable.prototype.set, + 'can.onValue': AttributeObservable.prototype.on, + 'can.offValue': AttributeObservable.prototype.off, + 'can.valueHasDependencies': AttributeObservable.prototype.hasDependencies, + 'can.getValueDependencies': AttributeObservable.prototype.getValueDependencies + }); + module.exports = AttributeObservable; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-bindings@5.0.4#can-stache-bindings*/ +define('can-stache-bindings@5.0.4#can-stache-bindings', [ + 'require', + 'exports', + 'module', + 'can-bind', + 'can-stache/src/expression', + 'can-view-model', + 'can-stache-key', + 'can-observation-recorder', + 'can-simple-observable', + 'can-view-scope', + 'can-assign', + 'can-log/dev/dev', + 'can-dom-mutate', + 'can-dom-data', + 'can-symbol', + 'can-reflect', + 'can-reflect-dependencies', + 'can-attribute-encoder', + 'can-queues', + 'can-simple-observable/setter/setter', + 'can-attribute-observable', + 'can-view-scope/make-compute-like', + 'can-event-queue/map/map' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var Bind = require('can-bind'); + var expression = require('can-stache/src/expression'); + var canViewModel = require('can-view-model'); + var stacheKey = require('can-stache-key'); + var ObservationRecorder = require('can-observation-recorder'); + var SimpleObservable = require('can-simple-observable'); + var Scope = require('can-view-scope'); + var assign = require('can-assign'); + var dev = require('can-log/dev/dev'); + var domMutate = require('can-dom-mutate'); + var domData = require('can-dom-data'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var canReflectDeps = require('can-reflect-dependencies'); + var encoder = require('can-attribute-encoder'); + var queues = require('can-queues'); + var SettableObservable = require('can-simple-observable/setter/setter'); + var AttributeObservable = require('can-attribute-observable'); + var makeCompute = require('can-view-scope/make-compute-like'); + var canEventQueue = require('can-event-queue/map/map'); + var bindings = new Map(); + var onMatchStr = 'on:', vmMatchStr = 'vm:', elMatchStr = 'el:', byMatchStr = ':by:', toMatchStr = ':to', fromMatchStr = ':from', bindMatchStr = ':bind', viewModelBindingStr = 'viewModel', attributeBindingStr = 'attribute', scopeBindingStr = 'scope', viewModelOrAttributeBindingStr = 'viewModelOrAttribute', viewModelSymbol = canSymbol.for('can.viewModel'), preventDataBindingsSymbol = canSymbol.for('can.preventDataBindings'); + var throwOnlyOneTypeOfBindingError = function () { + throw new Error('can-stache-bindings - you can not have contextual bindings ( this:from=\'value\' ) and key bindings ( prop:from=\'value\' ) on one element.'); + }; + var checkBindingState = function (bindingState, siblingBindingData) { + var isSettingOnViewModel = siblingBindingData.parent.exports && siblingBindingData.child.source === viewModelBindingStr; + if (isSettingOnViewModel) { + var bindingName = siblingBindingData.child.name; + var isSettingViewModel = isSettingOnViewModel && (bindingName === 'this' || bindingName === '.'); + if (isSettingViewModel) { + if (bindingState.isSettingViewModel || bindingState.isSettingOnViewModel) { + throwOnlyOneTypeOfBindingError(); + } else { + return { + isSettingViewModel: true, + initialViewModelData: undefined + }; + } + } else { + if (bindingState.isSettingViewModel) { + throwOnlyOneTypeOfBindingError(); + } else { + return { + isSettingOnViewModel: true, + initialViewModelData: bindingState.initialViewModelData + }; + } + } + } else { + return bindingState; + } + }; + var getEventBindingData = function (attributeName, el, scope) { + var bindingCode = attributeName.substr(onMatchStr.length); + var viewModel = el && el[viewModelSymbol]; + var elUsed = startsWith.call(bindingCode, elMatchStr); + var vmUsed = startsWith.call(bindingCode, vmMatchStr); + var byUsed = bindingCode.indexOf(byMatchStr) > -1; + var scopeUsed; + var bindingContext; + var eventName; + var bindingContextObservable; + var shortBindingCode = ''; + if (vmUsed) { + shortBindingCode = 'vm'; + bindingCode = bindingCode.substr(vmMatchStr.length); + } else if (elUsed) { + shortBindingCode = 'el'; + bindingCode = bindingCode.substr(elMatchStr.length); + } else if (!vmUsed && !elUsed) { + if (byUsed) { + scopeUsed = true; + } else if (viewModel) { + vmUsed = true; + } else { + elUsed = true; + } + } + var bindingContextKey; + if (byUsed) { + var byIndex = bindingCode.indexOf(byMatchStr); + bindingContextKey = bindingCode.substr(byIndex + byMatchStr.length); + bindingCode = bindingCode.substr(0, byIndex); + } + eventName = bindingCode; + if (elUsed) { + if (byUsed) { + throw new Error('binding with :by in element scope is not currently supported'); + } else { + bindingContext = el; + } + } else if (vmUsed) { + bindingContext = viewModel; + if (byUsed) { + bindingContext = viewModel.get(bindingContextKey); + bindingContextObservable = new Scope(viewModel).computeData(bindingContextKey); + } + } else if (scopeUsed) { + bindingContext = scope; + if (byUsed) { + bindingContext = bindingContext.get(bindingContextKey); + bindingContextObservable = scope.computeData(bindingContextKey); + } + } + return { + bindingContext: bindingContext, + bindingContextObservable: bindingContextObservable, + eventName: eventName, + bindingCode: shortBindingCode + }; + }; + var onKeyValueSymbol = canSymbol.for('can.onKeyValue'); + var makeScopeFromEvent = function (element, event, viewModel, args, data, bindingContext) { + var shiftArgumentsForLegacyArguments = bindingContext && bindingContext[onKeyValueSymbol] !== undefined; + var specialValues = { + element: element, + event: event, + viewModel: viewModel, + arguments: shiftArgumentsForLegacyArguments ? Array.prototype.slice.call(args, 1) : args, + args: args + }; + return data.scope.add(specialValues, { special: true }); + }; + var runEventCallback = function (el, ev, data, scope, expr, attributeName, attrVal) { + var updateFn = function () { + var value = expr.value(scope, { doNotWrapInObservation: true }); + value = canReflect.isValueLike(value) ? canReflect.getValue(value) : value; + return typeof value === 'function' ? value(el) : value; + }; + queues.batch.start(); + var mutateQueueArgs = []; + mutateQueueArgs = [ + updateFn, + null, + null, + {} + ]; + queues.mutateQueue.enqueue.apply(queues.mutateQueue, mutateQueueArgs); + queues.batch.stop(); + }; + var behaviors = { + initializeViewModel: function (bindings, initialViewModelData, makeViewModel, bindingContext) { + var onCompleteBindings = [], onTeardowns = {}; + var bindingsState = { + isSettingOnViewModel: false, + isSettingViewModel: false, + initialViewModelData: initialViewModelData || {} + }; + bindings.forEach(function (dataBinding) { + dataBinding.binding.startParent(); + var siblingBindingData = dataBinding.siblingBindingData; + bindingsState = checkBindingState(bindingsState, siblingBindingData); + if (siblingBindingData.parent.exports) { + var parentValue = siblingBindingData.child.setCompute ? makeCompute(dataBinding.binding.parent) : dataBinding.binding.parentValue; + if (parentValue !== undefined) { + if (bindingsState.isSettingViewModel) { + bindingsState.initialViewModelData = parentValue; + } else { + bindingsState.initialViewModelData[cleanVMName(siblingBindingData.child.name, bindingContext.scope)] = parentValue; + } + } + } + onCompleteBindings.push(dataBinding.binding.start.bind(dataBinding.binding)); + onTeardowns[siblingBindingData.bindingAttributeName] = dataBinding.binding.stop.bind(dataBinding.binding); + }); + var viewModel = makeViewModel(bindingsState.initialViewModelData, bindings.length > 0, bindingsState); + for (var i = 0, len = onCompleteBindings.length; i < len; i++) { + onCompleteBindings[i](); + } + return { + viewModel: viewModel, + onTeardowns: onTeardowns, + bindingsState: bindingsState + }; + }, + viewModel: function (el, tagData, makeViewModel, initialViewModelData, staticDataBindingsOnly) { + var attributeViewModelBindings = assign({}, initialViewModelData), bindingContext = assign({ + element: el, + viewModel: undefined + }, tagData), bindingSettings = { + attributeViewModelBindings: attributeViewModelBindings, + alreadyUpdatedChild: true, + favorViewModel: true + }, dataBindings = []; + canReflect.eachListLike(el.attributes || [], function (node) { + var dataBinding = makeDataBinding(node, bindingContext, bindingSettings); + if (dataBinding) { + dataBindings.push(dataBinding); + } + }); + if (staticDataBindingsOnly && dataBindings.length === 0) { + return; + } + var completedData = behaviors.initializeViewModel(dataBindings, initialViewModelData, function () { + bindingContext.viewModel = makeViewModel.apply(this, arguments); + }, bindingContext), onTeardowns = completedData.onTeardowns, bindingsState = completedData.bindingsState, siblingBindingDatas = {}; + var attributeDisposal; + if (!bindingsState.isSettingViewModel) { + bindingSettings.alreadyUpdatedChild = false; + attributeDisposal = domMutate.onNodeAttributeChange(el, function (ev) { + var attrName = ev.attributeName, value = el.getAttribute(attrName); + if (onTeardowns[attrName]) { + onTeardowns[attrName](); + } + var parentBindingWasAttribute = siblingBindingDatas[attrName] && siblingBindingDatas[attrName].parent.source === attributeBindingStr; + if (value !== null || parentBindingWasAttribute) { + var dataBinding = makeDataBinding({ + name: attrName, + value: value + }, bindingContext, bindingSettings); + if (dataBinding) { + dataBinding.binding.start(); + siblingBindingDatas[attrName] = dataBinding.siblingBindingData; + onTeardowns[attrName] = dataBinding.binding.stop.bind(dataBinding.binding); + } + } + }); + } + return function () { + if (attributeDisposal) { + attributeDisposal(); + attributeDisposal = undefined; + } + for (var attrName in onTeardowns) { + onTeardowns[attrName](); + } + }; + }, + data: function (el, attrData) { + if (el[preventDataBindingsSymbol] === true || domData.get(el, 'preventDataBindings')) { + return; + } + var viewModel, getViewModel = ObservationRecorder.ignore(function () { + return viewModel || (viewModel = canViewModel(el)); + }), teardown, attributeDisposal, removedDisposal, bindingContext = { + element: el, + templateType: attrData.templateType, + scope: attrData.scope, + parentNodeList: attrData.nodeList, + get viewModel() { + return getViewModel(); + } + }; + var dataBinding = makeDataBinding({ + name: attrData.attributeName, + value: el.getAttribute(attrData.attributeName) + }, bindingContext, { syncChildWithParent: false }); + var started = false; + if (!started) { + dataBinding.binding.start(); + started = true; + } + var attributeListener = function (ev) { + var attrName = ev.attributeName, value = el.getAttribute(attrName); + if (attrName === attrData.attributeName) { + if (teardown) { + teardown(); + } + if (value !== null) { + var dataBinding = makeDataBinding({ + name: attrName, + value: value + }, bindingContext, { syncChildWithParent: false }); + if (dataBinding) { + dataBinding.binding.start(); + teardown = dataBinding.binding.stop.bind(dataBinding.binding); + } + teardown = dataBinding.onTeardown; + } + } + }; + var tearItAllDown = function () { + if (teardown) { + teardown(); + teardown = undefined; + } + if (removedDisposal) { + removedDisposal(); + removedDisposal = undefined; + } + if (attributeDisposal) { + attributeDisposal(); + attributeDisposal = undefined; + } + }; + teardown = dataBinding.binding.stop.bind(dataBinding.binding); + attributeDisposal = domMutate.onNodeAttributeChange(el, attributeListener); + removedDisposal = domMutate.onNodeDisconnected(el, function () { + var doc = el.ownerDocument; + var ownerNode = doc.contains ? doc : doc.documentElement; + if (!ownerNode || ownerNode.contains(el) === false) { + tearItAllDown(); + } + }); + }, + event: function (el, data) { + var eventBindingData; + var attributeName = encoder.decode(data.attributeName), event, bindingContext, bindingContextObservable; + if (attributeName.indexOf(toMatchStr + ':') !== -1 || attributeName.indexOf(fromMatchStr + ':') !== -1 || attributeName.indexOf(bindMatchStr + ':') !== -1) { + return this.data(el, data); + } + if (startsWith.call(attributeName, onMatchStr)) { + eventBindingData = getEventBindingData(attributeName, el, data.scope); + event = eventBindingData.eventName; + bindingContext = eventBindingData.bindingContext; + bindingContextObservable = eventBindingData.bindingContextObservable; + } else { + throw new Error('can-stache-bindings - unsupported event bindings ' + attributeName); + } + var handler = function (ev) { + var attrVal = el.getAttribute(encoder.encode(attributeName)); + if (!attrVal) { + return; + } + var viewModel = el[viewModelSymbol]; + var expr = expression.parse(attrVal, { + lookupRule: function () { + return expression.Lookup; + }, + methodRule: 'call' + }); + var runScope = makeScopeFromEvent(el, ev, viewModel, arguments, data, bindingContext); + if (expr instanceof expression.Hashes) { + var hashExprs = expr.hashExprs; + var key = Object.keys(hashExprs)[0]; + var value = expr.hashExprs[key].value(runScope); + var isObservableValue = canReflect.isObservableLike(value) && canReflect.isValueLike(value); + runScope.set(key, isObservableValue ? canReflect.getValue(value) : value); + } else if (expr instanceof expression.Call) { + runEventCallback(el, ev, data, runScope, expr, attributeName, attrVal); + } else { + throw new Error('can-stache-bindings: Event bindings must be a call expression. Make sure you have a () in ' + data.attributeName + '=' + JSON.stringify(attrVal)); + } + }; + var attributesDisposal, removalDisposal, removeObservation, currentContext; + var attributesHandler = function (ev) { + var isEventAttribute = ev.attributeName === attributeName; + var isRemoved = !el.getAttribute(attributeName); + var isEventAttributeRemoved = isEventAttribute && isRemoved; + if (isEventAttributeRemoved) { + unbindEvent(); + } + }; + var removalHandler = function () { + var doc = el.ownerDocument; + var ownerNode = doc.contains ? doc : doc.documentElement; + if (!ownerNode || !ownerNode.contains(el)) { + unbindEvent(); + } + }; + var unbindEvent = function () { + if (bindingContext) { + canEventQueue.off.call(bindingContext, event, handler); + } + if (attributesDisposal) { + attributesDisposal(); + attributesDisposal = undefined; + } + if (removalDisposal) { + removalDisposal(); + removalDisposal = undefined; + } + if (removeObservation) { + removeObservation(); + removeObservation = undefined; + } + }; + function updateListener(newVal, oldVal) { + if (oldVal) { + canEventQueue.off.call(oldVal, event, handler); + } + if (newVal) { + canEventQueue.on.call(newVal, event, handler); + currentContext = newVal; + } + } + attributesDisposal = domMutate.onNodeAttributeChange(el, attributesHandler); + removalDisposal = domMutate.onNodeDisconnected(el, removalHandler); + if (!bindingContext && bindingContextObservable) { + removeObservation = function () { + if (currentContext) { + canEventQueue.off.call(currentContext, event, handler); + } + canReflect.offValue(bindingContextObservable, updateListener); + }; + canReflect.onValue(bindingContextObservable, updateListener); + } else { + try { + canEventQueue.on.call(bindingContext, event, handler); + } catch (error) { + if (/Unable to bind/.test(error.message)) { + var msg = 'can-stache-bindings - Unable to bind "' + event + '"'; + msg += ': "' + event + '" is a property on a plain object "'; + msg += JSON.stringify(bindingContext); + msg += '". Binding is available with observable objects only.'; + msg += ' For more details check https://canjs.com/doc/can-stache-bindings.html#Callafunctionwhenaneventhappensonavalueinthescope_animation_'; + throw new Error(msg); + } else { + throw error; + } + } + } + } + }; + bindings.set(/[\w\.:]+:to$/, behaviors.data); + bindings.set(/[\w\.:]+:from$/, behaviors.data); + bindings.set(/[\w\.:]+:bind$/, behaviors.data); + bindings.set(/[\w\.:]+:raw$/, behaviors.data); + bindings.set(/[\w\.:]+:to:on:[\w\.:]+/, behaviors.data); + bindings.set(/[\w\.:]+:from:on:[\w\.:]+/, behaviors.data); + bindings.set(/[\w\.:]+:bind:on:[\w\.:]+/, behaviors.data); + bindings.set(/on:[\w\.:]+/, behaviors.event); + var getObservableFrom = { + viewModelOrAttribute: function (bindingData, bindingContext) { + var viewModel = bindingContext.element[viewModelSymbol]; + if (viewModel) { + return this.viewModel.apply(this, arguments); + } else { + return this.attribute.apply(this, arguments); + } + }, + scope: function (bindingData, bindingContext) { + var scope = bindingContext.scope, scopeProp = bindingData.name, mustBeGettable = bindingData.exports; + if (!scopeProp) { + return new SimpleObservable(); + } else { + if (mustBeGettable || scopeProp.indexOf('(') >= 0 || scopeProp.indexOf('=') >= 0) { + var parentExpression = expression.parse(scopeProp, { baseMethodType: 'Call' }); + if (parentExpression instanceof expression.Hashes) { + return new SimpleObservable(function () { + var hashExprs = parentExpression.hashExprs; + var key = Object.keys(hashExprs)[0]; + var value = parentExpression.hashExprs[key].value(scope); + var isObservableValue = canReflect.isObservableLike(value) && canReflect.isValueLike(value); + scope.set(key, isObservableValue ? canReflect.getValue(value) : value); + }); + } else { + return parentExpression.value(scope); + } + } else { + var observation = {}; + canReflect.assignSymbols(observation, { + 'can.getValue': function getValue() { + }, + 'can.valueHasDependencies': function hasValueDependencies() { + return false; + }, + 'can.setValue': function setValue(newVal) { + var expr = expression.parse(cleanVMName(scopeProp, scope), { baseMethodType: 'Call' }); + var value = expr.value(scope); + canReflect.setValue(value, newVal); + }, + 'can.getWhatIChange': function getWhatIChange() { + var data = scope.getDataForScopeSet(cleanVMName(scopeProp, scope)); + var m = new Map(); + var s = new Set(); + s.add(data.key); + m.set(data.parent, s); + return { mutate: { keyDependencies: m } }; + }, + 'can.getName': function getName() { + } + }); + var data = scope.getDataForScopeSet(cleanVMName(scopeProp, scope)); + if (data.parent && data.key) { + canReflectDeps.addMutatedBy(data.parent, data.key, observation); + } + return observation; + } + } + }, + viewModel: function (bindingData, bindingContext) { + var scope = bindingContext.scope, vmName = bindingData.name, setCompute = bindingData.setCompute; + var setName = cleanVMName(vmName, scope); + var isBoundToContext = vmName === '.' || vmName === 'this'; + var keysToRead = isBoundToContext ? [] : stacheKey.reads(vmName); + function getViewModelProperty() { + var viewModel = bindingContext.viewModel; + return stacheKey.read(viewModel, keysToRead, {}).value; + } + var observation = new SettableObservable(getViewModelProperty, function setViewModelProperty(newVal) { + var viewModel = bindingContext.viewModel; + if (setCompute) { + var oldValue = canReflect.getKeyValue(viewModel, setName); + if (canReflect.isObservableLike(oldValue)) { + canReflect.setValue(oldValue, newVal); + } else { + canReflect.setKeyValue(viewModel, setName, new SimpleObservable(canReflect.getValue(newVal))); + } + } else { + if (isBoundToContext) { + canReflect.setValue(viewModel, newVal); + } else { + stacheKey.write(viewModel, keysToRead, newVal); + } + } + }); + return observation; + }, + attribute: function (bindingData, bindingContext) { + if (bindingData.name === 'this') { + return canReflect.assignSymbols({}, { + 'can.getValue': function () { + return bindingContext.element; + }, + 'can.valueHasDependencies': function () { + return false; + }, + 'can.getName': function getName() { + } + }); + } else { + return new AttributeObservable(bindingContext.element, bindingData.name, {}, bindingData.event); + } + } + }; + var startsWith = String.prototype.startsWith || function (text) { + return this.indexOf(text) === 0; + }; + function getEventName(result) { + if (result.special.on !== undefined) { + return result.tokens[result.special.on + 1]; + } + } + var siblingBindingRules = { + to: { + child: { + exports: true, + syncSibling: false + }, + parent: { + exports: false, + syncSibling: false + } + }, + from: { + child: { + exports: false, + syncSibling: false + }, + parent: { + exports: true, + syncSibling: false + } + }, + bind: { + child: { + exports: true, + syncSibling: false + }, + parent: { + exports: true, + syncSibling: true + } + }, + raw: { + child: { + exports: false, + syncSibling: false + }, + parent: { + exports: true, + syncSibling: false + } + } + }; + var bindingNames = []; + var special = { + vm: true, + on: true + }; + canReflect.eachKey(siblingBindingRules, function (value, key) { + bindingNames.push(key); + special[key] = true; + }); + function tokenize(source) { + var splitByColon = source.split(':'); + var result = { + tokens: [], + special: {} + }; + splitByColon.forEach(function (token) { + if (special[token]) { + result.special[token] = result.tokens.push(token) - 1; + } else { + result.tokens.push(token); + } + }); + return result; + } + var getChildBindingStr = function (tokens, favorViewModel) { + if (tokens.indexOf('vm') >= 0) { + return viewModelBindingStr; + } else if (tokens.indexOf('el') >= 0) { + return attributeBindingStr; + } else { + return favorViewModel ? viewModelBindingStr : viewModelOrAttributeBindingStr; + } + }; + function getSiblingBindingData(node, bindingSettings) { + var siblingBindingData, attributeName = encoder.decode(node.name), attributeValue = node.value || ''; + var result = tokenize(attributeName), dataBindingName, specialIndex; + bindingNames.forEach(function (name) { + if (result.special[name] !== undefined && result.special[name] > 0) { + dataBindingName = name; + specialIndex = result.special[name]; + return false; + } + }); + if (dataBindingName) { + var childEventName = getEventName(result); + var initializeValues = childEventName && dataBindingName !== 'bind' ? false : true; + siblingBindingData = { + parent: assign({ + source: scopeBindingStr, + name: result.special.raw ? '"' + attributeValue + '"' : attributeValue + }, siblingBindingRules[dataBindingName].parent), + child: assign({ + source: getChildBindingStr(result.tokens, bindingSettings && bindingSettings.favorViewModel), + name: result.tokens[specialIndex - 1], + event: childEventName + }, siblingBindingRules[dataBindingName].child), + bindingAttributeName: attributeName, + initializeValues: initializeValues + }; + if (attributeValue.trim().charAt(0) === '~') { + siblingBindingData.child.setCompute = true; + } + return siblingBindingData; + } + } + var makeDataBinding = function (node, bindingContext, bindingSettings) { + var siblingBindingData = getSiblingBindingData(node, bindingSettings); + if (!siblingBindingData) { + return; + } + var parentObservable = getObservableFrom[siblingBindingData.parent.source](siblingBindingData.parent, bindingContext, bindingSettings), childObservable = getObservableFrom[siblingBindingData.child.source](siblingBindingData.child, bindingContext, bindingSettings, parentObservable); + var childToParent = !!siblingBindingData.child.exports; + var parentToChild = !!siblingBindingData.parent.exports; + var bindingOptions = { + child: childObservable, + childToParent: childToParent, + cycles: childToParent === true && parentToChild === true ? 0 : 100, + onInitDoNotUpdateChild: bindingSettings.alreadyUpdatedChild || siblingBindingData.initializeValues === false, + onInitDoNotUpdateParent: siblingBindingData.initializeValues === false, + onInitSetUndefinedParentIfChildIsDefined: true, + parent: parentObservable, + parentToChild: parentToChild, + priority: bindingContext.parentNodeList ? bindingContext.parentNodeList.nesting + 1 : undefined, + queue: 'dom', + sticky: siblingBindingData.parent.syncSibling ? 'childSticksToParent' : undefined, + element: bindingContext.element + }; + var canBinding = new Bind(bindingOptions); + return { + siblingBindingData: siblingBindingData, + binding: canBinding + }; + }; + var cleanVMName = function (name, scope) { + return name.replace(/@/g, ''); + }; + var canStacheBindings = { + behaviors: behaviors, + getSiblingBindingData: getSiblingBindingData, + bindings: bindings, + getObservableFrom: getObservableFrom, + makeDataBinding: makeDataBinding + }; + canStacheBindings[canSymbol.for('can.callbackMap')] = bindings; + module.exports = canStacheBindings; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-parser@4.1.3#can-view-parser*/ +define('can-view-parser@4.1.3#can-view-parser', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-log/dev/dev', + 'can-attribute-encoder' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'), dev = require('can-log/dev/dev'), encoder = require('can-attribute-encoder'); + function each(items, callback) { + for (var i = 0; i < items.length; i++) { + callback(items[i], i); + } + } + function makeMap(str) { + var obj = {}, items = str.split(','); + each(items, function (name) { + obj[name] = true; + }); + return obj; + } + function handleIntermediate(intermediate, handler) { + for (var i = 0, len = intermediate.length; i < len; i++) { + var item = intermediate[i]; + handler[item.tokenType].apply(handler, item.args); + } + return intermediate; + } + var alphaNumeric = 'A-Za-z0-9', alphaNumericHU = '-:_' + alphaNumeric, magicStart = '{{', endTag = new RegExp('^<\\/([' + alphaNumericHU + ']+)[^>]*>'), magicMatch = new RegExp('\\{\\{(![\\s\\S]*?!|[\\s\\S]*?)\\}\\}\\}?', 'g'), space = /\s/, alphaRegex = new RegExp('[' + alphaNumeric + ']'), attributeRegexp = new RegExp('[' + alphaNumericHU + ']+s*=s*("[^"]*"|\'[^\']*\')'); + var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'); + var caseMattersElements = makeMap('altGlyph,altGlyphDef,altGlyphItem,animateColor,animateMotion,animateTransform,clipPath,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,foreignObject,glyphRef,linearGradient,radialGradient,textPath'); + var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); + var special = makeMap('script'); + var tokenTypes = 'start,end,close,attrStart,attrEnd,attrValue,chars,comment,special,done'.split(','); + var startOppositesMap = { + '{': '}', + '(': ')' + }; + var fn = function () { + }; + var HTMLParser = function (html, handler, returnIntermediate) { + if (typeof html === 'object') { + return handleIntermediate(html, handler); + } + var intermediate = []; + handler = handler || {}; + if (returnIntermediate) { + each(tokenTypes, function (name) { + var callback = handler[name] || fn; + handler[name] = function () { + if (callback.apply(this, arguments) !== false) { + var end = arguments.length; + if (arguments[end - 1] === undefined) { + end = arguments.length - 1; + } + intermediate.push({ + tokenType: name, + args: [].slice.call(arguments, 0, end) + }); + } + }; + }); + } + function parseStartTag(tag, tagName, rest, unary) { + tagName = caseMattersElements[tagName] ? tagName : tagName.toLowerCase(); + if (closeSelf[tagName] && stack.last() === tagName) { + parseEndTag('', tagName); + } + unary = empty[tagName] || !!unary; + handler.start(tagName, unary, lineNo); + if (!unary) { + stack.push(tagName); + } + HTMLParser.parseAttrs(rest, handler, lineNo); + handler.end(tagName, unary, lineNo); + if (tagName === 'html') { + skipChars = true; + } + } + function parseEndTag(tag, tagName) { + var pos; + if (!tagName) { + pos = 0; + } else { + tagName = caseMattersElements[tagName] ? tagName : tagName.toLowerCase(); + for (pos = stack.length - 1; pos >= 0; pos--) { + if (stack[pos] === tagName) { + break; + } + } + } + if (pos >= 0) { + for (var i = stack.length - 1; i >= pos; i--) { + if (handler.close) { + handler.close(stack[i], lineNo); + } + } + stack.length = pos; + if (tagName === 'body') { + skipChars = true; + } + } + } + function parseMustache(mustache, inside) { + if (handler.special) { + handler.special(inside, lineNo); + } + } + var callChars = function () { + if (charsText && !skipChars) { + if (handler.chars) { + handler.chars(charsText, lineNo); + } + } + skipChars = false; + charsText = ''; + }; + var index, chars, skipChars, match, lineNo, stack = [], last = html, charsText = ''; + stack.last = function () { + return this[this.length - 1]; + }; + while (html) { + chars = true; + if (!stack.last() || !special[stack.last()]) { + if (html.indexOf(''); + if (index >= 0) { + callChars(); + if (handler.comment) { + handler.comment(html.substring(4, index), lineNo); + } + html = html.substring(index + 3); + chars = false; + } + } else if (html.indexOf(']*>'), function (all, text) { + text = text.replace(/|/g, '$1$2'); + if (handler.chars) { + handler.chars(text, lineNo); + } + return ''; + }); + parseEndTag('', stack.last()); + } + if (html === last) { + throw new Error('Parse Error: ' + html); + } + last = html; + } + callChars(); + parseEndTag(); + handler.done(lineNo); + return intermediate; + }; + var callAttrStart = function (state, curIndex, handler, rest, lineNo) { + var attrName = rest.substring(typeof state.nameStart === 'number' ? state.nameStart : curIndex, curIndex), newAttrName = encoder.encode(attrName); + state.attrStart = newAttrName; + handler.attrStart(state.attrStart, lineNo); + state.inName = false; + }; + var callAttrEnd = function (state, curIndex, handler, rest, lineNo) { + if (state.valueStart !== undefined && state.valueStart < curIndex) { + var val = rest.substring(state.valueStart, curIndex); + handler.attrValue(val, lineNo); + } + handler.attrEnd(state.attrStart, lineNo); + state.attrStart = undefined; + state.valueStart = undefined; + state.inValue = false; + state.inName = false; + state.lookingForEq = false; + state.inQuote = false; + state.lookingForName = true; + }; + var findBreak = function (str, magicStart) { + var magicLength = magicStart.length; + for (var i = 0, len = str.length; i < len; i++) { + if (str[i] === '<' || str.substr(i, magicLength) === magicStart) { + return i; + } + } + return -1; + }; + HTMLParser.parseAttrs = function (rest, handler, lineNo) { + if (!rest) { + return; + } + var i = 0; + var curIndex; + var state = { + inName: false, + nameStart: undefined, + inValue: false, + valueStart: undefined, + inQuote: false, + attrStart: undefined, + lookingForName: true, + lookingForValue: false, + lookingForEq: false + }; + while (i < rest.length) { + curIndex = i; + var cur = rest.charAt(i); + i++; + if (magicStart === rest.substr(curIndex, magicStart.length)) { + if (state.inValue && curIndex > state.valueStart) { + handler.attrValue(rest.substring(state.valueStart, curIndex), lineNo); + } else if (state.inName && state.nameStart < curIndex) { + callAttrStart(state, curIndex, handler, rest, lineNo); + callAttrEnd(state, curIndex, handler, rest, lineNo); + } else if (state.lookingForValue) { + state.inValue = true; + } else if (state.lookingForEq && state.attrStart) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + magicMatch.lastIndex = curIndex; + var match = magicMatch.exec(rest); + if (match) { + handler.special(match[1], lineNo); + i = curIndex + match[0].length; + if (state.inValue) { + state.valueStart = curIndex + match[0].length; + } + } + } else if (state.inValue) { + if (state.inQuote) { + if (cur === state.inQuote) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + } else if (space.test(cur)) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + } else if (cur === '=' && (state.lookingForEq || state.lookingForName || state.inName)) { + if (!state.attrStart) { + callAttrStart(state, curIndex, handler, rest, lineNo); + } + state.lookingForValue = true; + state.lookingForEq = false; + state.lookingForName = false; + } else if (state.inName) { + var started = rest[state.nameStart], otherStart, otherOpposite; + if (startOppositesMap[started] === cur) { + otherStart = started === '{' ? '(' : '{'; + otherOpposite = startOppositesMap[otherStart]; + if (rest[curIndex + 1] === otherOpposite) { + callAttrStart(state, curIndex + 2, handler, rest, lineNo); + i++; + } else { + callAttrStart(state, curIndex + 1, handler, rest, lineNo); + } + state.lookingForEq = true; + } else if (space.test(cur) && started !== '{' && started !== '(') { + callAttrStart(state, curIndex, handler, rest, lineNo); + state.lookingForEq = true; + } + } else if (state.lookingForName) { + if (!space.test(cur)) { + if (state.attrStart) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + state.nameStart = curIndex; + state.inName = true; + } + } else if (state.lookingForValue) { + if (!space.test(cur)) { + state.lookingForValue = false; + state.inValue = true; + if (cur === '\'' || cur === '"') { + state.inQuote = cur; + state.valueStart = curIndex + 1; + } else { + state.valueStart = curIndex; + } + } else if (i === rest.length) { + callAttrEnd(state, curIndex, handler, rest, lineNo); + } + } + } + if (state.inName) { + callAttrStart(state, curIndex + 1, handler, rest, lineNo); + callAttrEnd(state, curIndex + 1, handler, rest, lineNo); + } else if (state.lookingForEq || state.lookingForValue || state.inValue) { + callAttrEnd(state, curIndex + 1, handler, rest, lineNo); + } + magicMatch.lastIndex = 0; + }; + HTMLParser.searchStartTag = function (html) { + var closingIndex = html.indexOf('>'); + var attributeRange = attributeRegexp.exec(html.substring(1)); + var afterAttributeOffset = 1; + while (attributeRange && closingIndex >= afterAttributeOffset + attributeRange.index) { + afterAttributeOffset += attributeRange.index + attributeRange[0].length; + while (closingIndex < afterAttributeOffset) { + closingIndex += html.substring(closingIndex + 1).indexOf('>') + 1; + } + attributeRange = attributeRegexp.exec(html.substring(afterAttributeOffset)); + } + if (closingIndex === -1 || !alphaRegex.test(html[1])) { + return null; + } + var tagName, tagContent, match, rest = '', unary = ''; + var startTag = html.substring(0, closingIndex + 1); + var isUnary = startTag[startTag.length - 2] === '/'; + var spaceIndex = startTag.search(space); + if (isUnary) { + unary = '/'; + tagContent = startTag.substring(1, startTag.length - 2).trim(); + } else { + tagContent = startTag.substring(1, startTag.length - 1).trim(); + } + if (spaceIndex === -1) { + tagName = tagContent; + } else { + spaceIndex--; + tagName = tagContent.substring(0, spaceIndex); + rest = tagContent.substring(spaceIndex); + } + match = [ + startTag, + tagName, + rest, + unary + ]; + return { + match: match, + html: html.substring(startTag.length) + }; + }; + module.exports = namespace.HTMLParser = HTMLParser; +}); +/*can-view-target@5.0.0#can-view-target*/ +define('can-view-target@5.0.0#can-view-target', [ + 'require', + 'exports', + 'module', + 'can-globals/document/document', + 'can-dom-mutate/node', + 'can-namespace', + 'can-globals/mutation-observer/mutation-observer' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getDocument = require('can-globals/document/document'); + var domMutate = require('can-dom-mutate/node'); + var namespace = require('can-namespace'); + var MUTATION_OBSERVER = require('can-globals/mutation-observer/mutation-observer'); + var processNodes = function (nodes, paths, location, document) { + var frag = document.createDocumentFragment(); + for (var i = 0, len = nodes.length; i < len; i++) { + var node = nodes[i]; + frag.appendChild(processNode(node, paths, location.concat(i), document)); + } + return frag; + }, keepsTextNodes = typeof document !== 'undefined' && function () { + var testFrag = document.createDocumentFragment(); + var div = document.createElement('div'); + div.appendChild(document.createTextNode('')); + div.appendChild(document.createTextNode('')); + testFrag.appendChild(div); + var cloned = testFrag.cloneNode(true); + return cloned.firstChild.childNodes.length === 2; + }(), clonesWork = typeof document !== 'undefined' && function () { + var el = document.createElement('a'); + el.innerHTML = ''; + var clone = el.cloneNode(true); + var works = clone.innerHTML === ''; + var MO, observer; + if (works) { + el = document.createDocumentFragment(); + el.appendChild(document.createTextNode('foo-bar')); + MO = MUTATION_OBSERVER(); + if (MO) { + observer = new MO(function () { + }); + observer.observe(document.documentElement, { + childList: true, + subtree: true + }); + clone = el.cloneNode(true); + observer.disconnect(); + } else { + clone = el.cloneNode(true); + } + return clone.childNodes.length === 1; + } + return works; + }(), namespacesWork = typeof document !== 'undefined' && !!document.createElementNS; + var cloneNode = clonesWork ? function (el) { + return el.cloneNode(true); + } : function (node) { + var document = node.ownerDocument; + var copy; + if (node.nodeType === 1) { + if (node.namespaceURI !== 'http://www.w3.org/1999/xhtml' && namespacesWork && document.createElementNS) { + copy = document.createElementNS(node.namespaceURI, node.nodeName); + } else { + copy = document.createElement(node.nodeName); + } + } else if (node.nodeType === 3) { + copy = document.createTextNode(node.nodeValue); + } else if (node.nodeType === 8) { + copy = document.createComment(node.nodeValue); + } else if (node.nodeType === 11) { + copy = document.createDocumentFragment(); + } + if (node.attributes) { + var attributes = node.attributes; + for (var i = 0; i < attributes.length; i++) { + var attribute = attributes[i]; + if (attribute && attribute.specified) { + if (attribute.namespaceURI) { + copy.setAttributeNS(attribute.namespaceURI, attribute.nodeName || attribute.name, attribute.nodeValue || attribute.value); + } else { + copy.setAttribute(attribute.nodeName || attribute.name, attribute.nodeValue || attribute.value); + } + } + } + } + if (node && node.firstChild) { + var child = node.firstChild; + while (child) { + copy.appendChild(cloneNode(child)); + child = child.nextSibling; + } + } + return copy; + }; + function processNode(node, paths, location, document) { + var callback, loc = location, nodeType = typeof node, el, p, i, len; + var getCallback = function () { + if (!callback) { + callback = { + path: location, + callbacks: [] + }; + paths.push(callback); + loc = []; + } + return callback; + }; + if (nodeType === 'object') { + if (node.tag) { + if (namespacesWork && node.namespace) { + el = document.createElementNS(node.namespace, node.tag); + } else { + el = document.createElement(node.tag); + } + if (node.attrs) { + for (var attrName in node.attrs) { + var value = node.attrs[attrName]; + if (typeof value === 'function') { + getCallback().callbacks.push({ callback: value }); + } else if (value !== null && typeof value === 'object' && value.namespaceURI) { + el.setAttributeNS(value.namespaceURI, attrName, value.value); + } else { + domMutate.setAttribute.call(el, attrName, value); + } + } + } + if (node.attributes) { + for (i = 0, len = node.attributes.length; i < len; i++) { + getCallback().callbacks.push({ callback: node.attributes[i] }); + } + } + if (node.children && node.children.length) { + if (callback) { + p = callback.paths = []; + } else { + p = paths; + } + el.appendChild(processNodes(node.children, p, loc, document)); + } + } else if (node.comment) { + el = document.createComment(node.comment); + if (node.callbacks) { + for (i = 0, len = node.callbacks.length; i < len; i++) { + getCallback().callbacks.push({ callback: node.callbacks[i] }); + } + } + } + } else if (nodeType === 'string') { + el = document.createTextNode(node); + } else if (nodeType === 'function') { + if (keepsTextNodes) { + el = document.createTextNode(''); + getCallback().callbacks.push({ callback: node }); + } else { + el = document.createComment('~'); + getCallback().callbacks.push({ + callback: function () { + var el = document.createTextNode(''); + domMutate.replaceChild.call(this.parentNode, el, this); + return node.apply(el, arguments); + } + }); + } + } + return el; + } + function getCallbacks(el, pathData, elementCallbacks) { + var path = pathData.path, callbacks = pathData.callbacks, paths = pathData.paths, child = el, pathLength = path ? path.length : 0, pathsLength = paths ? paths.length : 0; + for (var i = 0; i < pathLength; i++) { + child = child.childNodes.item(path[i]); + } + for (i = 0; i < pathsLength; i++) { + getCallbacks(child, paths[i], elementCallbacks); + } + elementCallbacks.push({ + element: child, + callbacks: callbacks + }); + } + function hydrateCallbacks(callbacks, args) { + var len = callbacks.length, callbacksLength, callbackElement, callbackData; + for (var i = 0; i < len; i++) { + callbackData = callbacks[i]; + callbacksLength = callbackData.callbacks.length; + callbackElement = callbackData.element; + for (var c = 0; c < callbacksLength; c++) { + callbackData.callbacks[c].callback.apply(callbackElement, args); + } + } + } + function makeTarget(nodes, doc) { + var paths = []; + var frag = processNodes(nodes, paths, [], doc || getDocument()); + return { + paths: paths, + clone: frag, + hydrate: function () { + var cloned = cloneNode(this.clone); + var args = []; + for (var a = 0, ref = args.length = arguments.length; a < ref; a++) { + args[a] = arguments[a]; + } + var callbacks = []; + for (var i = 0; i < paths.length; i++) { + getCallbacks(cloned, paths[i], callbacks); + } + hydrateCallbacks(callbacks, args); + return cloned; + } + }; + } + makeTarget.keepsTextNodes = keepsTextNodes; + makeTarget.cloneNode = cloneNode; + namespace.view = namespace.view || {}; + module.exports = namespace.view.target = makeTarget; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache@5.1.1#src/html_section*/ +define('can-stache@5.1.1#src/html_section', [ + 'require', + 'exports', + 'module', + 'can-view-target', + './utils', + 'can-globals/document/document', + 'can-assign' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var target = require('can-view-target'); + var utils = require('./utils'); + var getDocument = require('can-globals/document/document'); + var assign = require('can-assign'); + var last = utils.last; + var decodeHTML = typeof document !== 'undefined' && function () { + var el = getDocument().createElement('div'); + return function (html) { + if (html.indexOf('&') === -1) { + return html.replace(/\r\n/g, '\n'); + } + el.innerHTML = html; + return el.childNodes.length === 0 ? '' : el.childNodes.item(0).nodeValue; + }; + }(); + var HTMLSectionBuilder = function (filename) { + if (filename) { + this.filename = filename; + } + this.stack = [new HTMLSection()]; + }; + assign(HTMLSectionBuilder.prototype, utils.mixins); + assign(HTMLSectionBuilder.prototype, { + startSubSection: function (process) { + var newSection = new HTMLSection(process); + this.stack.push(newSection); + return newSection; + }, + endSubSectionAndReturnRenderer: function () { + if (this.last().isEmpty()) { + this.stack.pop(); + return null; + } else { + var htmlSection = this.endSection(); + return utils.makeView(htmlSection.compiled.hydrate.bind(htmlSection.compiled)); + } + }, + startSection: function (process, commentName) { + var newSection = new HTMLSection(process); + this.last().add({ + comment: commentName || '#section', + callbacks: [newSection.targetCallback] + }); + this.last().add({ comment: 'can-end-placeholder' }); + this.stack.push(newSection); + }, + endSection: function () { + this.last().compile(); + return this.stack.pop(); + }, + inverse: function () { + this.last().inverse(); + }, + compile: function () { + var compiled = this.stack.pop().compile(); + return utils.makeView(compiled.hydrate.bind(compiled)); + }, + push: function (chars) { + this.last().push(chars); + }, + pop: function () { + return this.last().pop(); + }, + removeCurrentNode: function () { + this.last().removeCurrentNode(); + } + }); + var HTMLSection = function (process) { + this.data = 'targetData'; + this.targetData = []; + this.targetStack = []; + var self = this; + this.targetCallback = function (scope) { + process.call(this, scope, self.compiled.hydrate.bind(self.compiled), self.inverseCompiled && self.inverseCompiled.hydrate.bind(self.inverseCompiled)); + }; + }; + assign(HTMLSection.prototype, { + inverse: function () { + this.inverseData = []; + this.data = 'inverseData'; + }, + push: function (data) { + this.add(data); + this.targetStack.push(data); + }, + pop: function () { + return this.targetStack.pop(); + }, + add: function (data) { + if (typeof data === 'string') { + data = decodeHTML(data); + } + if (this.targetStack.length) { + last(this.targetStack).children.push(data); + } else { + this[this.data].push(data); + } + }, + compile: function () { + this.compiled = target(this.targetData, getDocument()); + if (this.inverseData) { + this.inverseCompiled = target(this.inverseData, getDocument()); + delete this.inverseData; + } + this.targetStack = this.targetData = null; + return this.compiled; + }, + removeCurrentNode: function () { + var children = this.children(); + return children.pop(); + }, + children: function () { + if (this.targetStack.length) { + return last(this.targetStack).children; + } else { + return this[this.data]; + } + }, + isEmpty: function () { + return !this.targetData.length; + } + }); + HTMLSectionBuilder.HTMLSection = HTMLSection; + module.exports = HTMLSectionBuilder; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-live@5.0.4#lib/helpers*/ +define('can-view-live@5.0.4#lib/helpers', [ + 'require', + 'exports', + 'module', + 'can-dom-mutate/node', + 'can-dom-mutate', + 'can-symbol', + 'can-reflect', + 'can-reflect-dependencies', + 'can-view-parser', + 'can-log/dev/dev', + 'can-dom-mutate/-is-connected' +], function (require, exports, module) { + var domMutateNode = require('can-dom-mutate/node'); + var domMutate = require('can-dom-mutate'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var canReflectDeps = require('can-reflect-dependencies'); + var parser = require('can-view-parser'); + var canDev = require('can-log/dev/dev'); + var isConnected = require('can-dom-mutate/-is-connected'); + var setElementSymbol = canSymbol.for('can.setElement'); + var elementSymbol = canSymbol.for('can.element'); + function ListenUntilRemovedAndInitialize(observable, handler, placeholder, queueName, handlerName) { + this.observable = observable; + this.handler = handler; + this.placeholder = placeholder; + this.queueName = queueName; + this.handler[elementSymbol] = placeholder; + if (observable[setElementSymbol]) { + observable[setElementSymbol](placeholder); + } else { + console.warn('no can.setElement symbol on observable', observable); + } + this.setup(); + } + ListenUntilRemovedAndInitialize.prototype.setup = function () { + if (this.setupNodeReinserted) { + if (!isConnected.isConnected(this.placeholder)) { + return; + } + this.setupNodeReinserted(); + } + this.teardownNodeRemoved = domMutate.onNodeRemoved(this.placeholder, this.teardown.bind(this)); + canReflect.onValue(this.observable, this.handler, this.queueName); + this.handler(canReflect.getValue(this.observable)); + }; + ListenUntilRemovedAndInitialize.prototype.teardown = function () { + if (isConnected.isConnected(this.placeholder)) { + return; + } + this.teardownNodeRemoved(); + this.setupNodeReinserted = domMutate.onNodeInserted(this.placeholder, this.setup.bind(this)); + canReflect.offValue(this.observable, this.handler, this.queueName); + }; + module.exports = { + range: { + create: function (el, rangeName) { + var start, end, next; + if (el.nodeType === Node.COMMENT_NODE) { + start = el; + next = el.nextSibling; + if (next && next.nodeType === Node.COMMENT_NODE && next.nodeValue === 'can-end-placeholder') { + end = next; + end.nodeValue = '/' + (start.nodeValue = rangeName); + } else { + canDev.warn('can-view-live: creating an end comment for ', rangeName, el); + } + } else { + canDev.warn('can-view-live: forcing a comment range for ', rangeName, el); + start = el.ownerDocument.createComment(rangeName); + el.parentNode.replaceChild(start, el); + } + if (!end) { + end = el.ownerDocument.createComment('/' + rangeName); + start.parentNode.insertBefore(end, start.nextSibling); + } + return { + start: start, + end: end + }; + }, + remove: function (range) { + var parentNode = range.start.parentNode, cur = range.end.previousSibling, remove; + while (cur && cur !== range.start) { + remove = cur; + cur = cur.previousSibling; + domMutateNode.removeChild.call(parentNode, remove); + } + domMutate.flushRecords(); + }, + update: function (range, frag) { + var parentNode = range.start.parentNode; + if (parentNode) { + domMutateNode.insertBefore.call(parentNode, frag, range.end); + domMutate.flushRecords(); + } + } + }, + ListenUntilRemovedAndInitialize: ListenUntilRemovedAndInitialize, + getAttributeParts: function (newVal) { + var attrs = {}, attr; + parser.parseAttrs(newVal, { + attrStart: function (name) { + attrs[name] = ''; + attr = name; + }, + attrValue: function (value) { + attrs[attr] += value; + }, + attrEnd: function () { + } + }); + return attrs; + }, + addTextNodeIfNoChildren: function (frag) { + if (!frag.firstChild) { + frag.appendChild(frag.ownerDocument.createTextNode('')); + } + }, + makeString: function (txt) { + return txt == null ? '' : '' + txt; + } + }; +}); +/*can-view-live@5.0.4#lib/attr*/ +define('can-view-live@5.0.4#lib/attr', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-attribute-observable/behaviors', + './helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var attr = require('can-attribute-observable/behaviors'); + var helpers = require('./helpers'); + module.exports = function (el, attributeName, compute) { + var handlerName = ''; + new helpers.ListenUntilRemovedAndInitialize(compute, function liveUpdateAttr(newVal) { + attr.set(el, attributeName, newVal); + }, el, 'dom', handlerName); + }; +}); +/*can-view-live@5.0.4#lib/attrs*/ +define('can-view-live@5.0.4#lib/attrs', [ + 'require', + 'exports', + 'module', + 'can-view-callbacks', + 'can-dom-mutate/node', + 'can-reflect', + './helpers' +], function (require, exports, module) { + 'use strict'; + var viewCallbacks = require('can-view-callbacks'); + var domMutateNode = require('can-dom-mutate/node'); + var canReflect = require('can-reflect'); + var helpers = require('./helpers'); + module.exports = function (el, compute, scope, options) { + var handlerName = ''; + if (!canReflect.isObservableLike(compute)) { + var attrs = helpers.getAttributeParts(compute); + for (var name in attrs) { + domMutateNode.setAttribute.call(el, name, attrs[name]); + } + return; + } + var oldAttrs = {}; + new helpers.ListenUntilRemovedAndInitialize(compute, function canViewLive_updateAttributes(newVal) { + var newAttrs = helpers.getAttributeParts(newVal), name; + for (name in newAttrs) { + var newValue = newAttrs[name], oldValue = oldAttrs[name]; + if (newValue !== oldValue) { + domMutateNode.setAttribute.call(el, name, newValue); + var callback = viewCallbacks.attr(name); + if (callback) { + callback(el, { + attributeName: name, + scope: scope, + options: options + }); + } + } + delete oldAttrs[name]; + } + for (name in oldAttrs) { + domMutateNode.removeAttribute.call(el, name); + } + oldAttrs = newAttrs; + }, el, 'dom', handlerName); + }; +}); +/*can-view-live@5.0.4#lib/html*/ +define('can-view-live@5.0.4#lib/html', [ + 'require', + 'exports', + 'module', + 'can-fragment', + 'can-reflect', + 'can-symbol', + './helpers', + 'can-globals/document/document' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var makeFragment = require('can-fragment'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var helpers = require('./helpers'); + var getDocument = require('can-globals/document/document'); + var viewInsertSymbol = canSymbol.for('can.viewInsert'); + function makeCommentFragment(comment) { + var doc = getDocument(); + return makeFragment([ + doc.createComment(comment), + doc.createComment('can-end-placeholder') + ]); + } + module.exports = function (el, compute, viewInsertSymbolOptions) { + var observableName = ''; + var updateRange = helpers.range.update; + if (el.nodeType !== Node.COMMENT_NODE) { + var commentFrag = makeCommentFragment(observableName); + var startCommentNode = commentFrag.firstChild; + el.parentNode.replaceChild(commentFrag, el); + el = startCommentNode; + } + var range = helpers.range.create(el, observableName); + var useQueue = false; + new helpers.ListenUntilRemovedAndInitialize(compute, function canViewLive_updateHTML(val) { + if (val && typeof val[viewInsertSymbol] === 'function') { + val = val[viewInsertSymbol](viewInsertSymbolOptions); + } + var isFunction = typeof val === 'function'; + var frag = isFunction ? makeCommentFragment(observableName) : makeFragment(val); + if (isFunction) { + val(frag.firstChild); + } + if (useQueue === true) { + helpers.range.remove(range); + updateRange(range, frag); + } else { + helpers.range.update(range, frag); + useQueue = true; + } + }, range.start, 'dom', 'live.html replace::' + observableName); + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-diff@1.5.0#patcher/patcher*/ +define('can-diff@1.5.0#patcher/patcher', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-key-tree', + 'can-symbol', + '../list/list', + 'can-queues', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var KeyTree = require('can-key-tree'); + var canSymbol = require('can-symbol'); + var diff = require('../list/list'); + var queues = require('can-queues'); + var canSymbol = require('can-symbol'); + var onValueSymbol = canSymbol.for('can.onValue'), offValueSymbol = canSymbol.for('can.offValue'); + var onPatchesSymbol = canSymbol.for('can.onPatches'); + var offPatchesSymbol = canSymbol.for('can.offPatches'); + var Patcher = function (observableOrList, priority) { + this.handlers = new KeyTree([ + Object, + Array + ], { + onFirst: this.setup.bind(this), + onEmpty: this.teardown.bind(this) + }); + this.observableOrList = observableOrList; + this.isObservableValue = canReflect.isValueLike(this.observableOrList) || canReflect.isObservableLike(this.observableOrList); + if (this.isObservableValue) { + this.priority = canReflect.getPriority(observableOrList); + } else { + this.priority = priority || 0; + } + this.onList = this.onList.bind(this); + this.onPatchesNotify = this.onPatchesNotify.bind(this); + this.onPatchesDerive = this.onPatchesDerive.bind(this); + this.patches = []; + }; + Patcher.prototype = { + constructor: Patcher, + setup: function () { + if (this.observableOrList[onValueSymbol]) { + canReflect.onValue(this.observableOrList, this.onList, 'notify'); + this.setupList(canReflect.getValue(this.observableOrList)); + } else { + this.setupList(this.observableOrList); + } + }, + teardown: function () { + if (this.observableOrList[offValueSymbol]) { + canReflect.offValue(this.observableOrList, this.onList, 'notify'); + } + if (this.currentList && this.currentList[offPatchesSymbol]) { + this.currentList[offPatchesSymbol](this.onPatchesNotify, 'notify'); + } + }, + setupList: function (list) { + this.currentList = list; + if (list && list[onPatchesSymbol]) { + list[onPatchesSymbol](this.onPatchesNotify, 'notify'); + } + }, + onList: function onList(newList) { + var current = this.currentList || []; + newList = newList || []; + if (current[offPatchesSymbol]) { + current[offPatchesSymbol](this.onPatchesNotify, 'notify'); + } + var patches = diff(current, newList); + this.currentList = newList; + this.onPatchesNotify(patches); + if (newList[onPatchesSymbol]) { + newList[onPatchesSymbol](this.onPatchesNotify, 'notify'); + } + }, + onPatchesNotify: function onPatchesNotify(patches) { + this.patches.push.apply(this.patches, patches); + queues.deriveQueue.enqueue(this.onPatchesDerive, this, [], { priority: this.priority }); + }, + onPatchesDerive: function onPatchesDerive() { + var patches = this.patches; + this.patches = []; + queues.enqueueByQueue(this.handlers.getNode([]), this.currentList, [ + patches, + this.currentList + ], null, [ + 'Apply patches', + patches + ]); + } + }; + canReflect.assignSymbols(Patcher.prototype, { + 'can.onPatches': function (handler, queue) { + this.handlers.add([ + queue || 'mutate', + handler + ]); + }, + 'can.offPatches': function (handler, queue) { + this.handlers.delete([ + queue || 'mutate', + handler + ]); + } + }); + module.exports = Patcher; +}); +/*can-diff@1.5.0#patch-sort/patch-sort*/ +define('can-diff@1.5.0#patch-sort/patch-sort', function (require, exports, module) { + module.exports = function (patches) { + var splitPatches = []; + patches.forEach(function (patch) { + if (patch.type === 'move') { + splitPatches.push({ + patch: patch, + kind: 'move' + }); + } else { + if (patch.deleteCount) { + splitPatches.push({ + type: 'splice', + index: patch.index, + deleteCount: patch.deleteCount, + insert: [] + }); + } + if (patch.insert && patch.insert.length) { + splitPatches.push({ + type: 'splice', + index: patch.index, + deleteCount: 0, + insert: patch.insert + }); + } + } + }); + if (patches.length !== 2) { + return patches; + } + var first = splitPatches[0], second = splitPatches[1]; + if (first.insert && first.insert.length && second.deleteCount) { + var insert = first, remove = second; + if (insert.index < remove.index) { + remove.index = remove.index - insert.insert.length; + } else if (insert.index > remove.index) { + insert.index = insert.index - remove.deleteCount; + } else { + throw 'indexes the same!'; + } + return [ + remove, + insert + ]; + } + return patches; + }; +}); +/*can-view-live@5.0.4#lib/set-observable*/ +define('can-view-live@5.0.4#lib/set-observable', [ + 'require', + 'exports', + 'module', + 'can-simple-observable', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var SimpleObservable = require('can-simple-observable'); + var canReflect = require('can-reflect'); + function SetObservable(initialValue, setter) { + this.setter = setter; + SimpleObservable.call(this, initialValue); + } + SetObservable.prototype = Object.create(SimpleObservable.prototype); + SetObservable.prototype.constructor = SetObservable; + SetObservable.prototype.set = function (newVal) { + this.setter(newVal); + }; + canReflect.assignSymbols(SetObservable.prototype, { 'can.setValue': SetObservable.prototype.set }); + module.exports = SetObservable; +}); +/*can-view-live@5.0.4#lib/list*/ +define('can-view-live@5.0.4#lib/list', [ + 'require', + 'exports', + 'module', + 'can-fragment', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-reflect', + 'can-queues', + 'can-symbol', + 'can-reflect-dependencies', + 'can-simple-observable', + 'can-diff/patcher/patcher', + 'can-diff/patch-sort/patch-sort', + './set-observable', + './helpers' +], function (require, exports, module) { + 'use strict'; + var frag = require('can-fragment'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var canSymbol = require('can-symbol'); + var canReflectDeps = require('can-reflect-dependencies'); + var SimpleObservable = require('can-simple-observable'); + var Patcher = require('can-diff/patcher/patcher'); + var patchSort = require('can-diff/patch-sort/patch-sort'); + var SetObservable = require('./set-observable'); + var helpers = require('./helpers'); + var splice = [].splice; + var renderAndAddRangeNode = function (render, context, args, document) { + var itemHTML = render.apply(context, args.concat()), itemFrag = frag(itemHTML); + var rangeNode = document.createTextNode(''); + itemFrag.appendChild(rangeNode); + return itemFrag; + }; + function getFrag(first, last) { + var frag = first.ownerDocument.createDocumentFragment(); + var current, lastInserted; + while (last !== first) { + current = last; + last = current.previousSibling; + frag.insertBefore(current, lastInserted); + lastInserted = current; + } + frag.insertBefore(last, lastInserted); + return frag; + } + var onPatchesSymbol = canSymbol.for('can.onPatches'); + var offPatchesSymbol = canSymbol.for('can.offPatches'); + function ListDOMPatcher(el, compute, render, context, falseyRender) { + this.patcher = new Patcher(compute); + var observableName = canReflect.getName(compute); + this.value = compute; + this.render = render; + this.context = context; + this.falseyRender = falseyRender; + this.range = helpers.range.create(el, observableName); + this.indexMap = []; + this.itemEndNode = []; + this.domQueue = []; + this.isValueLike = canReflect.isValueLike(this.value); + this.isObservableLike = canReflect.isObservableLike(this.value); + this.onPatches = this.onPatches.bind(this); + this.processDomQueue = this.processDomQueue.bind(this); + this.teardownValueBinding = this.teardownValueBinding.bind(this); + this.meta = { + reasonLog: 'live.html add::' + observableName, + element: this.range.start + }; + this.setupValueBinding(); + } + var onPatchesSymbol = canSymbol.for('can.onPatches'); + var offPatchesSymbol = canSymbol.for('can.offPatches'); + ListDOMPatcher.prototype = { + setupValueBinding: function () { + this.teardownNodeRemoved = domMutate.onNodeRemoved(this.range.start, this.teardownValueBinding); + this.patcher[onPatchesSymbol](this.onPatches, 'notify'); + if (this.patcher.currentList && this.patcher.currentList.length) { + this.add(this.patcher.currentList, 0); + } else { + this.addFalseyIfEmpty(); + } + }, + teardownValueBinding: function () { + this.exit = true; + this.teardownNodeRemoved(); + this.patcher[offPatchesSymbol](this.onPatches, 'notify'); + }, + onPatches: function ListDOMPatcher_onPatches(patches) { + if (this.exit) { + return; + } + var sortedPatches = []; + patches.forEach(function (patch) { + sortedPatches.push.apply(sortedPatches, patchSort([patch])); + }); + for (var i = 0, patchLen = sortedPatches.length; i < patchLen; i++) { + var patch = sortedPatches[i]; + if (patch.type === 'move') { + this.addToDomQueue(this.move, [ + patch.toIndex, + patch.fromIndex + ]); + } else { + if (patch.deleteCount) { + this.addToDomQueue(this.remove, [ + { length: patch.deleteCount }, + patch.index + ]); + } + if (patch.insert && patch.insert.length) { + this.addToDomQueue(this.add, [ + patch.insert, + patch.index + ]); + } + } + } + }, + addToDomQueue: function (fn, args) { + this.domQueue.push({ + fn: fn, + args: args + }); + queues.domQueue.enqueue(this.processDomQueue, this, [this.domQueue], this.meta); + }, + processDomQueue: function () { + this.domQueue.forEach(function (queueItem) { + var fn = queueItem.fn; + var args = queueItem.args; + fn.apply(this, args); + }.bind(this)); + this.domQueue = []; + }, + add: function (items, index) { + var ownerDocument = this.range.start.ownerDocument, frag = ownerDocument.createDocumentFragment(), newEndNodes = [], newIndicies = [], render = this.render, context = this.context; + items.forEach(function (item, key) { + var itemIndex = new SimpleObservable(key + index), itemCompute = new SetObservable(item, function (newVal) { + canReflect.setKeyValue(this.patcher.currentList, itemIndex.get(), newVal); + }.bind(this)), itemFrag = renderAndAddRangeNode(render, context, [ + itemCompute, + itemIndex + ], ownerDocument); + newEndNodes.push(itemFrag.lastChild); + frag.appendChild(itemFrag); + newIndicies.push(itemIndex); + }, this); + if (!this.indexMap.length) { + helpers.range.remove(this.range); + this.itemEndNode = []; + } + var placeholder, endNodesLength = this.itemEndNode.length; + if (index === endNodesLength) { + placeholder = this.range.end; + } else if (index === 0) { + placeholder = this.range.start.nextSibling; + } else if (index < endNodesLength) { + placeholder = this.itemEndNode[index - 1].nextSibling; + } else { + throw new Error('Unable to place item'); + } + domMutateNode.insertBefore.call(placeholder.parentNode, frag, placeholder); + splice.apply(this.itemEndNode, [ + index, + 0 + ].concat(newEndNodes)); + splice.apply(this.indexMap, [ + index, + 0 + ].concat(newIndicies)); + for (var i = index + newIndicies.length, len = this.indexMap.length; i < len; i++) { + this.indexMap[i].set(i); + } + }, + remove: function (items, index) { + if (index < 0) { + index = this.indexMap.length + index; + } + var removeStart; + var removeEnd; + var removeCount = items.length; + var endIndex = index + removeCount - 1; + if (index === 0) { + removeStart = this.range.start; + } else { + removeStart = this.itemEndNode[index - 1]; + } + removeEnd = this.itemEndNode[endIndex].nextSibling; + this.itemEndNode.splice(index, items.length); + if (removeStart && removeEnd) { + helpers.range.remove({ + start: removeStart, + end: removeEnd + }); + } + var indexMap = this.indexMap; + indexMap.splice(index, items.length); + for (var i = index, len = indexMap.length; i < len; i++) { + indexMap[i].set(i); + } + if (!this.exit) { + this.addFalseyIfEmpty(); + } else { + } + }, + addFalseyIfEmpty: function () { + if (this.falseyRender && this.indexMap.length === 0) { + var falseyFrag = renderAndAddRangeNode(this.falseyRender, this.currentList, [this.currentList], this.range.start.ownerDocument); + helpers.range.update(this.range, falseyFrag); + } + }, + move: function move(newIndex, currentIndex) { + var currentFirstNode, currentEndNode = this.itemEndNode[currentIndex]; + if (currentIndex > 0) { + currentFirstNode = this.itemEndNode[currentIndex - 1].nextSibling; + } else { + currentFirstNode = this.range.start.nextSibling; + } + var newIndexFirstNode; + if (currentIndex < newIndex) { + newIndexFirstNode = this.itemEndNode[newIndex].nextSibling; + } else { + if (newIndex > 0) { + newIndexFirstNode = this.itemEndNode[newIndex - 1].nextSibling; + } else { + newIndexFirstNode = this.range.start.nextSibling; + } + } + var frag = getFrag(currentFirstNode, currentEndNode); + newIndexFirstNode.parentNode.insertBefore(frag, newIndexFirstNode); + this.itemEndNode.splice(currentIndex, 1); + this.itemEndNode.splice(newIndex, 0, currentEndNode); + newIndex = newIndex + 1; + currentIndex = currentIndex + 1; + var indexMap = this.indexMap; + newIndex = newIndex - 1; + currentIndex = currentIndex - 1; + var indexCompute = indexMap[currentIndex]; + [].splice.apply(indexMap, [ + currentIndex, + 1 + ]); + [].splice.apply(indexMap, [ + newIndex, + 0, + indexCompute + ]); + var i = Math.min(currentIndex, newIndex); + var len = indexMap.length; + for (i, len; i < len; i++) { + indexMap[i].set(i); + } + } + }; + module.exports = function (el, list, render, context, falseyRender) { + new ListDOMPatcher(el, list, render, context, falseyRender); + }; +}); +/*can-view-live@5.0.4#lib/text*/ +define('can-view-live@5.0.4#lib/text', [ + 'require', + 'exports', + 'module', + 'can-reflect', + './helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var helpers = require('./helpers'); + module.exports = function (el, compute) { + var handlerName = ''; + if (el.nodeType !== Node.TEXT_NODE) { + var textNode; + textNode = document.createTextNode(''); + el.parentNode.replaceChild(textNode, el); + el = textNode; + } + new helpers.ListenUntilRemovedAndInitialize(compute, function liveTextUpdateTextNode(newVal) { + el.nodeValue = helpers.makeString(newVal); + }, el, 'dom', handlerName); + }; +}); +/*can-view-live@5.0.4#can-view-live*/ +define('can-view-live@5.0.4#can-view-live', [ + 'require', + 'exports', + 'module', + './lib/attr', + './lib/attrs', + './lib/html', + './lib/list', + './lib/text' +], function (require, exports, module) { + 'use strict'; + var live = {}; + live.attr = require('./lib/attr'); + live.attrs = require('./lib/attrs'); + live.html = require('./lib/html'); + live.list = require('./lib/list'); + live.text = require('./lib/text'); + module.exports = live; +}); +/*can-stache@5.1.1#src/text_section*/ +define('can-stache@5.1.1#src/text_section', [ + 'require', + 'exports', + 'module', + 'can-view-live', + './utils', + 'can-dom-mutate/node', + 'can-assign', + 'can-reflect', + 'can-observation' +], function (require, exports, module) { + 'use strict'; + var live = require('can-view-live'); + var utils = require('./utils'); + var domMutate = require('can-dom-mutate/node'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var noop = function () { + }; + var TextSectionBuilder = function (filename) { + if (filename) { + this.filename = filename; + } + this.stack = [new TextSection()]; + }; + assign(TextSectionBuilder.prototype, utils.mixins); + assign(TextSectionBuilder.prototype, { + startSection: function (process) { + var subSection = new TextSection(); + this.last().add({ + process: process, + truthy: subSection + }); + this.stack.push(subSection); + }, + endSection: function () { + this.stack.pop(); + }, + inverse: function () { + this.stack.pop(); + var falseySection = new TextSection(); + this.last().last().falsey = falseySection; + this.stack.push(falseySection); + }, + compile: function (state) { + var renderer = this.stack[0].compile(); + return function (scope) { + function textSectionRender() { + return renderer(scope); + } + var observation = new Observation(textSectionRender, null, { isObservable: false }); + canReflect.onValue(observation, noop); + var value = canReflect.getValue(observation); + if (canReflect.valueHasDependencies(observation)) { + if (state.textContentOnly) { + live.text(this, observation); + } else if (state.attr) { + live.attr(this, state.attr, observation); + } else { + live.attrs(this, observation, scope); + } + canReflect.offValue(observation, noop); + } else { + if (state.textContentOnly) { + this.nodeValue = value; + } else if (state.attr) { + domMutate.setAttribute.call(this, state.attr, value); + } else { + live.attrs(this, value); + } + } + }; + } + }); + var passTruthyFalsey = function (process, truthy, falsey) { + return function (scope) { + return process.call(this, scope, truthy, falsey); + }; + }; + var TextSection = function () { + this.values = []; + }; + assign(TextSection.prototype, { + add: function (data) { + this.values.push(data); + }, + last: function () { + return this.values[this.values.length - 1]; + }, + compile: function () { + var values = this.values, len = values.length; + for (var i = 0; i < len; i++) { + var value = this.values[i]; + if (typeof value === 'object') { + values[i] = passTruthyFalsey(value.process, value.truthy && value.truthy.compile(), value.falsey && value.falsey.compile()); + } + } + return function (scope) { + var txt = '', value; + for (var i = 0; i < len; i++) { + value = values[i]; + txt += typeof value === 'string' ? value : value.call(this, scope); + } + return txt; + }; + } + }); + module.exports = TextSectionBuilder; +}); +/*can-stache@5.1.1#src/mustache_core*/ +define('can-stache@5.1.1#src/mustache_core', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-view-live/lib/helpers', + 'can-observation', + 'can-observation-recorder', + './utils', + './expression', + 'can-fragment', + 'can-dom-mutate', + 'can-symbol', + 'can-reflect', + 'can-log/dev/dev', + 'can-globals/document/document', + 'can-define-lazy-value' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var live = require('can-view-live'); + var liveHelpers = require('can-view-live/lib/helpers'); + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var utils = require('./utils'); + var expression = require('./expression'); + var frag = require('can-fragment'); + var domMutate = require('can-dom-mutate'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var dev = require('can-log/dev/dev'); + var getDocument = require('can-globals/document/document'); + var defineLazyValue = require('can-define-lazy-value'); + var toDOMSymbol = canSymbol.for('can.toDOM'); + function HelperOptions(scope, exprData, stringOnly) { + this.metadata = { rendered: false }; + this.stringOnly = stringOnly; + this.scope = scope; + this.exprData = exprData; + } + defineLazyValue(HelperOptions.prototype, 'context', function () { + return this.scope.peek('this'); + }); + var mustacheLineBreakRegExp = /(?:(^|\r?\n)(\s*)(\{\{([\s\S]*)\}\}\}?)([^\S\n\r]*)($|\r?\n))|(\{\{([\s\S]*)\}\}\}?)/g, mustacheWhitespaceRegExp = /\s*\{\{--\}\}\s*|\s*(\{\{\{?)-|-(\}\}\}?)\s*/g, k = function () { + }; + var viewInsertSymbol = canSymbol.for('can.viewInsert'); + function valueShouldBeInsertedAsHTML(value) { + return value !== null && typeof value === 'object' && (typeof value[toDOMSymbol] === 'function' || typeof value[viewInsertSymbol] === 'function' || typeof value.nodeType === 'number'); + } + var core = { + expression: expression, + makeEvaluator: function (scope, mode, exprData, truthyRenderer, falseyRenderer, stringOnly) { + if (mode === '^') { + var temp = truthyRenderer; + truthyRenderer = falseyRenderer; + falseyRenderer = temp; + } + var value, helperOptions = new HelperOptions(scope, exprData, stringOnly); + utils.createRenderers(helperOptions, scope, truthyRenderer, falseyRenderer, stringOnly); + if (exprData instanceof expression.Call) { + value = exprData.value(scope, helperOptions); + } else if (exprData instanceof expression.Bracket) { + value = exprData.value(scope); + } else if (exprData instanceof expression.Lookup) { + value = exprData.value(scope); + } else if (exprData instanceof expression.Literal) { + value = exprData.value.bind(exprData); + } else if (exprData instanceof expression.Helper && exprData.methodExpr instanceof expression.Bracket) { + value = exprData.methodExpr.value(scope, helperOptions); + } else { + value = exprData.value(scope, helperOptions); + if (typeof value === 'function') { + return value; + } + } + if (!mode || helperOptions.metadata.rendered) { + return value; + } else if (mode === '#' || mode === '^') { + return function () { + var finalValue = canReflect.getValue(value); + var result; + if (helperOptions.metadata.rendered) { + result = finalValue; + } else if (typeof finalValue !== 'string' && canReflect.isListLike(finalValue)) { + var isObserveList = canReflect.isObservableLike(finalValue) && canReflect.isListLike(finalValue); + if (canReflect.getKeyValue(finalValue, 'length')) { + if (stringOnly) { + result = utils.getItemsStringContent(finalValue, isObserveList, helperOptions); + } else { + result = frag(utils.getItemsFragContent(finalValue, helperOptions, scope)); + } + } else { + result = helperOptions.inverse(scope); + } + } else { + result = finalValue ? helperOptions.fn(finalValue || scope) : helperOptions.inverse(scope); + } + helperOptions.metadata.rendered = false; + return result; + }; + } else { + } + }, + makeLiveBindingPartialRenderer: function (expressionString, state) { + expressionString = expressionString.trim(); + var exprData, partialName = expressionString.split(/\s+/).shift(); + if (partialName !== expressionString) { + exprData = core.expression.parse(expressionString); + } + return function (scope) { + var partialFrag = new Observation(function () { + var localPartialName = partialName; + var partialScope = scope; + if (exprData && exprData.argExprs.length === 1) { + var newContext = canReflect.getValue(exprData.argExprs[0].value(scope)); + if (typeof newContext === 'undefined') { + } else { + partialScope = scope.add(newContext); + } + } + var partial = canReflect.getKeyValue(partialScope.templateContext.partials, localPartialName); + var renderer; + if (partial) { + renderer = function () { + return partial.render ? partial.render(partialScope) : partial(partialScope); + }; + } else { + var scopePartialName = partialScope.read(localPartialName, { isArgument: true }).value; + if (scopePartialName === null || !scopePartialName && localPartialName[0] === '*') { + return frag(''); + } + if (scopePartialName) { + localPartialName = scopePartialName; + } + renderer = function () { + if (typeof localPartialName === 'function') { + return localPartialName(partialScope, {}); + } else { + var domRenderer = core.getTemplateById(localPartialName); + return domRenderer ? domRenderer(partialScope, {}) : getDocument().createDocumentFragment(); + } + }; + } + var res = ObservationRecorder.ignore(renderer)(); + return frag(res); + }); + live.html(this, partialFrag); + }; + }, + makeStringBranchRenderer: function (mode, expressionString, state) { + var exprData = core.expression.parse(expressionString), fullExpression = mode + expressionString; + var branchRenderer = function branchRenderer(scope, truthyRenderer, falseyRenderer) { + var evaluator = scope.__cache[fullExpression]; + if (mode || !evaluator) { + evaluator = makeEvaluator(scope, mode, exprData, truthyRenderer, falseyRenderer, true); + if (!mode) { + scope.__cache[fullExpression] = evaluator; + } + } + var gotObservableValue = evaluator[canSymbol.for('can.onValue')], res; + if (gotObservableValue) { + res = canReflect.getValue(evaluator); + } else { + res = evaluator(); + } + if (res == null) { + return ''; + } + return res.nodeType === 11 ? res.textContent : '' + res; + }; + branchRenderer.exprData = exprData; + return branchRenderer; + }, + makeLiveBindingBranchRenderer: function (mode, expressionString, state) { + var exprData = core.expression.parse(expressionString); + var branchRenderer = function branchRenderer(scope, truthyRenderer, falseyRenderer) { + var stringOnly = state.tag; + var evaluator = makeEvaluator(scope, mode, exprData, truthyRenderer, falseyRenderer, stringOnly); + var gotObservableValue = evaluator[canSymbol.for('can.onValue')]; + var observable; + if (gotObservableValue) { + observable = evaluator; + } else { + observable = new Observation(evaluator, null, { isObservable: false }); + } + canReflect.onValue(observable, k); + var value = canReflect.getValue(observable); + if (typeof value === 'function' && !(exprData instanceof expression.Lookup)) { + ObservationRecorder.ignore(value)(this); + } else if (canReflect.valueHasDependencies(observable)) { + if (state.attr) { + live.attr(this, state.attr, observable); + } else if (state.tag) { + live.attrs(this, observable); + } else if (state.text && !valueShouldBeInsertedAsHTML(value)) { + live.text(this, observable); + } else { + live.html(this, observable); + } + } else { + if (state.attr) { + domMutate.setAttribute(this, state.attr, value); + } else if (state.tag) { + live.attrs(this, value); + } else if (state.text && !valueShouldBeInsertedAsHTML(value)) { + this.nodeValue = liveHelpers.makeString(value); + } else if (value != null) { + if (typeof value[viewInsertSymbol] === 'function') { + var insert = value[viewInsertSymbol]({}); + this.parentNode.replaceChild(insert, this); + } else { + this.parentNode.replaceChild(frag(value, this.ownerDocument), this); + } + } + } + canReflect.offValue(observable, k); + }; + branchRenderer.exprData = exprData; + return branchRenderer; + }, + splitModeFromExpression: function (expression, state) { + expression = expression.trim(); + var mode = expression.charAt(0); + if ('#/{&^>!<'.indexOf(mode) >= 0) { + expression = expression.substr(1).trim(); + } else { + mode = null; + } + if (mode === '{' && state.node) { + mode = null; + } + return { + mode: mode, + expression: expression + }; + }, + cleanLineEndings: function (template) { + return template.replace(mustacheLineBreakRegExp, function (whole, returnBefore, spaceBefore, special, expression, spaceAfter, returnAfter, spaceLessSpecial, spaceLessExpression, matchIndex) { + spaceAfter = spaceAfter || ''; + returnBefore = returnBefore || ''; + spaceBefore = spaceBefore || ''; + var modeAndExpression = splitModeFromExpression(expression || spaceLessExpression, {}); + if (spaceLessSpecial || '>{'.indexOf(modeAndExpression.mode) >= 0) { + return whole; + } else if ('^#!/'.indexOf(modeAndExpression.mode) >= 0) { + spaceBefore = returnBefore + spaceBefore && ' '; + return spaceBefore + special + (matchIndex !== 0 && returnAfter.length ? returnBefore + '\n' : ''); + } else { + return spaceBefore + special + spaceAfter + (spaceBefore.length || matchIndex !== 0 ? returnBefore + '\n' : ''); + } + }); + }, + cleanWhitespaceControl: function (template) { + return template.replace(mustacheWhitespaceRegExp, '$1$2'); + }, + getTemplateById: function () { + } + }; + var makeEvaluator = core.makeEvaluator, splitModeFromExpression = core.splitModeFromExpression; + module.exports = core; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-globals@1.2.2#base-url/base-url*/ +define('can-globals@1.2.2#base-url/base-url', [ + 'require', + 'exports', + 'module', + '../can-globals-instance', + '../global/global', + '../document/document' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var globals = require('../can-globals-instance'); + require('../global/global'); + require('../document/document'); + globals.define('base-url', function () { + var global = globals.getKeyValue('global'); + var domDocument = globals.getKeyValue('document'); + if (domDocument && 'baseURI' in domDocument) { + return domDocument.baseURI; + } else if (global.location) { + var href = global.location.href; + var lastSlash = href.lastIndexOf('/'); + return lastSlash !== -1 ? href.substr(0, lastSlash) : href; + } else if (typeof process !== 'undefined') { + return process.cwd(); + } + }); + module.exports = globals.makeExport('base-url'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-parse-uri@1.2.2#can-parse-uri*/ +define('can-parse-uri@1.2.2#can-parse-uri', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + module.exports = namespace.parseURI = function (url) { + var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); + return m ? { + href: m[0] || '', + protocol: m[1] || '', + authority: m[2] || '', + host: m[3] || '', + hostname: m[4] || '', + port: m[5] || '', + pathname: m[6] || '', + search: m[7] || '', + hash: m[8] || '' + } : null; + }; +}); +/*can-join-uris@1.2.0#can-join-uris*/ +define('can-join-uris@1.2.0#can-join-uris', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-parse-uri' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var parseURI = require('can-parse-uri'); + module.exports = namespace.joinURIs = function (base, href) { + function removeDotSegments(input) { + var output = []; + input.replace(/^(\.\.?(\/|$))+/, '').replace(/\/(\.(\/|$))+/g, '/').replace(/\/\.\.$/, '/../').replace(/\/?[^\/]*/g, function (p) { + if (p === '/..') { + output.pop(); + } else { + output.push(p); + } + }); + return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); + } + href = parseURI(href || ''); + base = parseURI(base || ''); + return !href || !base ? null : (href.protocol || base.protocol) + (href.protocol || href.authority ? href.authority : base.authority) + removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : href.pathname ? (base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname : base.pathname) + (href.protocol || href.authority || href.pathname ? href.search : href.search || base.search) + href.hash; + }; +}); +/*can-stache@5.1.1#helpers/-debugger*/ +define('can-stache@5.1.1#helpers/-debugger', [ + 'require', + 'exports', + 'module', + 'can-log' +], function (require, exports, module) { + 'use strict'; + var canLog = require('can-log'); + function noop() { + } + var resolveValue = noop; + var evaluateArgs = noop; + var __testing = {}; + function debuggerHelper(left, right) { + canLog.warn('Forgotten {{debugger}} helper'); + } + debuggerHelper.requiresOptionsArgument = true; + module.exports = { + helper: debuggerHelper, + evaluateArgs: evaluateArgs, + resolveValue: resolveValue, + __testing: __testing + }; +}); +/*can-stache@5.1.1#src/truthy-observable*/ +define('can-stache@5.1.1#src/truthy-observable', [ + 'require', + 'exports', + 'module', + 'can-observation', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var Observation = require('can-observation'); + var canReflect = require('can-reflect'); + module.exports = function (observable) { + return new Observation(function truthyObservation() { + var val = canReflect.getValue(observable); + return !!val; + }); + }; +}); +/*can-stache@5.1.1#helpers/converter*/ +define('can-stache@5.1.1#helpers/converter', [ + 'require', + 'exports', + 'module', + '../src/set-identifier', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var SetIdentifier = require('../src/set-identifier'); + var canReflect = require('can-reflect'); + function makeConverter(getterSetter) { + getterSetter = getterSetter || {}; + return function (newVal, source) { + var args = canReflect.toArray(arguments); + if (newVal instanceof SetIdentifier) { + return typeof getterSetter.set === 'function' ? getterSetter.set.apply(this, [newVal.value].concat(args.slice(1))) : source(newVal.value); + } else { + return typeof getterSetter.get === 'function' ? getterSetter.get.apply(this, args) : args[0]; + } + }; + } + module.exports = makeConverter; +}); +/*can-stache@5.1.1#helpers/-for-of*/ +define('can-stache@5.1.1#helpers/-for-of', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation', + 'can-view-live', + '../src/expression', + '../src/key-observable' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var live = require('can-view-live'); + var expression = require('../src/expression'); + var KeyObservable = require('../src/key-observable'); + var bindAndRead = function (value) { + if (value && canReflect.isValueLike(value)) { + Observation.temporarilyBind(value); + return canReflect.getValue(value); + } else { + return value; + } + }; + function forOfInteger(integer, variableName, options) { + var result = []; + for (var i = 0; i < integer; i++) { + var variableScope = {}; + if (variableName !== undefined) { + variableScope[variableName] = i; + } + result.push(options.fn(options.scope.add({ index: i }, { special: true }).addLetContext(variableScope))); + } + return options.stringOnly ? result.join('') : result; + } + function forOfObject(object, variableName, options) { + var result = []; + canReflect.each(object, function (val, key) { + var value = new KeyObservable(object, key.replace(/\./g, '\\.')); + var variableScope = {}; + if (variableName !== undefined) { + variableScope[variableName] = value; + } + result.push(options.fn(options.scope.add({ key: key }, { special: true }).addLetContext(variableScope))); + }); + return options.stringOnly ? result.join('') : result; + } + var forHelper = function (helperOptions) { + if (helperOptions.exprData.argExprs.length !== 1) { + throw new Error('for(of) broken syntax'); + } + var helperExpr = helperOptions.exprData.argExprs[0].expr; + var variableName, valueLookup, valueObservable; + if (helperExpr instanceof expression.Lookup) { + valueObservable = helperExpr.value(helperOptions.scope); + } else if (helperExpr instanceof expression.Helper) { + var inLookup = helperExpr.argExprs[0]; + if (inLookup.key !== 'of') { + throw new Error('for(of) broken syntax'); + } + variableName = helperExpr.methodExpr.key; + valueLookup = helperExpr.argExprs[1]; + valueObservable = valueLookup.value(helperOptions.scope); + } + var items = valueObservable; + var args = [].slice.call(arguments), options = args.pop(), resolved = bindAndRead(items); + if (resolved && resolved === Math.floor(resolved)) { + return forOfInteger(resolved, variableName, helperOptions); + } + if (resolved && !canReflect.isListLike(resolved)) { + return forOfObject(resolved, variableName, helperOptions); + } + if (options.stringOnly) { + var parts = []; + canReflect.eachIndex(resolved, function (value, index) { + var variableScope = {}; + if (variableName !== undefined) { + variableScope[variableName] = value; + } + parts.push(helperOptions.fn(options.scope.add({ index: index }, { special: true }).addLetContext(variableScope))); + }); + return parts.join(''); + } else { + options.metadata.rendered = true; + return function (el) { + var cb = function (item, index) { + var variableScope = {}; + if (variableName !== undefined) { + variableScope[variableName] = item; + } + return options.fn(options.scope.add({ index: index }, { special: true }).addLetContext(variableScope), options.options); + }; + live.list(el, items, cb, options.context, function (list) { + return options.inverse(options.scope, options.options); + }); + }; + } + }; + forHelper.isLiveBound = true; + forHelper.requiresOptionsArgument = true; + forHelper.ignoreArgLookup = function ignoreArgLookup(index) { + return index === 0; + }; + module.exports = forHelper; +}); +/*can-stache@5.1.1#helpers/-let*/ +define('can-stache@5.1.1#helpers/-let', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation-recorder' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + function isVariable(scope) { + return scope._meta.variable === true; + } + var letHelper = ObservationRecorder.ignore(function (options) { + if (options.isSection) { + return options.fn(options.scope.addLetContext(options.hash)); + } + var variableScope = options.scope.getScope(isVariable); + if (!variableScope) { + throw new Error('There is no variable scope!'); + } + canReflect.assignMap(variableScope._context, options.hash); + return document.createTextNode(''); + }); + module.exports = letHelper; +}); +/*can-stache@5.1.1#helpers/-portal*/ +define('can-stache@5.1.1#helpers/-portal', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-view-live', + 'can-observation', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-symbol', + 'can-view-live/lib/helpers' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var live = require('can-view-live'); + var Observation = require('can-observation'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var canSymbol = require('can-symbol'); + var liveHelpers = require('can-view-live/lib/helpers'); + var keepNodeSymbol = canSymbol.for('done.keepNode'); + function portalHelper(elementObservable, options) { + var debugName = 'portal(' + canReflect.getName(elementObservable) + ')'; + function portalContents() { + var frag = options.fn(options.scope.addLetContext({}), options.options); + var child = frag.firstChild; + while (child) { + child[keepNodeSymbol] = true; + child = child.nextSibling; + } + return frag; + } + var portalElement, startPortalledPlaceholder, endPortalledPlaceholder, commentPlaceholderDispose; + function teardownPortalledContent() { + if (portalElement) { + canReflect.offValue(elementObservable, getElementAndRender); + portalElement = null; + } + if (startPortalledPlaceholder && endPortalledPlaceholder) { + var parentNode = startPortalledPlaceholder.parentNode; + if (parentNode) { + liveHelpers.range.remove({ + start: startPortalledPlaceholder, + end: endPortalledPlaceholder + }); + domMutateNode.removeChild.call(parentNode, startPortalledPlaceholder); + domMutateNode.removeChild.call(parentNode, endPortalledPlaceholder); + startPortalledPlaceholder = endPortalledPlaceholder = null; + } + } + } + function teardownEverything() { + if (commentPlaceholderDispose) { + commentPlaceholderDispose(); + } + teardownPortalledContent(); + } + function getElementAndRender() { + teardownPortalledContent(); + canReflect.onValue(elementObservable, getElementAndRender); + portalElement = canReflect.getValue(elementObservable); + if (portalElement) { + startPortalledPlaceholder = portalElement.ownerDocument.createComment(debugName + ' contents'); + endPortalledPlaceholder = portalElement.ownerDocument.createComment('can-end-placeholder'); + startPortalledPlaceholder[keepNodeSymbol] = true; + endPortalledPlaceholder[keepNodeSymbol] = true; + portalElement.appendChild(startPortalledPlaceholder); + portalElement.appendChild(endPortalledPlaceholder); + var observable = new Observation(portalContents, null, { isObservable: false }); + live.html(startPortalledPlaceholder, observable); + } else { + options.metadata.rendered = true; + } + } + getElementAndRender(); + return function (placeholderElement) { + var commentPlaceholder = placeholderElement.ownerDocument.createComment(debugName); + placeholderElement.parentNode.replaceChild(commentPlaceholder, placeholderElement); + commentPlaceholderDispose = domMutate.onNodeRemoved(commentPlaceholder, teardownEverything); + return commentPlaceholder; + }; + } + portalHelper.isLiveBound = true; + portalHelper.requiresOptionsArgument = true; + module.exports = portalHelper; +}); +/*can-stache@5.1.1#helpers/core*/ +define('can-stache@5.1.1#helpers/core', [ + 'require', + 'exports', + 'module', + 'can-view-live', + '../src/utils', + 'can-globals/base-url/base-url', + 'can-join-uris', + 'can-assign', + 'can-log/dev/dev', + 'can-reflect', + './-debugger', + '../src/key-observable', + 'can-observation', + '../src/truthy-observable', + 'can-stache-helpers', + './converter', + 'can-dom-data', + './-for-of', + './-let', + './-portal' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var live = require('can-view-live'); + var utils = require('../src/utils'); + var getBaseURL = require('can-globals/base-url/base-url'); + var joinURIs = require('can-join-uris'); + var assign = require('can-assign'); + var dev = require('can-log/dev/dev'); + var canReflect = require('can-reflect'); + var debuggerHelper = require('./-debugger').helper; + var KeyObservable = require('../src/key-observable'); + var Observation = require('can-observation'); + var TruthyObservable = require('../src/truthy-observable'); + var helpers = require('can-stache-helpers'); + var makeConverter = require('./converter'); + var domData = require('can-dom-data'); + var forHelper = require('./-for-of'); + var letHelper = require('./-let'); + var portalHelper = require('./-portal'); + var builtInHelpers = {}; + var builtInConverters = {}; + var converterPackages = new WeakMap(); + var helpersCore = { + looksLikeOptions: function (options) { + return options && typeof options.fn === 'function' && typeof options.inverse === 'function'; + }, + resolve: function (value) { + if (value && canReflect.isValueLike(value)) { + return canReflect.getValue(value); + } else { + return value; + } + }, + resolveHash: function (hash) { + var params = {}; + for (var prop in hash) { + params[prop] = helpersCore.resolve(hash[prop]); + } + return params; + }, + bindAndRead: function (value) { + if (value && canReflect.isValueLike(value)) { + Observation.temporarilyBind(value); + return canReflect.getValue(value); + } else { + return value; + } + }, + registerHelper: function (name, callback) { + callback.requiresOptionsArgument = true; + helpers[name] = callback; + }, + registerHelpers: function (helpers) { + var name, callback; + for (name in helpers) { + callback = helpers[name]; + helpersCore.registerHelper(name, helpersCore.makeSimpleHelper(callback)); + } + }, + registerConverter: function (name, getterSetter) { + helpersCore.registerHelper(name, makeConverter(getterSetter)); + }, + makeSimpleHelper: function (fn) { + return function () { + var realArgs = []; + canReflect.eachIndex(arguments, function (val) { + realArgs.push(helpersCore.resolve(val)); + }); + return fn.apply(this, realArgs); + }; + }, + addHelper: function (name, callback) { + if (typeof name === 'object') { + return helpersCore.registerHelpers(name); + } + return helpersCore.registerHelper(name, helpersCore.makeSimpleHelper(callback)); + }, + addConverter: function (name, getterSetter) { + if (typeof name === 'object') { + if (!converterPackages.has(name)) { + converterPackages.set(name, true); + canReflect.eachKey(name, function (getterSetter, name) { + helpersCore.addConverter(name, getterSetter); + }); + } + return; + } + var helper = makeConverter(getterSetter); + helper.isLiveBound = true; + helpersCore.registerHelper(name, helper); + }, + addLiveHelper: function (name, callback) { + callback.isLiveBound = true; + return helpersCore.registerHelper(name, callback); + }, + getHelper: function (name, scope) { + var helper = scope && scope.getHelper(name); + if (!helper) { + helper = helpers[name]; + } + return helper; + }, + __resetHelpers: function () { + for (var helper in helpers) { + delete helpers[helper]; + } + converterPackages.delete(builtInConverters); + helpersCore.addBuiltInHelpers(); + helpersCore.addBuiltInConverters(); + }, + addBuiltInHelpers: function () { + canReflect.each(builtInHelpers, function (helper, helperName) { + helpers[helperName] = helper; + }); + }, + addBuiltInConverters: function () { + helpersCore.addConverter(builtInConverters); + }, + _makeLogicHelper: function (name, logic) { + var logicHelper = assign(function () { + var args = Array.prototype.slice.call(arguments, 0), options; + if (helpersCore.looksLikeOptions(args[args.length - 1])) { + options = args.pop(); + } + function callLogic() { + if (options) { + return logic(args) ? true : false; + } else { + return logic(args); + } + } + var callFn = new Observation(callLogic); + if (options) { + return callFn.get() ? options.fn() : options.inverse(); + } else { + return callFn.get(); + } + }, { + requiresOptionsArgument: true, + isLiveBound: true + }); + return logicHelper; + } + }; + var ifHelper = assign(function ifHelper(expr, options) { + var value; + if (expr && canReflect.isValueLike(expr)) { + value = canReflect.getValue(new TruthyObservable(expr)); + } else { + value = !!helpersCore.resolve(expr); + } + if (options) { + return value ? options.fn(options.scope || this) : options.inverse(options.scope || this); + } + return !!value; + }, { + requiresOptionsArgument: true, + isLiveBound: true + }); + var isHelper = helpersCore._makeLogicHelper('eq', function eqHelper(args) { + var curValue, lastValue; + for (var i = 0; i < args.length; i++) { + curValue = helpersCore.resolve(args[i]); + curValue = typeof curValue === 'function' ? curValue() : curValue; + if (i > 0) { + if (curValue !== lastValue) { + return false; + } + } + lastValue = curValue; + } + return true; + }); + var andHelper = helpersCore._makeLogicHelper('and', function andHelper(args) { + if (args.length === 0) { + return false; + } + var last; + for (var i = 0, len = args.length; i < len; i++) { + last = helpersCore.resolve(args[i]); + if (!last) { + return last; + } + } + return last; + }); + var orHelper = helpersCore._makeLogicHelper('or', function orHelper(args) { + if (args.length === 0) { + return false; + } + var last; + for (var i = 0, len = args.length; i < len; i++) { + last = helpersCore.resolve(args[i]); + if (last) { + return last; + } + } + return last; + }); + var switchHelper = function (expression, options) { + helpersCore.resolve(expression); + var found = false; + var caseHelper = function (value, options) { + if (!found && helpersCore.resolve(expression) === helpersCore.resolve(value)) { + found = true; + return options.fn(options.scope); + } + }; + caseHelper.requiresOptionsArgument = true; + var defaultHelper = function (options) { + if (!found) { + return options ? options.scope.peek('this') : true; + } + }; + defaultHelper.requiresOptionsArgument = true; + canReflect.assignSymbols(defaultHelper, { + 'can.isValueLike': true, + 'can.isFunctionLike': false, + 'can.getValue': function () { + return this(options); + } + }); + var newScope = options.scope.add({ + case: caseHelper, + default: defaultHelper + }, { notContext: true }); + return options.fn(newScope, options); + }; + switchHelper.requiresOptionsArgument = true; + var domDataHelper = function (attr, value) { + var data = (helpersCore.looksLikeOptions(value) ? value.context : value) || this; + return function setDomData(el) { + domData.set(el, attr, data); + }; + }; + var joinBaseHelper = function (firstExpr) { + var args = [].slice.call(arguments); + var options = args.pop(); + var moduleReference = args.map(function (expr) { + var value = helpersCore.resolve(expr); + return typeof value === 'function' ? value() : value; + }).join(''); + var templateModule = canReflect.getKeyValue(options.scope.templateContext.helpers, 'module'); + var parentAddress = templateModule ? templateModule.uri : undefined; + var isRelative = moduleReference[0] === '.'; + if (isRelative && parentAddress) { + return joinURIs(parentAddress, moduleReference); + } else { + var baseURL = typeof System !== 'undefined' && (System.renderingBaseURL || System.baseURL) || getBaseURL(); + if (moduleReference[0] !== '/' && baseURL[baseURL.length - 1] !== '/') { + baseURL += '/'; + } + return joinURIs(baseURL, moduleReference); + } + }; + joinBaseHelper.requiresOptionsArgument = true; + var eachHelper = function (items) { + var args = [].slice.call(arguments), options = args.pop(), hashExprs = options.exprData.hashExprs, resolved = helpersCore.bindAndRead(items), hashOptions, aliases; + if (canReflect.size(hashExprs) > 0) { + hashOptions = {}; + canReflect.eachKey(hashExprs, function (exprs, key) { + hashOptions[exprs.key] = key; + }); + } + if ((canReflect.isObservableLike(resolved) && canReflect.isListLike(resolved) || canReflect.isListLike(resolved) && canReflect.isValueLike(items)) && !options.stringOnly) { + options.metadata.rendered = true; + return function (el) { + var cb = function (item, index) { + var aliases = {}; + if (canReflect.size(hashOptions) > 0) { + if (hashOptions.value) { + aliases[hashOptions.value] = item; + } + if (hashOptions.index) { + aliases[hashOptions.index] = index; + } + } + return options.fn(options.scope.add(aliases, { notContext: true }).add({ index: index }, { special: true }).add(item), options.options); + }; + live.list(el, items, cb, options.context, function (list) { + return options.inverse(options.scope.add(list), options.options); + }); + }; + } + var expr = helpersCore.resolve(items), result; + if (!!expr && canReflect.isListLike(expr)) { + result = utils.getItemsFragContent(expr, options, options.scope); + return options.stringOnly ? result.join('') : result; + } else if (canReflect.isObservableLike(expr) && canReflect.isMapLike(expr) || expr instanceof Object) { + result = []; + canReflect.each(expr, function (val, key) { + var value = new KeyObservable(expr, key); + aliases = {}; + if (canReflect.size(hashOptions) > 0) { + if (hashOptions.value) { + aliases[hashOptions.value] = value; + } + if (hashOptions.key) { + aliases[hashOptions.key] = key; + } + } + result.push(options.fn(options.scope.add(aliases, { notContext: true }).add({ key: key }, { special: true }).add(value))); + }); + return options.stringOnly ? result.join('') : result; + } + }; + eachHelper.isLiveBound = true; + eachHelper.requiresOptionsArgument = true; + eachHelper.ignoreArgLookup = function ignoreArgLookup(index) { + return index === 1; + }; + var indexHelper = assign(function indexHelper(offset, options) { + if (!options) { + options = offset; + offset = 0; + } + var index = options.scope.peek('scope.index'); + return '' + ((typeof index === 'function' ? index() : index) + offset); + }, { requiresOptionsArgument: true }); + var withHelper = function (expr, options) { + var ctx = expr; + if (!options) { + options = expr; + expr = true; + ctx = options.hash; + } else { + expr = helpersCore.resolve(expr); + if (options.hash && canReflect.size(options.hash) > 0) { + ctx = options.scope.add(options.hash, { notContext: true }).add(ctx); + } + } + return options.fn(ctx || {}); + }; + withHelper.requiresOptionsArgument = true; + var dataHelper = function (attr, value) { + var data = (helpersCore.looksLikeOptions(value) ? value.context : value) || this; + return function setData(el) { + domData.set(el, attr, data); + }; + }; + var unlessHelper = function (expr, options) { + if (!options) { + return !ifHelper.apply(this, [expr]); + } + return ifHelper.apply(this, [ + expr, + assign(assign({}, options), { + fn: options.inverse, + inverse: options.fn + }) + ]); + }; + unlessHelper.requiresOptionsArgument = true; + unlessHelper.isLiveBound = true; + var notConverter = { + get: function (obs, options) { + if (helpersCore.looksLikeOptions(options)) { + return canReflect.getValue(obs) ? options.inverse() : options.fn(); + } else { + return !canReflect.getValue(obs); + } + }, + set: function (newVal, obs) { + canReflect.setValue(obs, !newVal); + } + }; + assign(builtInHelpers, { + 'debugger': debuggerHelper, + each: eachHelper, + eachOf: eachHelper, + index: indexHelper, + 'if': ifHelper, + is: isHelper, + eq: isHelper, + unless: unlessHelper, + 'with': withHelper, + console: console, + data: dataHelper, + domData: domDataHelper, + 'switch': switchHelper, + joinBase: joinBaseHelper, + and: andHelper, + or: orHelper, + 'let': letHelper, + 'for': forHelper, + portal: portalHelper + }); + assign(builtInConverters, { 'not': notConverter }); + helpersCore.addBuiltInHelpers(); + helpersCore.addBuiltInConverters(); + module.exports = helpersCore; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-ast@1.1.0#controls*/ +define('can-stache-ast@1.1.0#controls', function (require, exports, module) { + 'use strict'; + var mustacheLineBreakRegExp = /(?:(^|\r?\n)(\s*)(\{\{([\s\S]*)\}\}\}?)([^\S\n\r]*)($|\r?\n))|(\{\{([\s\S]*)\}\}\}?)/g, mustacheWhitespaceRegExp = /(\s*)(\{\{\{?)(-?)([\s\S]*?)(-?)(\}\}\}?)(\s*)/g; + function splitModeFromExpression(expression, state) { + expression = expression.trim(); + var mode = expression.charAt(0); + if ('#/{&^>!<'.indexOf(mode) >= 0) { + expression = expression.substr(1).trim(); + } else { + mode = null; + } + if (mode === '{' && state.node) { + mode = null; + } + return { + mode: mode, + expression: expression + }; + } + function cleanLineEndings(template) { + return template.replace(mustacheLineBreakRegExp, function (whole, returnBefore, spaceBefore, special, expression, spaceAfter, returnAfter, spaceLessSpecial, spaceLessExpression, matchIndex) { + spaceAfter = spaceAfter || ''; + returnBefore = returnBefore || ''; + spaceBefore = spaceBefore || ''; + var modeAndExpression = splitModeFromExpression(expression || spaceLessExpression, {}); + if (spaceLessSpecial || '>{'.indexOf(modeAndExpression.mode) >= 0) { + return whole; + } else if ('^#!/'.indexOf(modeAndExpression.mode) >= 0) { + spaceBefore = returnBefore + spaceBefore && ' '; + return spaceBefore + special + (matchIndex !== 0 && returnAfter.length ? returnBefore + '\n' : ''); + } else { + return spaceBefore + special + spaceAfter + (spaceBefore.length || matchIndex !== 0 ? returnBefore + '\n' : ''); + } + }); + } + function whiteSpaceReplacement(whole, spaceBefore, bracketBefore, controlBefore, expression, controlAfter, bracketAfter, spaceAfter) { + if (controlBefore === '-') { + spaceBefore = ''; + } + if (controlAfter === '-') { + spaceAfter = ''; + } + return spaceBefore + bracketBefore + expression + bracketAfter + spaceAfter; + } + function cleanWhitespaceControl(template) { + return template.replace(mustacheWhitespaceRegExp, whiteSpaceReplacement); + } + exports.cleanLineEndings = cleanLineEndings; + exports.cleanWhitespaceControl = cleanWhitespaceControl; +}); +/*can-stache-ast@1.1.0#can-stache-ast*/ +define('can-stache-ast@1.1.0#can-stache-ast', [ + 'require', + 'exports', + 'module', + './controls', + 'can-view-parser' +], function (require, exports, module) { + 'use strict'; + var controls = require('./controls'); + var parser = require('can-view-parser'); + exports.parse = function (filename, source) { + if (arguments.length === 1) { + source = arguments[0]; + filename = undefined; + } + var template = source; + template = controls.cleanWhitespaceControl(template); + template = controls.cleanLineEndings(template); + var imports = [], dynamicImports = [], importDeclarations = [], ases = {}, attributes = new Map(), inImport = false, inFrom = false, inAs = false, isUnary = false, importIsDynamic = false, currentAs = '', currentFrom = '', currentAttrName = null; + function processImport(line) { + if (currentAs) { + ases[currentAs] = currentFrom; + currentAs = ''; + } + if (importIsDynamic) { + dynamicImports.push(currentFrom); + } else { + imports.push(currentFrom); + } + importDeclarations.push({ + specifier: currentFrom, + loc: { line: line }, + attributes: attributes + }); + attributes = new Map(); + } + var program = parser(template, { + filename: filename, + start: function (tagName, unary) { + if (tagName === 'can-import') { + isUnary = unary; + importIsDynamic = false; + inImport = true; + } else if (tagName === 'can-dynamic-import') { + isUnary = unary; + importIsDynamic = true; + inImport = true; + } else if (inImport) { + importIsDynamic = true; + inImport = false; + } + }, + attrStart: function (attrName) { + currentAttrName = attrName; + attributes.set(currentAttrName, true); + if (attrName === 'from') { + inFrom = true; + } else if (attrName === 'as' || attrName === 'export-as') { + inAs = true; + } + }, + attrEnd: function (attrName) { + if (attrName === 'from') { + inFrom = false; + } else if (attrName === 'as' || attrName === 'export-as') { + inAs = false; + } + }, + attrValue: function (value) { + if (inImport) { + attributes.set(currentAttrName, value); + } + if (inFrom && inImport) { + currentFrom = value; + } else if (inAs && inImport) { + currentAs = value; + } + }, + end: function (tagName, unary, line) { + if ((tagName === 'can-import' || tagName === 'can-dynamic-import') && isUnary) { + processImport(line); + } + }, + close: function (tagName, unary, line) { + if (tagName === 'can-import' || tagName === 'can-dynamic-import') { + processImport(line); + } + }, + chars: function (text) { + if (text.trim().length > 0) { + importIsDynamic = true; + } + }, + special: function () { + importIsDynamic = true; + } + }, true); + return { + intermediate: program, + program: program, + imports: imports, + dynamicImports: dynamicImports, + importDeclarations: importDeclarations, + ases: ases, + exports: ases + }; + }; +}); +/*can-import-module@1.2.0#can-import-module*/ +define('can-import-module@1.2.0#can-import-module', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-namespace' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getGlobal = require('can-globals/global/global'); + var namespace = require('can-namespace'); + module.exports = namespace.import = function (moduleName, parentName) { + return new Promise(function (resolve, reject) { + try { + var global = getGlobal(); + if (typeof global.System === 'object' && isFunction(global.System['import'])) { + global.System['import'](moduleName, { name: parentName }).then(resolve, reject); + } else if (global.define && global.define.amd) { + global.require([moduleName], function (value) { + resolve(value); + }); + } else if (global.require) { + resolve(global.require(moduleName)); + } else { + if (typeof stealRequire !== 'undefined') { + steal.import(moduleName, { name: parentName }).then(resolve, reject); + } else { + resolve(); + } + } + } catch (err) { + reject(err); + } + }); + }; + function isFunction(fn) { + return typeof fn === 'function'; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache@5.1.1#can-stache*/ +define('can-stache@5.1.1#can-stache', [ + 'require', + 'exports', + 'module', + 'can-view-parser', + 'can-view-callbacks', + './src/html_section', + './src/text_section', + './src/mustache_core', + './helpers/core', + 'can-stache-ast', + './src/utils', + 'can-attribute-encoder', + 'can-log/dev/dev', + 'can-namespace', + 'can-globals/document/document', + 'can-assign', + 'can-import-module', + 'can-reflect', + 'can-view-scope', + 'can-view-scope/template-context', + 'can-observation-recorder', + 'can-symbol', + 'can-view-target' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var parser = require('can-view-parser'); + var viewCallbacks = require('can-view-callbacks'); + var HTMLSectionBuilder = require('./src/html_section'); + var TextSectionBuilder = require('./src/text_section'); + var mustacheCore = require('./src/mustache_core'); + var mustacheHelpers = require('./helpers/core'); + var getIntermediateAndImports = require('can-stache-ast').parse; + var utils = require('./src/utils'); + var makeRendererConvertScopes = utils.makeRendererConvertScopes; + var last = utils.last; + var attributeEncoder = require('can-attribute-encoder'); + var dev = require('can-log/dev/dev'); + var namespace = require('can-namespace'); + var DOCUMENT = require('can-globals/document/document'); + var assign = require('can-assign'); + var importer = require('can-import-module'); + var canReflect = require('can-reflect'); + var Scope = require('can-view-scope'); + var TemplateContext = require('can-view-scope/template-context'); + var ObservationRecorder = require('can-observation-recorder'); + var canSymbol = require('can-symbol'); + require('can-view-target'); + if (!viewCallbacks.tag('content')) { + viewCallbacks.tag('content', function (el, tagData) { + return tagData.scope; + }); + } + var isViewSymbol = canSymbol.for('can.isView'); + var wrappedAttrPattern = /[{(].*[)}]/; + var colonWrappedAttrPattern = /^on:|(:to|:from|:bind)$|.*:to:on:.*/; + var svgNamespace = 'http://www.w3.org/2000/svg', xmlnsAttrNamespaceURI = 'http://www.w3.org/2000/xmlns/', xlinkHrefAttrNamespaceURI = 'http://www.w3.org/1999/xlink'; + var namespaces = { + 'svg': svgNamespace, + 'g': svgNamespace, + 'defs': svgNamespace, + 'path': svgNamespace, + 'filter': svgNamespace, + 'feMorphology': svgNamespace, + 'feGaussianBlur': svgNamespace, + 'feOffset': svgNamespace, + 'feComposite': svgNamespace, + 'feColorMatrix': svgNamespace, + 'use': svgNamespace + }, attrsNamespacesURI = { + 'xmlns': xmlnsAttrNamespaceURI, + 'xlink:href': xlinkHrefAttrNamespaceURI + }, textContentOnlyTag = { + style: true, + script: true + }; + function stache(filename, template) { + if (arguments.length === 1) { + template = arguments[0]; + filename = undefined; + } + var inlinePartials = {}; + if (typeof template === 'string') { + template = mustacheCore.cleanWhitespaceControl(template); + template = mustacheCore.cleanLineEndings(template); + } + var section = new HTMLSectionBuilder(filename), state = { + node: null, + attr: null, + sectionElementStack: [], + text: false, + namespaceStack: [], + textContentOnly: null + }, makeRendererAndUpdateSection = function (section, mode, stache, lineNo) { + if (mode === '>') { + section.add(mustacheCore.makeLiveBindingPartialRenderer(stache, copyState({ + filename: section.filename, + lineNo: lineNo + }))); + } else if (mode === '/') { + var createdSection = section.last(); + if (createdSection.startedWith === '<') { + inlinePartials[stache] = section.endSubSectionAndReturnRenderer(); + section.removeCurrentNode(); + section.removeCurrentNode(); + } else { + section.endSection(); + } + if (section instanceof HTMLSectionBuilder) { + state.sectionElementStack.pop(); + } + } else if (mode === 'else') { + section.inverse(); + } else { + var makeRenderer = section instanceof HTMLSectionBuilder ? mustacheCore.makeLiveBindingBranchRenderer : mustacheCore.makeStringBranchRenderer; + if (mode === '{' || mode === '&') { + section.add(makeRenderer(null, stache, copyState({ + filename: section.filename, + lineNo: lineNo + }))); + } else if (mode === '#' || mode === '^' || mode === '<') { + var renderer = makeRenderer(mode, stache, copyState({ + filename: section.filename, + lineNo: lineNo + })); + var sectionItem = { type: 'section' }; + section.startSection(renderer, stache); + section.last().startedWith = mode; + if (section instanceof HTMLSectionBuilder) { + state.sectionElementStack.push(sectionItem); + } + } else { + section.add(makeRenderer(null, stache, copyState({ + text: true, + filename: section.filename, + lineNo: lineNo + }))); + } + } + }, isDirectlyNested = function () { + var lastElement = state.sectionElementStack[state.sectionElementStack.length - 1]; + return state.sectionElementStack.length ? lastElement.type === 'section' || lastElement.type === 'custom' : true; + }, copyState = function (overwrites) { + var cur = { + tag: state.node && state.node.tag, + attr: state.attr && state.attr.name, + directlyNested: isDirectlyNested(), + textContentOnly: !!state.textContentOnly + }; + return overwrites ? assign(cur, overwrites) : cur; + }, addAttributesCallback = function (node, callback) { + if (!node.attributes) { + node.attributes = []; + } + node.attributes.unshift(callback); + }; + parser(template, { + filename: filename, + start: function (tagName, unary, lineNo) { + var matchedNamespace = namespaces[tagName]; + if (matchedNamespace && !unary) { + state.namespaceStack.push(matchedNamespace); + } + state.node = { + tag: tagName, + children: [], + namespace: matchedNamespace || last(state.namespaceStack) + }; + }, + end: function (tagName, unary, lineNo) { + var isCustomTag = viewCallbacks.tag(tagName); + var directlyNested = isDirectlyNested(); + if (unary) { + section.add(state.node); + if (isCustomTag) { + addAttributesCallback(state.node, function (scope) { + viewCallbacks.tagHandler(this, tagName, { + scope: scope, + subtemplate: null, + templateType: 'stache', + directlyNested: directlyNested + }); + }); + } + } else { + section.push(state.node); + state.sectionElementStack.push({ + type: isCustomTag ? 'custom' : null, + tag: isCustomTag ? null : tagName, + templates: {}, + directlyNested: directlyNested + }); + if (isCustomTag) { + section.startSubSection(); + } else if (textContentOnlyTag[tagName]) { + state.textContentOnly = new TextSectionBuilder(filename); + } + } + state.node = null; + }, + close: function (tagName, lineNo) { + var matchedNamespace = namespaces[tagName]; + if (matchedNamespace) { + state.namespaceStack.pop(); + } + var isCustomTag = viewCallbacks.tag(tagName), renderer; + if (isCustomTag) { + renderer = section.endSubSectionAndReturnRenderer(); + } + if (textContentOnlyTag[tagName]) { + section.last().add(state.textContentOnly.compile(copyState())); + state.textContentOnly = null; + } + var oldNode = section.pop(); + if (isCustomTag) { + if (tagName === 'can-template') { + var parent = state.sectionElementStack[state.sectionElementStack.length - 2]; + if (renderer) { + parent.templates[oldNode.attrs.name] = makeRendererConvertScopes(renderer); + } + section.removeCurrentNode(); + } else { + var current = state.sectionElementStack[state.sectionElementStack.length - 1]; + addAttributesCallback(oldNode, function (scope) { + viewCallbacks.tagHandler(this, tagName, { + scope: scope, + subtemplate: renderer ? makeRendererConvertScopes(renderer) : renderer, + templateType: 'stache', + templates: current.templates, + directlyNested: current.directlyNested + }); + }); + } + } + state.sectionElementStack.pop(); + }, + attrStart: function (attrName, lineNo) { + if (state.node.section) { + state.node.section.add(attrName + '="'); + } else { + state.attr = { + name: attrName, + value: '' + }; + } + }, + attrEnd: function (attrName, lineNo) { + var matchedAttrNamespacesURI = attrsNamespacesURI[attrName]; + if (state.node.section) { + state.node.section.add('" '); + } else { + if (!state.node.attrs) { + state.node.attrs = {}; + } + if (state.attr.section) { + state.node.attrs[state.attr.name] = state.attr.section.compile(copyState()); + } else if (matchedAttrNamespacesURI) { + state.node.attrs[state.attr.name] = { + value: state.attr.value, + namespaceURI: attrsNamespacesURI[attrName] + }; + } else { + state.node.attrs[state.attr.name] = state.attr.value; + } + var attrCallback = viewCallbacks.attr(attrName); + if (attrCallback) { + if (!state.node.attributes) { + state.node.attributes = []; + } + state.node.attributes.push(function (scope) { + attrCallback(this, { + attributeName: attrName, + scope: scope + }); + }); + } + state.attr = null; + } + }, + attrValue: function (value, lineNo) { + var section = state.node.section || state.attr.section; + if (section) { + section.add(value); + } else { + state.attr.value += value; + } + }, + chars: function (text, lineNo) { + (state.textContentOnly || section).add(text); + }, + special: function (text, lineNo) { + var firstAndText = mustacheCore.splitModeFromExpression(text, state), mode = firstAndText.mode, expression = firstAndText.expression; + if (expression === 'else') { + var inverseSection; + if (state.attr && state.attr.section) { + inverseSection = state.attr.section; + } else if (state.node && state.node.section) { + inverseSection = state.node.section; + } else { + inverseSection = state.textContentOnly || section; + } + inverseSection.inverse(); + return; + } + if (mode === '!') { + return; + } + if (state.node && state.node.section) { + makeRendererAndUpdateSection(state.node.section, mode, expression, lineNo); + if (state.node.section.subSectionDepth() === 0) { + state.node.attributes.push(state.node.section.compile(copyState())); + delete state.node.section; + } + } else if (state.attr) { + if (!state.attr.section) { + state.attr.section = new TextSectionBuilder(filename); + if (state.attr.value) { + state.attr.section.add(state.attr.value); + } + } + makeRendererAndUpdateSection(state.attr.section, mode, expression, lineNo); + } else if (state.node) { + if (!state.node.attributes) { + state.node.attributes = []; + } + if (!mode) { + state.node.attributes.push(mustacheCore.makeLiveBindingBranchRenderer(null, expression, copyState({ + filename: section.filename, + lineNo: lineNo + }))); + } else if (mode === '#' || mode === '^') { + if (!state.node.section) { + state.node.section = new TextSectionBuilder(filename); + } + makeRendererAndUpdateSection(state.node.section, mode, expression, lineNo); + } else { + throw new Error(mode + ' is currently not supported within a tag.'); + } + } else { + makeRendererAndUpdateSection(state.textContentOnly || section, mode, expression, lineNo); + } + }, + comment: function (text) { + section.add({ comment: text }); + }, + done: function (lineNo) { + } + }); + var renderer = section.compile(); + var scopifiedRenderer = ObservationRecorder.ignore(function (scope, options) { + if (options && !options.helpers && !options.partials && !options.tags) { + options = { helpers: options }; + } + canReflect.eachKey(options && options.helpers, function (helperValue) { + helperValue.requiresOptionsArgument = true; + }); + var templateContext = new TemplateContext(options); + canReflect.eachKey(inlinePartials, function (partial, partialName) { + canReflect.setKeyValue(templateContext.partials, partialName, partial); + }); + canReflect.setKeyValue(templateContext, 'view', scopifiedRenderer); + if (!(scope instanceof Scope)) { + scope = new Scope(templateContext).add(scope); + } else { + var templateContextScope = new Scope(templateContext); + templateContextScope._parent = scope._parent; + scope._parent = templateContextScope; + } + return renderer(scope.addLetContext()); + }); + scopifiedRenderer[isViewSymbol] = true; + return scopifiedRenderer; + } + assign(stache, mustacheHelpers); + stache.safeString = function (text) { + return canReflect.assignSymbols({}, { + 'can.toDOM': function () { + return text; + } + }); + }; + stache.async = function (source) { + var iAi = getIntermediateAndImports(source); + var importPromises = iAi.imports.map(function (moduleName) { + return importer(moduleName); + }); + return Promise.all(importPromises).then(function () { + return stache(iAi.intermediate); + }); + }; + var templates = {}; + stache.from = mustacheCore.getTemplateById = function (id) { + if (!templates[id]) { + var el = DOCUMENT().getElementById(id); + if (el) { + templates[id] = stache('#' + id, el.innerHTML); + } + } + return templates[id]; + }; + stache.registerPartial = function (id, partial) { + templates[id] = typeof partial === 'string' ? stache(partial) : partial; + }; + stache.addBindings = viewCallbacks.attrs; + module.exports = namespace.stache = stache; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-element@1.2.0#src/mixin-lifecycle-methods*/ +define('can-stache-element@1.2.0#src/mixin-lifecycle-methods', function (require, exports, module) { + 'use strict'; + const lifecycleStatusSymbol = Symbol.for('can.lifecycleStatus'); + const inSetupSymbol = Symbol.for('can.initializing'); + const teardownHandlersSymbol = Symbol.for('can.teardownHandlers'); + function defineConfigurableNonEnumerable(obj, prop, value) { + Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: value + }); + } + module.exports = function mixinLifecycleMethods(BaseElement = HTMLElement) { + return class LifecycleElement extends BaseElement { + constructor() { + super(); + if (arguments.length) { + throw new Error('can-stache-element: Do not pass arguments to the constructor. Initial property values should be passed to the `initialize` hook.'); + } + defineConfigurableNonEnumerable(this, inSetupSymbol, true); + defineConfigurableNonEnumerable(this, lifecycleStatusSymbol, { + initialized: false, + rendered: false, + connected: false, + disconnected: false + }); + defineConfigurableNonEnumerable(this, teardownHandlersSymbol, []); + } + connectedCallback(props) { + this.initialize(props); + this.render(); + this.connect(); + return this; + } + disconnectedCallback() { + this.disconnect(); + return this; + } + initialize(props) { + const lifecycleStatus = this[lifecycleStatusSymbol]; + if (lifecycleStatus.initialized) { + return this; + } + this[inSetupSymbol] = true; + if (super.initialize) { + super.initialize(props); + } + this[inSetupSymbol] = false; + lifecycleStatus.initialized = true; + return this; + } + render(props) { + const lifecycleStatus = this[lifecycleStatusSymbol]; + if (lifecycleStatus.rendered) { + return this; + } + if (!lifecycleStatus.initialized) { + this.initialize(props); + } + if (super.render) { + super.render(props); + } + lifecycleStatus.rendered = true; + return this; + } + connect(props) { + const lifecycleStatus = this[lifecycleStatusSymbol]; + if (lifecycleStatus.connected) { + return this; + } + if (!lifecycleStatus.initialized) { + this.initialize(props); + } + if (!lifecycleStatus.rendered) { + this.render(props); + } + if (super.connect) { + super.connect(props); + } + if (this.connected) { + let connectedTeardown = this.connected(); + if (typeof connectedTeardown === 'function') { + this[teardownHandlersSymbol].push(connectedTeardown); + } + } + lifecycleStatus.connected = true; + lifecycleStatus.disconnected = false; + return this; + } + disconnect() { + const lifecycleStatus = this[lifecycleStatusSymbol]; + if (lifecycleStatus.disconnected) { + return this; + } + if (super.disconnect) { + super.disconnect(); + } + if (this.stopListening) { + this.stopListening(); + } + for (let handler of this[teardownHandlersSymbol]) { + handler.call(this); + } + if (this.disconnected) { + this.disconnected(); + } + this[lifecycleStatusSymbol] = { + initialized: false, + rendered: false, + connected: false, + disconnected: true + }; + return this; + } + }; + }; +}); +/*can-observable-mixin@1.0.10#src/create-constructor-function*/ +define('can-observable-mixin@1.0.10#src/create-constructor-function', function (require, exports, module) { + function createConstructorFunction(Type, Parent) { + if (typeof Parent === 'undefined') { + Parent = Object.getPrototypeOf(Object); + } + function TypeConstructor() { + return Reflect.construct(Type, arguments, this.constructor); + } + TypeConstructor.prototype = Object.create(Type.prototype); + TypeConstructor.prototype.constructor = TypeConstructor; + function copyIfMissing(source, prop) { + if (!TypeConstructor[prop]) { + Object.defineProperty(TypeConstructor, prop, Object.getOwnPropertyDescriptor(source, prop)); + } + } + let Link = Type; + while (Link !== Parent && Link !== null) { + const props = Object.getOwnPropertyNames(Link); + props.forEach(function (prop) { + copyIfMissing(Link, prop); + }); + const symbols = Object.getOwnPropertySymbols(Link); + symbols.forEach(function (symbol) { + copyIfMissing(Link, symbol); + }); + Link = Object.getPrototypeOf(Link); + } + return TypeConstructor; + } + module.exports = createConstructorFunction; +}); +/*can-simple-observable@2.5.0#async/async*/ +define('can-simple-observable@2.5.0#async/async', [ + 'require', + 'exports', + 'module', + '../can-simple-observable', + 'can-observation', + 'can-queues', + '../settable/settable', + 'can-reflect', + 'can-observation-recorder', + 'can-event-queue/value/value' +], function (require, exports, module) { + 'use strict'; + var SimpleObservable = require('../can-simple-observable'); + var Observation = require('can-observation'); + var queues = require('can-queues'); + var SettableObservable = require('../settable/settable'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var valueEventBindings = require('can-event-queue/value/value'); + function AsyncObservable(fn, context, initialValue) { + this.resolve = this.resolve.bind(this); + this.lastSetValue = new SimpleObservable(initialValue); + this.handler = this.handler.bind(this); + function observe() { + this.resolveCalled = false; + this.inGetter = true; + var newVal = fn.call(context, this.lastSetValue.get(), this.bound === true ? this.resolve : undefined); + this.inGetter = false; + if (newVal !== undefined) { + this.resolve(newVal); + } else if (this.resolveCalled) { + this.resolve(this._value); + } + if (this.bound !== true) { + return newVal; + } + } + this.observation = new Observation(observe, this); + } + AsyncObservable.prototype = Object.create(SettableObservable.prototype); + AsyncObservable.prototype.constructor = AsyncObservable; + AsyncObservable.prototype.handler = function (newVal) { + if (newVal !== undefined) { + SettableObservable.prototype.handler.apply(this, arguments); + } + }; + var peek = ObservationRecorder.ignore(canReflect.getValue.bind(canReflect)); + AsyncObservable.prototype.activate = function () { + canReflect.onValue(this.observation, this.handler, 'notify'); + if (!this.resolveCalled) { + this._value = peek(this.observation); + } + }; + AsyncObservable.prototype.resolve = function resolve(newVal) { + this.resolveCalled = true; + var old = this._value; + this._value = newVal; + if (!this.inGetter) { + var queuesArgs = [ + this.handlers.getNode([]), + this, + [ + newVal, + old + ], + null + ]; + queues.enqueueByQueue.apply(queues, queuesArgs); + } + }; + module.exports = AsyncObservable; +}); +/*can-simple-observable@2.5.0#resolver/resolver*/ +define('can-simple-observable@2.5.0#resolver/resolver', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + 'can-observation-recorder', + 'can-observation', + 'can-queues', + 'can-event-queue/map/map', + '../settable/settable', + '../can-simple-observable' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var ObservationRecorder = require('can-observation-recorder'); + var Observation = require('can-observation'); + var queues = require('can-queues'); + var mapEventBindings = require('can-event-queue/map/map'); + var SettableObservable = require('../settable/settable'); + var SimpleObservable = require('../can-simple-observable'); + var getChangesSymbol = canSymbol.for('can.getChangesDependencyRecord'); + var metaSymbol = canSymbol.for('can.meta'); + function ResolverObservable(resolver, context, initialValue, options) { + this.resolver = ObservationRecorder.ignore(resolver); + this.context = context; + this._valueOptions = { + resolve: this.resolve.bind(this), + listenTo: this.listenTo.bind(this), + stopListening: this.stopListening.bind(this), + lastSet: new SimpleObservable(initialValue) + }; + this.update = this.update.bind(this); + this.contextHandlers = new WeakMap(); + this.teardown = null; + this.binder = {}; + this[metaSymbol] = canReflect.assignMap({}, options); + } + ResolverObservable.prototype = Object.create(SettableObservable.prototype); + function deleteHandler(bindTarget, event, queue, handler) { + mapEventBindings.off.call(bindTarget, event, handler, queue); + } + canReflect.assignMap(ResolverObservable.prototype, { + constructor: ResolverObservable, + listenTo: function (bindTarget, event, handler, queueName) { + if (canReflect.isPrimitive(bindTarget)) { + handler = event; + event = bindTarget; + bindTarget = this.context; + } + if (typeof event === 'function') { + handler = event; + event = undefined; + } + var resolverInstance = this; + var contextHandler = handler.bind(this.context); + contextHandler[getChangesSymbol] = function getChangesDependencyRecord() { + var s = new Set(); + s.add(resolverInstance); + return { valueDependencies: s }; + }; + this.contextHandlers.set(handler, contextHandler); + mapEventBindings.listenTo.call(this.binder, bindTarget, event, contextHandler, queueName || 'notify'); + }, + stopListening: function () { + var meta = this.binder[canSymbol.for('can.meta')]; + var listenHandlers = meta && meta.listenHandlers; + if (listenHandlers) { + var keys = mapEventBindings.stopListeningArgumentsToKeys.call({ + context: this.context, + defaultQueue: 'notify' + }); + listenHandlers.delete(keys, deleteHandler); + } + return this; + }, + resolve: function (newVal) { + this._value = newVal; + if (this.isBinding) { + this.lastValue = this._value; + return newVal; + } + if (this._value !== this.lastValue) { + var enqueueMeta = {}; + queues.batch.start(); + queues.deriveQueue.enqueue(this.update, this, [], enqueueMeta); + queues.batch.stop(); + } + return newVal; + }, + update: function () { + if (this.lastValue !== this._value) { + var old = this.lastValue; + this.lastValue = this._value; + queues.enqueueByQueue(this.handlers.getNode([]), this, [ + this._value, + old + ]); + } + }, + activate: function () { + this.isBinding = true; + this.teardown = this.resolver.call(this.context, this._valueOptions); + this.isBinding = false; + }, + onUnbound: function () { + this.bound = false; + mapEventBindings.stopListening.call(this.binder); + if (this.teardown != null) { + this.teardown(); + this.teardown = null; + } + }, + set: function (value) { + this._valueOptions.lastSet.set(value); + }, + get: function () { + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this); + if (!this.bound) { + this.onBound(); + } + } + if (this.bound === true) { + return this._value; + } else { + if (this[metaSymbol].resetUnboundValueInGet) { + this._value = undefined; + } + var handler = function () { + }; + this.on(handler); + var val = this._value; + this.off(handler); + return val; + } + }, + hasDependencies: function hasDependencies() { + var hasDependencies = false; + if (this.bound) { + var meta = this.binder[metaSymbol]; + var listenHandlers = meta && meta.listenHandlers; + hasDependencies = !!listenHandlers.size(); + } + return hasDependencies; + }, + getValueDependencies: function getValueDependencies() { + if (this.bound) { + var meta = this.binder[canSymbol.for('can.meta')]; + var listenHandlers = meta && meta.listenHandlers; + var keyDeps = new Map(); + var valueDeps = new Set(); + if (listenHandlers) { + canReflect.each(listenHandlers.root, function (events, obj) { + canReflect.each(events, function (queues, eventName) { + if (eventName === undefined) { + valueDeps.add(obj); + } else { + var entry = keyDeps.get(obj); + if (!entry) { + entry = new Set(); + keyDeps.set(obj, entry); + } + entry.add(eventName); + } + }); + }); + if (valueDeps.size || keyDeps.size) { + var result = {}; + if (keyDeps.size) { + result.keyDependencies = keyDeps; + } + if (valueDeps.size) { + result.valueDependencies = valueDeps; + } + return result; + } + } + } + } + }); + canReflect.assignSymbols(ResolverObservable.prototype, { + 'can.getValue': ResolverObservable.prototype.get, + 'can.setValue': ResolverObservable.prototype.set, + 'can.isMapLike': false, + 'can.getPriority': function () { + return this.priority || 0; + }, + 'can.setPriority': function (newPriority) { + this.priority = newPriority; + }, + 'can.valueHasDependencies': ResolverObservable.prototype.hasDependencies, + 'can.getValueDependencies': ResolverObservable.prototype.getValueDependencies + }); + module.exports = ResolverObservable; +}); +/*can-event-queue@1.1.8#type/type*/ +define('can-event-queue@1.1.8#type/type', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + 'can-key-tree', + 'can-queues' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var KeyTree = require('can-key-tree'); + var queues = require('can-queues'); + var metaSymbol = canSymbol.for('can.meta'); + function addHandlers(obj, meta) { + if (!meta.lifecycleHandlers) { + meta.lifecycleHandlers = new KeyTree([ + Object, + Array + ]); + } + if (!meta.instancePatchesHandlers) { + meta.instancePatchesHandlers = new KeyTree([ + Object, + Array + ]); + } + } + function ensureMeta(obj) { + var meta = obj[metaSymbol]; + if (!meta) { + meta = {}; + canReflect.setKeyValue(obj, metaSymbol, meta); + } + addHandlers(obj, meta); + return meta; + } + var props = {}; + function onOffAndDispatch(symbolName, dispatchName, handlersName) { + props['can.on' + symbolName] = function (handler, queueName) { + ensureMeta(this)[handlersName].add([ + queueName || 'mutate', + handler + ]); + }; + props['can.off' + symbolName] = function (handler, queueName) { + ensureMeta(this)[handlersName].delete([ + queueName || 'mutate', + handler + ]); + }; + props['can.' + dispatchName] = function (instance, arg) { + queues.enqueueByQueue(ensureMeta(this)[handlersName].getNode([]), this, [ + instance, + arg + ]); + }; + } + onOffAndDispatch('InstancePatches', 'dispatchInstanceOnPatches', 'instancePatchesHandlers'); + onOffAndDispatch('InstanceBoundChange', 'dispatchInstanceBoundChange', 'lifecycleHandlers'); + function mixinTypeBindings(obj) { + return canReflect.assignSymbols(obj, props); + } + Object.defineProperty(mixinTypeBindings, 'addHandlers', { + enumerable: false, + value: addHandlers + }); + module.exports = mixinTypeBindings; +}); +/*can-type@1.1.5#can-type*/ +define('can-type@1.1.5#can-type', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + 'can-string', + 'can-namespace' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var canString = require('can-string'); + var namespace = require('can-namespace'); + var isMemberSymbol = canSymbol.for('can.isMember'); + var newSymbol = canSymbol.for('can.new'); + var getSchemaSymbol = canSymbol.for('can.getSchema'); + var baseTypeSymbol = canSymbol.for('can.baseType'); + var strictTypeOfSymbol = canSymbol.for('can.strictTypeOf'); + var type = exports; + function makeSchema(values) { + return function () { + return { + type: 'Or', + values: values + }; + }; + } + function canNew(value) { + if (this[isMemberSymbol](value)) { + return value; + } + return canReflect.convert(value, this[baseTypeSymbol]); + } + function strictNew(value) { + var isMember = this[isMemberSymbol](value); + if (!isMember) { + return check(this[baseTypeSymbol], value); + } + return value; + } + function booleanNew(value) { + if (value === 'false' || value === '0') { + return false; + } + return Boolean(value); + } + var maybeValues = Object.freeze([ + null, + undefined + ]); + function check(Type, val) { + var valueType = canString.capitalize(typeof val); + var error = new Error('Type value ' + typeof val === 'string' ? '"' + val + '"' : val + ' (' + valueType + ') is not of type ' + canReflect.getName(Type) + '.'); + error.type = 'can-type-error'; + throw error; + } + function makeIsMember(Type) { + if (isMemberSymbol in Type) { + return Type[isMemberSymbol]; + } + return function (value) { + return value instanceof Type; + }; + } + function makeBaseType(Type) { + var typeObject = {}; + typeObject[newSymbol] = canNew; + typeObject[isMemberSymbol] = makeIsMember(Type); + typeObject[baseTypeSymbol] = Type; + typeObject[getSchemaSymbol] = makeSchema([Type]); + Type[strictTypeOfSymbol] = typeObject[strictTypeOfSymbol] = typeObject; + return typeObject; + } + function makePrimitiveType(Type, typeString) { + var typeObject = makeBaseType(Type); + if (Type === Boolean) { + typeObject[newSymbol] = booleanNew; + typeObject[getSchemaSymbol] = makeSchema([ + true, + false + ]); + } + typeObject[isMemberSymbol] = function (value) { + return typeof value === typeString; + }; + return typeObject; + } + function getBaseType(Type) { + if (typeof Type === 'function') { + if (canReflect.hasOwnKey(Type, strictTypeOfSymbol)) { + return Type[strictTypeOfSymbol]; + } + } else if (strictTypeOfSymbol in Type) { + return Type[strictTypeOfSymbol]; + } + return makeBaseType(Type); + } + function makeMaybe(Type) { + var isMember = Type[isMemberSymbol]; + return function (value) { + return value == null || isMember.call(this, value); + }; + } + function makeMaybeSchema(baseType) { + var baseSchema = canReflect.getSchema(baseType); + var allValues = baseSchema.values.concat(maybeValues); + return makeSchema(allValues); + } + function inheritFrom(o, Type, property) { + if (property in Type) { + o[property] = Type[property]; + } + } + function wrapName(wrapper, Type) { + var baseName = canReflect.getName(Type); + return 'type.' + wrapper + '(' + baseName + ')'; + } + canReflect.each({ + 'boolean': Boolean, + 'number': Number, + 'string': String + }, function (Type, typeString) { + makePrimitiveType(Type, typeString); + }); + function isTypeObject(Type) { + if (canReflect.isPrimitive(Type)) { + return false; + } + return newSymbol in Type && isMemberSymbol in Type; + } + function normalize(Type) { + if (canReflect.isPrimitive(Type)) { + throw new Error('can-type: Unable to normalize primitive values.'); + } else if (isTypeObject(Type)) { + return Type; + } else { + return type.check(Type); + } + } + function late(fn) { + var lateType = {}; + var underlyingType; + var unwrap = function () { + underlyingType = type.normalize(fn()); + unwrap = function () { + return underlyingType; + }; + return underlyingType; + }; + return canReflect.assignSymbols(lateType, { + 'can.new': function (val) { + return canReflect.new(unwrap(), val); + }, + 'can.isMember': function (val) { + return unwrap()[isMemberSymbol](val); + } + }); + } + var Any = canReflect.assignSymbols({}, { + 'can.new': function (val) { + return val; + }, + 'can.isMember': function () { + return true; + } + }); + function all(typeFn, Type) { + var typeObject = typeFn(Type); + typeObject[getSchemaSymbol] = function () { + var parentSchema = canReflect.getSchema(Type); + var schema = canReflect.assignMap({}, parentSchema); + schema.keys = {}; + canReflect.eachKey(parentSchema.keys, function (value, key) { + schema.keys[key] = typeFn(value); + }); + return schema; + }; + function Constructor(values) { + var schema = canReflect.getSchema(this); + var keys = schema.keys; + var convertedValues = {}; + canReflect.eachKey(values || {}, function (value, key) { + convertedValues[key] = canReflect.convert(value, keys[key]); + }); + return canReflect.new(Type, convertedValues); + } + canReflect.setName(Constructor, 'Converted<' + canReflect.getName(Type) + '>'); + Constructor.prototype = typeObject; + return Constructor; + } + var Integer = {}; + Integer[newSymbol] = function (value) { + return value | 0; + }; + Integer[isMemberSymbol] = function (value) { + return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; + }; + Integer[getSchemaSymbol] = makeSchema([Number]); + canReflect.setName(Integer, 'Integer'); + function makeCache(fn) { + var cache = new WeakMap(); + return function (Type) { + if (cache.has(Type)) { + return cache.get(Type); + } + var typeObject = fn.call(this, Type); + cache.set(Type, typeObject); + return typeObject; + }; + } + exports.check = makeCache(function (Type) { + var o = Object.create(getBaseType(Type)); + o[newSymbol] = strictNew; + inheritFrom(o, Type, isMemberSymbol); + inheritFrom(o, Type, getSchemaSymbol); + canReflect.setName(o, wrapName('check', Type)); + return o; + }); + exports.convert = makeCache(function (Type) { + var o = Object.create(getBaseType(Type)); + inheritFrom(o, Type, isMemberSymbol); + inheritFrom(o, Type, getSchemaSymbol); + canReflect.setName(o, wrapName('convert', Type)); + return o; + }); + exports.maybe = makeCache(function (Type) { + var baseType = getBaseType(Type); + var desc = {}; + desc[newSymbol] = { value: strictNew }; + desc[isMemberSymbol] = { value: makeMaybe(baseType) }; + desc[getSchemaSymbol] = { value: makeMaybeSchema(baseType) }; + var o = Object.create(baseType, desc); + canReflect.setName(o, wrapName('maybe', Type)); + return o; + }); + exports.maybeConvert = makeCache(function (Type) { + var baseType = getBaseType(Type); + var desc = {}; + desc[isMemberSymbol] = { value: makeMaybe(baseType) }; + desc[getSchemaSymbol] = { value: makeMaybeSchema(baseType) }; + var o = Object.create(baseType, desc); + canReflect.setName(o, wrapName('maybeConvert', Type)); + return o; + }); + exports.Any = Any; + exports.Integer = Integer; + exports.late = late; + exports.isTypeObject = isTypeObject; + exports.normalize = normalize; + exports.all = all; + exports.convertAll = all.bind(null, exports.convert); + namespace.type = exports; +}); +/*can-observable-mixin@1.0.10#src/define*/ +define('can-observable-mixin@1.0.10#src/define', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation', + 'can-observation-recorder', + 'can-simple-observable/async/async', + 'can-simple-observable/settable/settable', + 'can-simple-observable/resolver/resolver', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + 'can-queues', + 'can-assign', + 'can-log/dev/dev', + 'can-define-lazy-value', + 'can-type' +], function (require, exports, module) { + 'use strict'; + const canReflect = require('can-reflect'); + let define; + const Observation = require('can-observation'); + const ObservationRecorder = require('can-observation-recorder'); + const AsyncObservable = require('can-simple-observable/async/async'); + const SettableObservable = require('can-simple-observable/settable/settable'); + const ResolverObservable = require('can-simple-observable/resolver/resolver'); + const eventQueue = require('can-event-queue/map/map'); + const addTypeEvents = require('can-event-queue/type/type'); + const queues = require('can-queues'); + const assign = require('can-assign'); + const canLogDev = require('can-log/dev/dev'); + const defineLazyValue = require('can-define-lazy-value'); + const type = require('can-type'); + const newSymbol = Symbol.for('can.new'), serializeSymbol = Symbol.for('can.serialize'), inSetupSymbol = Symbol.for('can.initializing'), isMemberSymbol = Symbol.for('can.isMember'), hasBeenDefinedSymbol = Symbol.for('can.hasBeenDefined'), canMetaSymbol = Symbol.for('can.meta'), baseTypeSymbol = Symbol.for('can.baseType'); + let eventsProto, make, makeDefinition, getDefinitionsAndMethods, getDefinitionOrMethod; + function isDefineType(func) { + return func && (func.canDefineType === true || func[newSymbol]); + } + function observableType() { + throw new Error('This is not currently implemented.'); + } + let AsyncFunction; + const browserSupportsAsyncFunctions = function () { + try { + AsyncFunction = async function () { + }.constructor; + return true; + } catch (e) { + return false; + } + }(); + function isAsyncFunction(fn) { + if (!browserSupportsAsyncFunctions) { + return false; + } + return fn && fn instanceof AsyncFunction; + } + const peek = ObservationRecorder.ignore(canReflect.getValue.bind(canReflect)); + let Object_defineNamedPrototypeProperty = Object.defineProperty; + function defineConfigurableAndNotEnumerable(obj, prop, value) { + Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: value + }); + } + function defineNotWritableAndNotEnumerable(obj, prop, value) { + Object.defineProperty(obj, prop, { + value: value, + enumerable: false, + writable: false + }); + } + function eachPropertyDescriptor(map, cb, ...args) { + for (const prop of Object.getOwnPropertyNames(map)) { + if (map.hasOwnProperty(prop)) { + cb.call(map, prop, Object.getOwnPropertyDescriptor(map, prop), ...args); + } + } + } + function getEveryPropertyAndSymbol(obj) { + const props = Object.getOwnPropertyNames(obj); + const symbols = 'getOwnPropertySymbols' in Object ? Object.getOwnPropertySymbols(obj) : []; + return props.concat(symbols); + } + module.exports = define = function (typePrototype, defines, baseDefine, propertyDefaults = {}) { + let prop, dataInitializers = Object.create(baseDefine ? baseDefine.dataInitializers : null), computedInitializers = Object.create(baseDefine ? baseDefine.computedInitializers : null), required = new Set(); + const result = getDefinitionsAndMethods(defines, baseDefine, typePrototype, propertyDefaults); + result.dataInitializers = dataInitializers; + result.computedInitializers = computedInitializers; + result.required = required; + canReflect.eachKey(result.definitions, function (definition, property) { + if (definition.required === true) { + required.add(property); + } + define.property(typePrototype, property, definition, dataInitializers, computedInitializers, result.defaultDefinition); + }); + if (typePrototype.hasOwnProperty('_data')) { + for (prop in dataInitializers) { + defineLazyValue(typePrototype._data, prop, dataInitializers[prop].bind(typePrototype), true); + } + } else { + defineLazyValue(typePrototype, '_data', function () { + const map = this; + const data = {}; + for (const prop in dataInitializers) { + defineLazyValue(data, prop, dataInitializers[prop].bind(map), true); + } + return data; + }); + } + if (typePrototype.hasOwnProperty('_computed')) { + for (prop in computedInitializers) { + defineLazyValue(typePrototype._computed, prop, computedInitializers[prop].bind(typePrototype)); + } + } else { + defineLazyValue(typePrototype, '_computed', function () { + const map = this; + const data = Object.create(null); + for (const prop in computedInitializers) { + defineLazyValue(data, prop, computedInitializers[prop].bind(map)); + } + return data; + }); + } + getEveryPropertyAndSymbol(eventsProto).forEach(function (prop) { + Object.defineProperty(typePrototype, prop, { + enumerable: false, + value: eventsProto[prop], + configurable: true, + writable: true + }); + }); + Object.defineProperty(typePrototype, '_define', { + enumerable: false, + value: result, + configurable: true, + writable: true + }); + const iteratorSymbol = Symbol.iterator || Symbol.for('iterator'); + if (!typePrototype[iteratorSymbol]) { + defineConfigurableAndNotEnumerable(typePrototype, iteratorSymbol, function () { + return new define.Iterator(this); + }); + } + return result; + }; + const onlyType = function (obj) { + for (const prop in obj) { + if (prop !== 'type') { + return false; + } + } + return true; + }; + const callAsync = function (fn) { + return function asyncResolver(lastSet, resolve) { + let newValue = fn.call(this, resolve, lastSet); + if (canReflect.isPromise(newValue)) { + newValue.then(resolve); + return undefined; + } + return newValue; + }; + }; + define.extensions = function () { + }; + define.isEnumerable = function (definition) { + return typeof definition !== 'object' || ('serialize' in definition ? !!definition.serialize : !definition.get && !definition.async && !definition.value); + }; + define.property = function (typePrototype, prop, definition, dataInitializers, computedInitializers, defaultDefinition) { + const propertyDefinition = define.extensions.apply(this, arguments); + if (propertyDefinition) { + definition = makeDefinition(prop, propertyDefinition, defaultDefinition || {}, typePrototype); + } + const type = definition.type; + if (type && onlyType(definition) && type === type.Any) { + Object_defineNamedPrototypeProperty(typePrototype, prop, { + get: make.get.data(prop), + set: make.set.events(prop, make.get.data(prop), make.set.data(prop), make.eventType.data(prop)), + enumerable: true, + configurable: true + }); + return; + } + definition.type = type; + let dataProperty = definition.get || definition.async || definition.value ? 'computed' : 'data', reader = make.read[dataProperty](prop), getter = make.get[dataProperty](prop), setter = make.set[dataProperty](prop), getInitialValue; + let typeConvert = function (val) { + return val; + }; + if (type) { + typeConvert = make.set.type(prop, type, typeConvert); + } + const eventsSetter = make.set.events(prop, reader, setter, make.eventType[dataProperty](prop)); + if (definition.value) { + computedInitializers[prop] = make.resolver(prop, definition, typeConvert); + } else if (definition.default !== undefined) { + getInitialValue = ObservationRecorder.ignore(make.get.defaultValue(prop, definition, typeConvert, eventsSetter)); + } + if (definition.get) { + computedInitializers[prop] = make.compute(prop, definition.get, getInitialValue); + } else if (definition.async) { + computedInitializers[prop] = make.compute(prop, callAsync(definition.async), getInitialValue); + } else if (getInitialValue) { + dataInitializers[prop] = getInitialValue; + } + if (definition.get && definition.set) { + setter = make.set.setter(prop, definition.set, make.read.lastSet(prop), setter, true); + } else if (definition.set) { + setter = make.set.setter(prop, definition.set, reader, eventsSetter, false); + } else if (dataProperty === 'data') { + setter = eventsSetter; + } else if (definition.get && definition.get.length < 1) { + setter = function () { + }; + } + if (type) { + setter = make.set.type(prop, type, setter); + } + Object_defineNamedPrototypeProperty(typePrototype, prop, { + get: getter, + set: setter, + enumerable: define.isEnumerable(definition), + configurable: true + }); + }; + define.makeDefineInstanceKey = function (constructor) { + constructor[Symbol.for('can.defineInstanceKey')] = function (property, value) { + define.hooks.finalizeClass(this); + const defineResult = this.prototype._define; + if (value && typeof value.value !== 'undefined') { + value.default = value.value; + value.type = type.Any; + delete value.value; + } + const definition = getDefinitionOrMethod(property, value, defineResult.defaultDefinition, this); + if (definition && typeof definition === 'object') { + define.property(this.prototype, property, definition, defineResult.dataInitializers, defineResult.computedInitializers, defineResult.defaultDefinition); + defineResult.definitions[property] = definition; + } else { + defineResult.methods[property] = definition; + } + this.prototype.dispatch({ + action: 'can.keys', + type: 'can.keys', + target: this.prototype + }); + }; + }; + define.Constructor = function (defines, sealed) { + const constructor = function DefineConstructor(props) { + Object.defineProperty(this, inSetupSymbol, { + configurable: true, + enumerable: false, + value: true, + writable: true + }); + define.setup.call(this, props, sealed); + this[inSetupSymbol] = false; + }; + const result = define(constructor.prototype, defines); + addTypeEvents(constructor); + define.makeDefineInstanceKey(constructor, result); + return constructor; + }; + make = { + computeObj: function (map, prop, observable) { + const computeObj = { + oldValue: undefined, + compute: observable, + count: 0, + handler: function (newVal) { + let oldValue = computeObj.oldValue; + computeObj.oldValue = newVal; + map.dispatch({ + action: 'prop', + key: prop, + value: newVal, + oldValue: oldValue, + type: prop, + target: map + }, [ + newVal, + oldValue + ]); + } + }; + return computeObj; + }, + resolver: function (prop, definition, typeConvert) { + const getDefault = make.get.defaultValue(prop, definition, typeConvert); + return function () { + const map = this; + const defaultValue = getDefault.call(this); + const computeObj = make.computeObj(map, prop, new ResolverObservable(definition.value, map, defaultValue, { resetUnboundValueInGet: true })); + return computeObj; + }; + }, + compute: function (prop, get, defaultValueFn) { + return function () { + const map = this; + const defaultValue = defaultValueFn && defaultValueFn.call(this); + let observable, computeObj; + if (get.length === 0) { + observable = new Observation(get, map); + } else if (get.length === 1) { + observable = new SettableObservable(get, map, defaultValue); + } else { + observable = new AsyncObservable(get, map, defaultValue); + } + computeObj = make.computeObj(map, prop, observable); + return computeObj; + }; + }, + set: { + data: function (prop) { + return function (newVal) { + this._data[prop] = newVal; + }; + }, + computed: function (prop) { + return function (val) { + canReflect.setValue(this._computed[prop].compute, val); + }; + }, + events: function (prop, getCurrent, setData) { + return function (newVal) { + if (this[inSetupSymbol]) { + setData.call(this, newVal); + } else { + const current = getCurrent.call(this); + if (newVal !== current) { + let dispatched; + setData.call(this, newVal); + dispatched = { + patches: [{ + type: 'set', + key: prop, + value: newVal + }], + action: 'prop', + key: prop, + value: newVal, + oldValue: current, + type: prop, + target: this + }; + this.dispatch(dispatched, [ + newVal, + current + ]); + } + } + }; + }, + eventDispatcher: function (map, prop, current, newVal) { + if (map[inSetupSymbol]) { + return; + } else { + if (newVal !== current) { + const dispatched = { + patches: [{ + type: 'set', + key: prop, + value: newVal + }], + action: 'prop', + key: prop, + value: newVal, + oldValue: current, + type: prop, + target: map + }; + eventQueue.dispatch.call(map, dispatched, [ + newVal, + current + ]); + } + } + }, + setter: function (prop, setter, getCurrent, setEvents, hasGetter) { + return function (value) { + const self = this; + queues.batch.start(); + const setterCalled = false, current = getCurrent.call(this), setValue = setter.call(this, value, current); + if (setterCalled) { + queues.batch.stop(); + } else { + if (hasGetter) { + if (setValue !== undefined) { + if (current !== setValue) { + setEvents.call(this, setValue); + } + queues.batch.stop(); + } else if (setter.length === 0) { + setEvents.call(this, value); + queues.batch.stop(); + return; + } else if (setter.length === 1) { + queues.batch.stop(); + } else { + queues.batch.stop(); + return; + } + } else { + if (setValue !== undefined) { + setEvents.call(this, setValue); + queues.batch.stop(); + } else if (setter.length === 0) { + setEvents.call(this, value); + queues.batch.stop(); + return; + } else if (setter.length === 1) { + setEvents.call(this, undefined); + queues.batch.stop(); + } else { + queues.batch.stop(); + return; + } + } + } + }; + }, + type: function (prop, type, set) { + function setter(newValue) { + return set.call(this, type.call(this, newValue, prop)); + } + if (isDefineType(type)) { + if (type.canDefineType) { + return setter; + } else { + return function setter(newValue) { + return set.call(this, canReflect.convert(newValue, type)); + }; + } + } + return setter; + } + }, + eventType: { + data: function (prop) { + return function (newVal, oldVal) { + return oldVal !== undefined || this._data.hasOwnProperty(prop) ? 'set' : 'add'; + }; + }, + computed: function () { + return function () { + return 'set'; + }; + } + }, + read: { + data: function (prop) { + return function () { + return this._data[prop]; + }; + }, + computed: function (prop) { + return function () { + return canReflect.getValue(this._computed[prop].compute); + }; + }, + lastSet: function (prop) { + return function () { + const observable = this._computed[prop].compute; + if (observable.lastSetValue) { + return canReflect.getValue(observable.lastSetValue); + } + }; + } + }, + get: { + defaultValue: function (prop, definition, typeConvert, callSetter) { + return function () { + let value = definition.default; + if (value !== undefined) { + if (typeof value === 'function' && value.isAGetter) { + value = value.call(this); + } + value = typeConvert.call(this, value); + } + if (definition.set) { + let VALUE; + let sync = true; + const setter = make.set.setter(prop, definition.set, function () { + }, function (value) { + if (sync) { + VALUE = value; + } else { + callSetter.call(this, value); + } + }, definition.get); + setter.call(this, value); + sync = false; + return VALUE; + } + return value; + }; + }, + data: function (prop) { + return function () { + if (!this[inSetupSymbol]) { + ObservationRecorder.add(this, prop); + } + return this._data[prop]; + }; + }, + computed: function (prop) { + return function () { + const compute = this._computed[prop].compute; + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this, prop); + if (!canReflect.isBound(compute)) { + Observation.temporarilyBind(compute); + } + } + return peek(compute); + }; + } + } + }; + define.behaviors = [ + 'get', + 'set', + 'value', + 'type', + 'serialize' + ]; + const addBehaviorToDefinition = function (definition, behavior, descriptor, def, prop, typePrototype) { + if (behavior === 'enumerable') { + definition.serialize = !!def[behavior]; + } else if (behavior === 'type') { + const behaviorDef = def[behavior]; + if (typeof behaviorDef !== 'undefined') { + definition[behavior] = behaviorDef; + } + } else { + const value = descriptor.get || descriptor.value; + if (descriptor.get) { + value.isAGetter = true; + } + if (behavior === 'async') { + if (value.length === 1 && isAsyncFunction(value)) { + canLogDev.warn(`${ canReflect.getName(typePrototype) }: async property [${ prop }] should not be an async function and also use the resolve() argument. Remove the argument and return a value from the async function instead.`); + } + } + definition[behavior] = value; + } + }; + makeDefinition = function (prop, def, defaultDefinition, typePrototype) { + let definition = {}; + eachPropertyDescriptor(def, function (behavior, descriptor) { + addBehaviorToDefinition(definition, behavior, descriptor, def, prop, typePrototype); + }); + canReflect.eachKey(defaultDefinition, function (value, prop) { + if (definition[prop] === undefined) { + if (prop !== 'type') { + definition[prop] = value; + } + } + }); + if (def.type) { + const value = def.type; + const serialize = value[serializeSymbol]; + if (serialize) { + definition.serialize = function (val) { + return serialize.call(val); + }; + } + definition.type = type.normalize(value); + } + const noTypeDefined = !definition.type && (!defaultDefinition.type || defaultDefinition.type && defaultDefinition.typeSetByDefault); + if (definition.hasOwnProperty('default')) { + if (typeof definition.default === 'function' && !definition.default.isAGetter && noTypeDefined) { + definition.type = type.normalize(Function); + } + if (canReflect.isPrimitive(definition.default) && noTypeDefined) { + if (definition.default === null || typeof definition.default === 'undefined') { + definition.type = type.Any; + } else { + definition.type = type.normalize(definition.default.constructor); + } + } + } + if (!definition.type) { + const defaultsCopy = canReflect.assignMap({}, defaultDefinition); + definition = canReflect.assignMap(defaultsCopy, definition); + } + if (canReflect.size(definition) === 0) { + definition.type = type.Any; + definition.typeSetByDefault = true; + } + return definition; + }; + getDefinitionOrMethod = function (prop, value, defaultDefinition, typePrototype) { + let definition; + let definitionType; + if (canReflect.isPrimitive(value)) { + if (value === null || typeof value === 'undefined') { + definitionType = type.Any; + } else { + definitionType = defaultDefinition.typeSetByDefault ? type.normalize(value.constructor) : defaultDefinition.type; + } + definition = { + default: value, + type: definitionType + }; + } else if (value && (value[serializeSymbol] || value[newSymbol])) { + if (value[isMemberSymbol]) { + definition = { type: value }; + } else { + definition = { type: type.normalize(value) }; + } + } else if (typeof value === 'function') { + if (canReflect.isConstructorLike(value)) { + definition = { type: type.normalize(value) }; + } else { + definition = { + default: value, + type: Function + }; + } + } else if (Array.isArray(value)) { + definition = { type: type.normalize(Array) }; + } else if (canReflect.isPlainObject(value)) { + definition = value; + } + if (definition) { + return makeDefinition(prop, definition, defaultDefinition, typePrototype); + } else { + return value; + } + }; + getDefinitionsAndMethods = function (defines, baseDefines, typePrototype, propertyDefaults) { + const definitions = Object.create(baseDefines ? baseDefines.definitions : null); + let methods = {}; + let defaultDefinition; + if (propertyDefaults) { + defaultDefinition = getDefinitionOrMethod('*', propertyDefaults, {}, typePrototype); + } else { + defaultDefinition = Object.create(null); + } + function addDefinition(prop, propertyDescriptor, skipGetDefinitionForMethods) { + let value; + if (propertyDescriptor.get || propertyDescriptor.set) { + value = { + get: propertyDescriptor.get, + set: propertyDescriptor.set + }; + } else { + value = propertyDescriptor.value; + } + if (prop === 'constructor' || skipGetDefinitionForMethods && typeof value === 'function') { + methods[prop] = value; + return; + } else { + const result = getDefinitionOrMethod(prop, value, defaultDefinition, typePrototype); + const resultType = typeof result; + if (result && resultType === 'object' && canReflect.size(result) > 0) { + definitions[prop] = result; + } else { + if (resultType === 'function') { + methods[prop] = result; + } + } + } + } + eachPropertyDescriptor(typePrototype, addDefinition, true); + eachPropertyDescriptor(defines, addDefinition); + if (propertyDefaults) { + defineConfigurableAndNotEnumerable(defines, '*', propertyDefaults); + } + return { + definitions: definitions, + methods: methods, + defaultDefinition: defaultDefinition + }; + }; + eventsProto = eventQueue({}); + function setupComputed(instance, eventName) { + const computedBinding = instance._computed && instance._computed[eventName]; + if (computedBinding && computedBinding.compute) { + if (!computedBinding.count) { + computedBinding.count = 1; + canReflect.onValue(computedBinding.compute, computedBinding.handler, 'notify'); + computedBinding.oldValue = peek(computedBinding.compute); + } else { + computedBinding.count++; + } + } + } + function teardownComputed(instance, eventName) { + const computedBinding = instance._computed && instance._computed[eventName]; + if (computedBinding) { + if (computedBinding.count === 1) { + computedBinding.count = 0; + canReflect.offValue(computedBinding.compute, computedBinding.handler, 'notify'); + } else { + computedBinding.count--; + } + } + } + assign(eventsProto, { + _eventSetup: function () { + }, + _eventTeardown: function () { + }, + addEventListener: function (eventName) { + setupComputed(this, eventName); + return eventQueue.addEventListener.apply(this, arguments); + }, + removeEventListener: function (eventName) { + teardownComputed(this, eventName); + return eventQueue.removeEventListener.apply(this, arguments); + } + }); + eventsProto.on = eventsProto.bind = eventsProto.addEventListener; + eventsProto.off = eventsProto.unbind = eventsProto.removeEventListener; + const onKeyValueSymbol = Symbol.for('can.onKeyValue'); + const offKeyValueSymbol = Symbol.for('can.offKeyValue'); + canReflect.assignSymbols(eventsProto, { + 'can.onKeyValue': function (key) { + setupComputed(this, key); + return eventQueue[onKeyValueSymbol].apply(this, arguments); + }, + 'can.offKeyValue': function (key) { + teardownComputed(this, key); + return eventQueue[offKeyValueSymbol].apply(this, arguments); + } + }); + delete eventsProto.one; + define.finalizeInstance = function () { + defineNotWritableAndNotEnumerable(this, 'constructor', this.constructor); + defineNotWritableAndNotEnumerable(this, canMetaSymbol, Object.create(null)); + }; + define.setup = function (props, sealed) { + const requiredButNotProvided = new Set(this._define.required); + const definitions = this._define.definitions; + const instanceDefinitions = Object.create(null); + const map = this; + canReflect.eachKey(props, function (value, prop) { + if (requiredButNotProvided.has(prop)) { + requiredButNotProvided.delete(prop); + } + if (definitions[prop] !== undefined) { + map[prop] = value; + } else { + if (sealed) { + throw new Error(`The type ${ canReflect.getName(map.constructor) } is sealed, but the property [${ prop }] has no definition.`); + } + define.expando(map, prop, value); + } + }); + if (canReflect.size(instanceDefinitions) > 0) { + defineConfigurableAndNotEnumerable(this, '_instanceDefinitions', instanceDefinitions); + } + if (requiredButNotProvided.size) { + let msg; + const missingProps = Array.from(requiredButNotProvided); + let thisName = canReflect.getName(this); + if (requiredButNotProvided.size === 1) { + msg = `${ thisName }: Missing required property [${ missingProps[0] }].`; + } else { + msg = `${ thisName }: Missing required properties [${ missingProps.join(', ') }].`; + } + throw new Error(msg); + } + }; + const returnFirstArg = function (arg) { + return arg; + }; + define.normalizeTypeDefinition = type.normalize; + define.expando = function (map, prop, value) { + if (define._specialKeys[prop]) { + return true; + } + const constructorDefines = map._define.definitions; + if (constructorDefines && constructorDefines[prop]) { + return; + } + let instanceDefines = map._instanceDefinitions; + if (!instanceDefines) { + if (Object.isSealed(map)) { + let errorMessage = `Cannot set property [${ prop }] on sealed instance of ${ canReflect.getName(map) }`; + throw new Error(errorMessage); + } + Object.defineProperty(map, '_instanceDefinitions', { + configurable: true, + enumerable: false, + writable: true, + value: {} + }); + instanceDefines = map._instanceDefinitions; + } + if (!instanceDefines[prop]) { + const defaultDefinition = map._define.defaultDefinition || { type: observableType }; + define.property(map, prop, defaultDefinition, {}, {}); + if (defaultDefinition.type) { + map._data[prop] = define.make.set.type(prop, defaultDefinition.type, returnFirstArg).call(map, value); + } else { + map._data[prop] = observableType(value); + } + instanceDefines[prop] = defaultDefinition; + if (!map[inSetupSymbol]) { + queues.batch.start(); + map.dispatch({ + action: 'can.keys', + type: 'can.keys', + target: map + }); + if (Object.prototype.hasOwnProperty.call(map._data, prop)) { + map.dispatch({ + action: 'add', + key: prop, + type: prop, + value: map._data[prop], + target: map, + patches: [{ + type: 'add', + key: prop, + value: map._data[prop] + }] + }, [ + map._data[prop], + undefined + ]); + } else { + map.dispatch({ + action: 'set', + type: 'set', + value: map._data[prop], + target: map, + patches: [{ + type: 'add', + key: prop, + value: map._data[prop] + }] + }, [ + map._data[prop], + undefined + ]); + } + queues.batch.stop(); + } + return true; + } + }; + define.replaceWith = defineLazyValue; + define.eventsProto = eventsProto; + define.defineConfigurableAndNotEnumerable = defineConfigurableAndNotEnumerable; + define.make = make; + define.getDefinitionOrMethod = getDefinitionOrMethod; + define._specialKeys = { + _data: true, + _computed: true + }; + let simpleGetterSetters = {}; + define.makeSimpleGetterSetter = function (prop) { + if (simpleGetterSetters[prop] === undefined) { + const setter = make.set.events(prop, make.get.data(prop), make.set.data(prop), make.eventType.data(prop)); + simpleGetterSetters[prop] = { + get: make.get.data(prop), + set: function (newVal) { + return setter.call(this, observableType(newVal)); + }, + enumerable: true, + configurable: true + }; + } + return simpleGetterSetters[prop]; + }; + define.Iterator = function (obj) { + this.obj = obj; + this.definitions = Object.keys(obj._define.definitions); + this.instanceDefinitions = obj._instanceDefinitions ? Object.keys(obj._instanceDefinitions) : Object.keys(obj); + this.hasGet = typeof obj.get === 'function'; + }; + define.Iterator.prototype.next = function () { + let key; + if (this.definitions.length) { + key = this.definitions.shift(); + const def = this.obj._define.definitions[key]; + if (def.get) { + return this.next(); + } + } else if (this.instanceDefinitions.length) { + key = this.instanceDefinitions.shift(); + } else { + return { + value: undefined, + done: true + }; + } + return { + value: [ + key, + this.hasGet ? this.obj.get(key) : this.obj[key] + ], + done: false + }; + }; + define.updateSchemaKeys = function (schema, definitions) { + for (const prop in definitions) { + const definition = definitions[prop]; + if (definition.serialize !== false) { + if (definition.type) { + schema.keys[prop] = definition.type; + } else { + schema.keys[prop] = function (val) { + return val; + }; + } + if (definitions[prop].identity === true) { + schema.identity.push(prop); + } + } + } + return schema; + }; + define.hooks = { + finalizeClass: function (Type) { + let hasBeenDefined = Type.hasOwnProperty(hasBeenDefinedSymbol); + if (!hasBeenDefined) { + let prototypeObject = Type.prototype; + let defines = typeof Type.props === 'object' ? Type.props : typeof Type.define === 'object' ? Type.define : {}; + define(prototypeObject, defines, null, Type.propertyDefaults); + Type[hasBeenDefinedSymbol] = true; + } + }, + initialize: function (instance, props) { + const firstInitialize = !instance.hasOwnProperty(canMetaSymbol); + const sealed = instance.constructor.seal; + if (firstInitialize) { + define.finalizeInstance.call(instance); + } + if (!instance[canMetaSymbol].initialized) { + defineConfigurableAndNotEnumerable(instance, inSetupSymbol, true); + define.setup.call(instance, props, sealed); + instance[inSetupSymbol] = false; + instance[canMetaSymbol].initialized = true; + } + }, + expando: define.expando, + normalizeTypeDefinition: type.normalize + }; +}); +/*can-observable-mixin@1.0.10#src/ensure-meta*/ +define('can-observable-mixin@1.0.10#src/ensure-meta', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + const canReflect = require('can-reflect'); + module.exports = function ensureMeta(obj) { + const metaSymbol = Symbol.for('can.meta'); + let meta = obj[metaSymbol]; + if (!meta) { + meta = {}; + canReflect.setKeyValue(obj, metaSymbol, meta); + } + return meta; + }; +}); +/*can-observable-mixin@1.0.10#src/define-helpers*/ +define('can-observable-mixin@1.0.10#src/define-helpers', [ + 'require', + 'exports', + 'module', + './define', + 'can-reflect', + 'can-queues', + 'can-log/dev/dev', + './ensure-meta' +], function (require, exports, module) { + 'use strict'; + const define = require('./define'); + const canReflect = require('can-reflect'); + const queues = require('can-queues'); + const dev = require('can-log/dev/dev'); + const ensureMeta = require('./ensure-meta'); + const defineHelpers = { + defineExpando: define.expando, + reflectSerialize: function (unwrapped) { + const constructorDefinitions = this._define.definitions; + const defaultDefinition = this._define.defaultDefinition; + this.forEach(function (val, name) { + const propDef = constructorDefinitions[name]; + if (propDef && typeof propDef.serialize === 'function') { + val = propDef.serialize.call(this, val, name); + } else if (defaultDefinition && typeof defaultDefinition.serialize === 'function') { + val = defaultDefinition.serialize.call(this, val, name); + } else { + val = canReflect.serialize(val); + } + if (val !== undefined) { + unwrapped[name] = val; + } + }, this); + return unwrapped; + }, + reflectUnwrap: function (unwrapped) { + this.forEach(function (value, key) { + if (value !== undefined) { + unwrapped[key] = canReflect.unwrap(value); + } + }); + return unwrapped; + }, + log: function (key) { + const instance = this; + const quoteString = function quoteString(x) { + return typeof x === 'string' ? JSON.stringify(x) : x; + }; + const meta = ensureMeta(instance); + const allowed = meta.allowedLogKeysSet || new Set(); + meta.allowedLogKeysSet = allowed; + if (key) { + allowed.add(key); + } + meta._log = function (event, data) { + const type = event.type; + if (type === 'can.onPatches' || key && !allowed.has(type) || type === 'can.keys' || key && !allowed.has(type)) { + return; + } + if (type === 'add' || type === 'remove') { + dev.log(canReflect.getName(instance), '\n how ', quoteString(type), '\n what ', quoteString(data[0]), '\n index ', quoteString(data[1])); + } else { + dev.log(canReflect.getName(instance), '\n key ', quoteString(type), '\n is ', quoteString(data[0]), '\n was ', quoteString(data[1])); + } + }; + }, + deleteKey: function (prop) { + const instanceDefines = this._instanceDefinitions; + if (instanceDefines && Object.prototype.hasOwnProperty.call(instanceDefines, prop) && !Object.isSealed(this)) { + delete instanceDefines[prop]; + delete this[prop]; + queues.batch.start(); + this.dispatch({ + action: 'can.keys', + type: 'can.keys', + target: this + }); + const oldValue = this._data[prop]; + if (oldValue !== undefined) { + delete this._data[prop]; + this.dispatch({ + action: 'delete', + key: prop, + oldValue: oldValue, + type: prop, + target: this, + patches: [{ + type: 'delete', + key: prop + }] + }, [ + undefined, + oldValue + ]); + } + queues.batch.stop(); + } else { + this.set(prop, undefined); + } + return this; + } + }; + module.exports = defineHelpers; +}); +/*can-observable-mixin@1.0.10#src/mixin-mapprops*/ +define('can-observable-mixin@1.0.10#src/mixin-mapprops', [ + 'require', + 'exports', + 'module', + './define', + './define-helpers', + 'can-observation-recorder', + 'can-log/dev/dev', + 'can-reflect', + 'can-queues' +], function (require, exports, module) { + const addDefinedProps = require('./define'); + const {updateSchemaKeys, hooks, isEnumerable} = addDefinedProps; + const defineHelpers = require('./define-helpers'); + const ObservationRecorder = require('can-observation-recorder'); + const canLogDev = require('can-log/dev/dev'); + const canReflect = require('can-reflect'); + const queues = require('can-queues'); + const getSchemaSymbol = Symbol.for('can.getSchema'); + function keysForDefinition(definitions) { + const keys = []; + for (let prop in definitions) { + if (isEnumerable(definitions[prop])) { + keys.push(prop); + } + } + return keys; + } + function assign(source) { + queues.batch.start(); + canReflect.assignMap(this, source || {}); + queues.batch.stop(); + } + function update(source) { + queues.batch.start(); + if (canReflect.isListLike(source)) { + canReflect.updateList(this, source); + } else { + canReflect.updateMap(this, source || {}); + } + queues.batch.stop(); + } + function assignDeep(source) { + queues.batch.start(); + canReflect.assignDeepMap(this, source || {}); + queues.batch.stop(); + } + function updateDeep(source) { + queues.batch.start(); + if (canReflect.isListLike(source)) { + canReflect.updateDeepList(this, source); + } else { + canReflect.updateDeepMap(this, source || {}); + } + queues.batch.stop(); + } + function setKeyValue(key, value) { + const defined = defineHelpers.defineExpando(this, key, value); + if (!defined) { + this[key] = value; + } + } + function getKeyValue(key) { + const value = this[key]; + if (value !== undefined || key in this || Object.isSealed(this)) { + return value; + } else { + ObservationRecorder.add(this, key); + return this[key]; + } + } + module.exports = function (Type) { + return class extends Type { + static [getSchemaSymbol]() { + hooks.finalizeClass(this); + let def = this.prototype._define; + let definitions = def ? def.definitions : {}; + let schema = { + type: 'map', + identity: [], + keys: {} + }; + return updateSchemaKeys(schema, definitions); + } + get(prop) { + if (prop) { + return getKeyValue.call(this, prop); + } else { + return canReflect.unwrap(this, Map); + } + } + set(prop, value) { + if (typeof prop === 'object') { + if (value === true) { + updateDeep.call(this, prop); + } else { + assignDeep.call(this, prop); + } + } else { + setKeyValue.call(this, prop, value); + } + return this; + } + assignDeep(prop) { + assignDeep.call(this, prop); + return this; + } + updateDeep(prop) { + updateDeep.call(this, prop); + return this; + } + assign(prop) { + assign.call(this, prop); + return this; + } + update(prop) { + update.call(this, prop); + return this; + } + serialize() { + return canReflect.serialize(this, Map); + } + deleteKey() { + return defineHelpers.deleteKey.apply(this, arguments); + } + forEach(cb, thisarg, observe) { + function forEach(list, cb, thisarg) { + return canReflect.eachKey(list, cb, thisarg); + } + if (observe === false) { + ObservationRecorder.ignore(forEach)(this, cb, thisarg); + } else { + return forEach(this, cb, thisarg); + } + } + static [Symbol.for('can.new')](...args) { + return new this(...args); + } + get [Symbol.for('can.isMapLike')]() { + return true; + } + get [Symbol.for('can.isListLike')]() { + return false; + } + get [Symbol.for('can.isValueLike')]() { + return false; + } + [Symbol.for('can.getKeyValue')](...args) { + return getKeyValue.apply(this, args); + } + [Symbol.for('can.deleteKeyValue')](...args) { + return defineHelpers.deleteKey.call(this, ...args); + } + [Symbol.for('can.getOwnKeys')]() { + const keys = canReflect.getOwnEnumerableKeys(this); + if (this._computed) { + const computedKeys = canReflect.getOwnKeys(this._computed); + let key; + for (let i = 0; i < computedKeys.length; i++) { + key = computedKeys[i]; + if (keys.indexOf(key) < 0) { + keys.push(key); + } + } + } + return keys; + } + [Symbol.for('can.getOwnEnumerableKeys')]() { + ObservationRecorder.add(this, 'can.keys'); + ObservationRecorder.add(Object.getPrototypeOf(this), 'can.keys'); + return keysForDefinition(this._define.definitions).concat(keysForDefinition(this._instanceDefinitions)); + } + [Symbol.for('can.serialize')](...args) { + return defineHelpers.reflectSerialize.apply(this, args); + } + [Symbol.for('can.unwrap')](...args) { + return defineHelpers.reflectUnwrap.apply(this, args); + } + [Symbol.for('can.hasKey')](key) { + return key in this._define.definitions || this._instanceDefinitions !== undefined && key in this._instanceDefinitions; + } + [Symbol.for('can.updateDeep')](...args) { + return this.updateDeep(...args); + } + }; + }; +}); +/*can-observable-mixin@1.0.10#src/mixin-proxy*/ +define('can-observable-mixin@1.0.10#src/mixin-proxy', [ + 'require', + 'exports', + 'module', + './define', + 'can-observation-recorder', + 'can-symbol', + 'can-log/dev/dev' +], function (require, exports, module) { + const defineBehavior = require('./define'); + const ObservationRecorder = require('can-observation-recorder'); + const canSymbol = require('can-symbol'); + const eventDispatcher = defineBehavior.make.set.eventDispatcher; + const inSetupSymbol = canSymbol.for('can.initializing'); + const canLogDev = require('can-log/dev/dev'); + let isProtoReadOnSuper = false; + (function () { + if (typeof Proxy === 'function') { + let par = class { + fn() { + } + }; + let base = new Proxy(par, { + get(t, k, r) { + if (k === '__proto__') { + isProtoReadOnSuper = true; + } + return Reflect.get(t, k, r); + } + }); + let chi = class extends base { + fn() { + super.fn(); + } + }; + new chi().fn(); + } + }()); + let wasLogged = false; + function logNotSupported() { + if (!wasLogged && typeof Proxy !== 'function') { + wasLogged = true; + canLogDev.warn('can-observable-mixin/mixin-proxy requires ES Proxies which are not supported by your JS runtime.'); + } + } + function proxyPrototype(Base) { + const instances = new WeakSet(); + function LateDefined() { + let inst = Reflect.construct(Base, arguments, new.target); + instances.add(inst); + return inst; + } + LateDefined.instances = instances; + const underlyingPrototypeObject = Object.create(Base.prototype); + const getHandler = isProtoReadOnSuper ? function (target, key, receiver) { + if (!this[inSetupSymbol] && typeof key !== 'symbol' && key !== '__proto__') { + ObservationRecorder.add(receiver, key); + } + return Reflect.get(target, key, receiver); + } : function (target, key, receiver) { + if (!this[inSetupSymbol] && typeof key !== 'symbol') { + ObservationRecorder.add(receiver, key); + } + return Reflect.get(target, key, receiver); + }; + const proxyHandlers = { + get: getHandler, + set(target, key, value, receiver) { + if (typeof key === 'symbol') { + Reflect.set(target, key, value, receiver); + return true; + } + if (key in target || !instances.has(receiver)) { + let current = Reflect.get(target, key, receiver); + Reflect.set(target, key, value, receiver); + eventDispatcher(receiver, key, current, value); + } else { + defineBehavior.expando(receiver, key, value); + } + return true; + } + }; + LateDefined.prototype = typeof Proxy === 'function' ? new Proxy(underlyingPrototypeObject, proxyHandlers) : underlyingPrototypeObject; + return LateDefined; + } + module.exports = proxyPrototype; +}); +/*can-observable-mixin@1.0.10#src/mixin-typeevents*/ +define('can-observable-mixin@1.0.10#src/mixin-typeevents', [ + 'require', + 'exports', + 'module', + 'can-event-queue/type/type', + 'can-event-queue/map/map' +], function (require, exports, module) { + const addTypeEvents = require('can-event-queue/type/type'); + const addMapEvents = require('can-event-queue/map/map'); + function mixinTypeEvents(Type) { + let Child = class extends Type { + }; + addTypeEvents(Child); + addMapEvents(Child); + return Child; + } + module.exports = mixinTypeEvents; +}); +/*can-observable-mixin@1.0.10#src/mixin-element*/ +define('can-observable-mixin@1.0.10#src/mixin-element', [ + 'require', + 'exports', + 'module', + './define', + './mixin-mapprops', + './mixin-proxy', + './mixin-typeevents' +], function (require, exports, module) { + const {hooks, makeDefineInstanceKey} = require('./define'); + const mixinMapProps = require('./mixin-mapprops'); + const mixinProxy = require('./mixin-proxy'); + const mixinTypeEvents = require('./mixin-typeevents'); + const constructorPropsSymbol = Symbol.for('can.constructorProps'); + const renderedSymbol = Symbol.for('can.rendered'); + module.exports = function mixinElement(BaseElement) { + let Element = class extends mixinProxy(BaseElement) { + constructor(props) { + super(); + hooks.finalizeClass(this.constructor); + this[constructorPropsSymbol] = props; + } + initialize(props) { + if (super.initialize) { + super.initialize(props); + } + hooks.initialize(this, props || this[constructorPropsSymbol]); + } + render(props) { + if (super.render) { + super.render(props); + } + hooks.initialize(this, props || this[constructorPropsSymbol]); + this[renderedSymbol] = true; + } + connectedCallback() { + if (super.connectedCallback) { + super.connectedCallback(); + } + if (!this[renderedSymbol]) { + this.render(); + } + } + }; + Element = mixinTypeEvents(mixinMapProps(Element)); + makeDefineInstanceKey(Element); + return Element; + }; +}); +/*can-observable-mixin@1.0.10#src/mixins*/ +define('can-observable-mixin@1.0.10#src/mixins', [ + 'require', + 'exports', + 'module', + './create-constructor-function', + './define', + './mixin-element', + './mixin-mapprops', + './mixin-proxy', + './mixin-typeevents' +], function (require, exports, module) { + const createConstructorFunction = require('./create-constructor-function'); + const defineBehavior = require('./define'); + const mixinElement = require('./mixin-element'); + const mixinMapProps = require('./mixin-mapprops'); + const mixinProxy = require('./mixin-proxy'); + const mixinTypeEvents = require('./mixin-typeevents'); + exports.createConstructorFunction = createConstructorFunction; + exports.makeDefineInstanceKey = defineBehavior.makeDefineInstanceKey; + exports.mixins = defineBehavior.hooks; + exports.mixinElement = mixinElement; + exports.mixinMapProps = mixinMapProps; + exports.mixinProxy = mixinProxy; + exports.mixinTypeEvents = mixinTypeEvents; +}); +/*can-stache-element@1.2.0#src/mixin-props*/ +define('can-stache-element@1.2.0#src/mixin-props', [ + 'require', + 'exports', + 'module', + 'can-observable-mixin', + 'can-reflect', + 'can-log/dev/dev' +], function (require, exports, module) { + const {mixinElement, mixins} = require('can-observable-mixin'); + const canReflect = require('can-reflect'); + const canLogDev = require('can-log/dev/dev'); + const eventTargetInstalledSymbol = Symbol.for('can.eventTargetInstalled'); + module.exports = function mixinDefine(Base = HTMLElement) { + const realAddEventListener = Base.prototype.addEventListener; + const realRemoveEventListener = Base.prototype.removeEventListener; + function installEventTarget(Type) { + if (Type[eventTargetInstalledSymbol]) { + return; + } + const eventQueueAddEventListener = Type.prototype.addEventListener; + const eventQueueRemoveEventListener = Type.prototype.removeEventListener; + Type.prototype.addEventListener = function () { + eventQueueAddEventListener.apply(this, arguments); + return realAddEventListener.apply(this, arguments); + }; + Type.prototype.removeEventListener = function () { + eventQueueRemoveEventListener.apply(this, arguments); + return realRemoveEventListener.apply(this, arguments); + }; + Type[eventTargetInstalledSymbol] = true; + } + class DefinedClass extends mixinElement(Base) { + constructor() { + super(); + installEventTarget(this.constructor); + } + initialize(props) { + super.initialize(props); + let prop, staticProps; + if (this.constructor.props) { + staticProps = Object.keys(this.constructor.props); + } + for (prop in this) { + if (this.hasOwnProperty(prop)) { + if (staticProps && staticProps.includes(prop)) { + const val = this[prop]; + delete this[prop]; + this[prop] = val; + } else { + mixins.expando(this, prop, this[prop]); + } + } + } + } + } + return DefinedClass; + }; +}); +/*can-stache-element@1.2.0#src/mixin-stache-view*/ +define('can-stache-element@1.2.0#src/mixin-stache-view', [ + 'require', + 'exports', + 'module', + 'can-stache', + 'can-stache-bindings', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-reflect', + 'can-view-scope' +], function (require, exports, module) { + 'use strict'; + const stache = require('can-stache'); + const stacheBindings = require('can-stache-bindings'); + const domMutate = require('can-dom-mutate'); + const domMutateNode = require('can-dom-mutate/node'); + const canReflect = require('can-reflect'); + const Scope = require('can-view-scope'); + const rendererSymbol = Symbol.for('can.stacheRenderer'); + const viewInsertSymbol = Symbol.for('can.viewInsert'); + stache.addBindings(stacheBindings); + module.exports = function mixinStacheView(Base = HTMLElement) { + class StacheClass extends Base { + render(props, renderOptions) { + if (super.render) { + super.render(props); + } + let renderer = this.constructor[rendererSymbol]; + if (!renderer) { + const view = this.constructor.view; + const viewName = canReflect.getName(this.constructor) + 'View'; + renderer = typeof view === 'function' ? view : stache(viewName, view || ''); + this.constructor[rendererSymbol] = renderer; + } + const frag = renderer(new Scope(this, null, { viewModel: true }), renderOptions); + const viewRoot = this.viewRoot || this; + domMutateNode.appendChild.call(viewRoot, frag); + } + connect() { + if (super.connect) { + super.connect(); + } + const removedDisposal = domMutate.onNodeRemoved(this, () => { + var doc = this.ownerDocument; + var rootNode = doc.contains ? doc : doc.documentElement; + if (!rootNode || !rootNode.contains(this)) { + removedDisposal(); + this.disconnect(); + } + }); + } + [viewInsertSymbol]() { + return this; + } + } + StacheClass.prototype[Symbol.for('can.preventDataBindings')] = true; + return StacheClass; + }; +}); +/*can-stache-element@1.2.0#src/mixin-viewmodel-symbol*/ +define('can-stache-element@1.2.0#src/mixin-viewmodel-symbol', [ + 'require', + 'exports', + 'module', + 'can-define-lazy-value' +], function (require, exports, module) { + 'use strict'; + const defineLazyValue = require('can-define-lazy-value'); + const viewModelSymbol = Symbol.for('can.viewModel'); + module.exports = function mixinViewModelSymbol(BaseClass = HTMLElement) { + class ViewModelClass extends BaseClass { + } + defineLazyValue(ViewModelClass.prototype, viewModelSymbol, function () { + return this; + }); + return ViewModelClass; + }; +}); +/*can-key@1.2.1#utils*/ +define('can-key@1.2.1#utils', function (require, exports, module) { + 'use strict'; + var utils = { + isContainer: function (current) { + var type = typeof current; + return current && (type === 'object' || type === 'function'); + }, + strReplacer: /\{([^\}]+)\}/g, + parts: function (name) { + if (Array.isArray(name)) { + return name; + } else { + return typeof name !== 'undefined' ? (name + '').replace(/\[/g, '.').replace(/]/g, '').split('.') : []; + } + } + }; + module.exports = utils; +}); +/*can-key@1.2.1#delete/delete*/ +define('can-key@1.2.1#delete/delete', [ + 'require', + 'exports', + 'module', + 'can-reflect', + '../utils' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var utils = require('../utils'); + module.exports = function deleteAtPath(data, path) { + var parts = utils.parts(path); + var current = data; + for (var i = 0; i < parts.length - 1; i++) { + if (current) { + current = canReflect.getKeyValue(current, parts[i]); + } + } + if (current) { + canReflect.deleteKeyValue(current, parts[parts.length - 1]); + } + }; +}); +/*can-key@1.2.1#get/get*/ +define('can-key@1.2.1#get/get', [ + 'require', + 'exports', + 'module', + 'can-reflect', + '../utils' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var utils = require('../utils'); + function get(obj, name) { + var parts = utils.parts(name); + var length = parts.length, current, i, container; + if (!length) { + return obj; + } + current = obj; + for (i = 0; i < length && utils.isContainer(current) && current !== null; i++) { + container = current; + current = canReflect.getKeyValue(container, parts[i]); + } + return current; + } + module.exports = get; +}); +/*can-key@1.2.1#replace-with/replace-with*/ +define('can-key@1.2.1#replace-with/replace-with', [ + 'require', + 'exports', + 'module', + '../utils', + '../get/get', + '../delete/delete' +], function (require, exports, module) { + 'use strict'; + var utils = require('../utils'); + var get = require('../get/get'); + var deleteKey = require('../delete/delete'); + module.exports = function (str, data, replacer, shouldRemoveMatchedPaths) { + return str.replace(utils.strReplacer, function (whole, path) { + var value = get(data, path); + if (shouldRemoveMatchedPaths) { + deleteKey(data, path); + } + return replacer ? replacer(path, value) : value; + }); + }; +}); +/*can-key@1.2.1#set/set*/ +define('can-key@1.2.1#set/set', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + '../utils' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var utils = require('../utils'); + var setValueSymbol = canSymbol.for('can.setValue'); + function set(object, path, value) { + var parts = utils.parts(path); + var current = object; + var length = parts.length; + for (var i = 0; i < length - 1; i++) { + if (utils.isContainer(current)) { + current = canReflect.getKeyValue(current, parts[i]); + } else { + break; + } + } + if (current) { + canReflect.setKeyValue(current, parts[i], value); + } else { + throw new TypeError('Cannot set value at key path \'' + path + '\''); + } + return object; + } + module.exports = set; +}); +/*can-key@1.2.1#walk/walk*/ +define('can-key@1.2.1#walk/walk', [ + 'require', + 'exports', + 'module', + 'can-reflect', + '../utils' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var utils = require('../utils'); + module.exports = function walk(obj, name, keyCallback) { + var parts = utils.parts(name); + var length = parts.length, current, i, container, part; + if (!length) { + return; + } + current = obj; + for (i = 0; i < length; i++) { + container = current; + part = parts[i]; + current = utils.isContainer(container) && canReflect.getKeyValue(container, part); + var result = keyCallback({ + parent: container, + key: part, + value: current + }, i); + if (result !== undefined) { + current = result; + } + } + }; +}); +/*can-key@1.2.1#transform/transform*/ +define('can-key@1.2.1#transform/transform', [ + 'require', + 'exports', + 'module', + '../walk/walk', + '../utils', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var walk = require('../walk/walk'); + var utils = require('../utils'); + var canReflect = require('can-reflect'); + function deleteKeys(parentsAndKeys) { + for (var i = parentsAndKeys.length - 1; i >= 0; i--) { + var parentAndKey = parentsAndKeys[i]; + delete parentAndKey.parent[parentAndKey.key]; + if (canReflect.size(parentAndKey.parent) !== 0) { + return; + } + } + } + module.exports = function (obj, transformer) { + var copy = canReflect.serialize(obj); + canReflect.eachKey(transformer, function (writeKey, readKey) { + var readParts = utils.parts(readKey), writeParts = utils.parts(writeKey); + var parentsAndKeys = []; + walk(copy, readParts, function (info) { + parentsAndKeys.push(info); + }); + var last = parentsAndKeys[parentsAndKeys.length - 1]; + var value = last.value; + if (value !== undefined) { + walk(copy, writeParts, function (info, i) { + if (i < writeParts.length - 1 && !info.value) { + return info.parent[info.key] = {}; + } else if (i === writeParts.length - 1) { + info.parent[info.key] = value; + } + }); + deleteKeys(parentsAndKeys); + } + }); + return copy; + }; +}); +/*can-key@1.2.1#can-key*/ +define('can-key@1.2.1#can-key', [ + 'require', + 'exports', + 'module', + 'can-key/delete/delete', + 'can-key/get/get', + 'can-key/replace-with/replace-with', + 'can-key/set/set', + 'can-key/transform/transform', + 'can-key/walk/walk', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var deleteKey = require('can-key/delete/delete'), get = require('can-key/get/get'), replaceWith = require('can-key/replace-with/replace-with'), set = require('can-key/set/set'), transform = require('can-key/transform/transform'), walk = require('can-key/walk/walk'), namespace = require('can-namespace'); + module.exports = namespace.key = { + deleteKey: deleteKey, + get: get, + replaceWith: replaceWith, + set: set, + transform: transform, + walk: walk + }; +}); +/*can-simple-observable@2.5.0#key/key*/ +define('can-simple-observable@2.5.0#key/key', [ + 'require', + 'exports', + 'module', + 'can-key', + 'can-key/utils', + 'can-reflect', + 'can-observation' +], function (require, exports, module) { + var canKey = require('can-key'); + var canKeyUtils = require('can-key/utils'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + module.exports = function keyObservable(root, keyPath) { + var keyPathParts = canKeyUtils.parts(keyPath); + var lastIndex = keyPathParts.length - 1; + var observation = new Observation(function () { + var value; + canKey.walk(root, keyPathParts, function (keyData, i) { + if (i === lastIndex) { + value = keyData.value; + } + }); + return value; + }); + var valueSetter = function (newVal) { + canKey.set(root, keyPathParts, newVal); + }; + Object.defineProperty(observation, 'value', { + get: observation.get, + set: valueSetter + }); + var symbolsToAssign = { 'can.setValue': valueSetter }; + return canReflect.assignSymbols(observation, symbolsToAssign); + }; +}); +/*can-stache-element@1.2.0#src/mixin-bindings*/ +define('can-stache-element@1.2.0#src/mixin-bindings', [ + 'require', + 'exports', + 'module', + 'can-simple-observable/key/key', + 'can-reflect', + 'can-bind' +], function (require, exports, module) { + 'use strict'; + const keyObservable = require('can-simple-observable/key/key'); + const canReflect = require('can-reflect'); + const Bind = require('can-bind'); + const getValueSymbol = Symbol.for('can.getValue'); + const setValueSymbol = Symbol.for('can.setValue'); + const metaSymbol = Symbol.for('can.meta'); + module.exports = function mixinBindings(Base = HTMLElement) { + return class BindingsClass extends Base { + bindings(bindings) { + if (this[metaSymbol] === undefined) { + this[metaSymbol] = {}; + } + const bindingsObservables = {}; + canReflect.eachKey(bindings, (parent, propName) => { + const child = keyObservable(this, propName); + bindingsObservables[propName] = { + parent, + child + }; + }); + this[metaSymbol]._connectedBindings = bindingsObservables; + return this; + } + initialize(props) { + var savedBindings = this[metaSymbol] && this[metaSymbol]._connectedBindings; + if (savedBindings) { + props = props || {}; + if (this[metaSymbol]._bindings === undefined) { + this[metaSymbol]._bindings = []; + } + canReflect.eachKey(savedBindings, (binding, propName) => { + const {child, parent} = binding; + var canGetParentValue = parent != null && !!parent[getValueSymbol]; + var canSetParentValue = parent != null && !!parent[setValueSymbol]; + if (canGetParentValue || canSetParentValue) { + var canBinding = new Bind({ + child: child, + parent: parent, + queue: 'dom', + element: this + }); + this[metaSymbol]._bindings.push({ + binding: canBinding, + siblingBindingData: { + parent: { + source: 'scope', + exports: canGetParentValue + }, + child: { + source: 'viewModel', + exports: canSetParentValue, + name: propName + }, + bindingAttributeName: propName + } + }); + } else { + props[propName] = parent; + } + }); + this[metaSymbol].other = true; + } + if (super.initialize) { + super.initialize(props); + } + } + render(props, renderOptions) { + const viewRoot = this.viewRoot || this; + viewRoot.innerHTML = ''; + if (super.render) { + super.render(props, renderOptions); + } + } + disconnect() { + delete this[metaSymbol]._bindings; + if (super.disconnect) { + super.disconnect(); + } + } + }; + }; +}); +/*can-stache-element@1.2.0#src/mixin-initialize-bindings*/ +define('can-stache-element@1.2.0#src/mixin-initialize-bindings', [ + 'require', + 'exports', + 'module', + 'can-stache-bindings' +], function (require, exports, module) { + 'use strict'; + const stacheBindings = require('can-stache-bindings'); + const metaSymbol = Symbol.for('can.meta'); + const inSetupSymbol = Symbol.for('can.initializing'); + module.exports = function mixinBindings(Base = HTMLElement) { + return class InitializeBindingsClass extends Base { + initialize(props) { + var bindings = this[metaSymbol] && this[metaSymbol]._bindings; + if (bindings && bindings.length) { + const origInSetup = this[inSetupSymbol]; + this[inSetupSymbol] = false; + const bindingContext = { element: this }; + var initializeData = stacheBindings.behaviors.initializeViewModel(bindings, props, properties => { + super.initialize(properties); + return this; + }, bindingContext); + this[metaSymbol]._connectedBindingsTeardown = function () { + for (var attrName in initializeData.onTeardowns) { + initializeData.onTeardowns[attrName](); + } + }; + this[inSetupSymbol] = origInSetup; + } else { + if (super.initialize) { + super.initialize(props); + } + } + } + disconnect() { + if (this[metaSymbol] && this[metaSymbol]._connectedBindingsTeardown) { + this[metaSymbol]._connectedBindingsTeardown(); + this[metaSymbol]._connectedBindingsTeardown = null; + } + if (super.disconnect) { + super.disconnect(); + } + } + }; + }; +}); +/*can-stache-element@1.2.0#src/mixin-bind-behaviour*/ +define('can-stache-element@1.2.0#src/mixin-bind-behaviour', [ + 'require', + 'exports', + 'module', + 'can-observable-mixin' +], function (require, exports, module) { + 'use strict'; + const {mixins} = require('can-observable-mixin'); + const metaSymbol = Symbol.for('can.meta'); + function baseAttributeChangedCallback() { + if (this.attributeChangedCallback !== baseAttributeChangedCallback) { + this.attributeChangedCallback.apply(this, arguments); + } + } + module.exports = function mixinBindBehaviour(Base = HTMLElement) { + class BindingPropsClass extends Base { + initialize(props) { + if (this[metaSymbol] === undefined) { + this[metaSymbol] = {}; + } + if (this[metaSymbol]._bindings === undefined) { + this[metaSymbol]._bindings = []; + } + Object.keys(this.constructor[metaSymbol]._uninitializedBindings).forEach(propName => { + const binding = this.constructor[metaSymbol]._uninitializedBindings[propName](this); + this[metaSymbol]._bindings.push({ + binding, + siblingBindingData: { + parent: { + source: 'scope', + exports: true + }, + child: { + source: 'viewModel', + exports: true, + name: propName + }, + bindingAttributeName: propName + } + }); + }); + if (super.initialize) { + super.initialize(props); + } + } + } + Object.defineProperty(BindingPropsClass.prototype, 'attributeChangedCallback', { + value: baseAttributeChangedCallback, + writable: true + }); + return BindingPropsClass; + }; + module.exports.initializeObservedAttributes = function initializeObservedAttributes(ctr) { + Object.defineProperty(ctr, 'observedAttributes', { + get() { + let hasBindDefinition = false; + mixins.finalizeClass(this); + if (this[metaSymbol] === undefined) { + this[metaSymbol] = {}; + } + if (this[metaSymbol]._uninitializedBindings === undefined) { + this[metaSymbol]._uninitializedBindings = {}; + } + const definitions = this.prototype._define && this.prototype._define.definitions; + if (definitions) { + Object.keys(definitions).forEach(propName => { + const definition = definitions[propName]; + if (typeof definition.bind === 'function') { + const bindFn = definition.bind(propName, this); + this[metaSymbol]._uninitializedBindings[propName] = bindFn; + hasBindDefinition = true; + } + }); + } + return hasBindDefinition ? this.observedAttributes : []; + } + }); + }; +}); +/*can-stache-element@1.2.0#src/can-stache-element*/ +define('can-stache-element@1.2.0#src/can-stache-element', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './mixin-lifecycle-methods', + './mixin-props', + './mixin-stache-view', + './mixin-viewmodel-symbol', + './mixin-bindings', + './mixin-initialize-bindings', + './mixin-bind-behaviour', + './mixin-bind-behaviour', + 'can-stache-bindings', + 'can-observable-mixin', + 'can-view-scope' +], function (require, exports, module) { + 'use strict'; + const namespace = require('can-namespace'); + const mixinLifecycleMethods = require('./mixin-lifecycle-methods'); + const mixinProps = require('./mixin-props'); + const mixinStacheView = require('./mixin-stache-view'); + const mixinViewModelSymbol = require('./mixin-viewmodel-symbol'); + const mixinBindings = require('./mixin-bindings'); + const mixinInitializeBindings = require('./mixin-initialize-bindings'); + const mixinBindBehaviour = require('./mixin-bind-behaviour'); + const {initializeObservedAttributes} = require('./mixin-bind-behaviour'); + const canStacheBindings = require('can-stache-bindings'); + const {createConstructorFunction} = require('can-observable-mixin'); + const initializeSymbol = Symbol.for('can.initialize'); + const teardownHandlersSymbol = Symbol.for('can.teardownHandlers'); + const isViewSymbol = Symbol.for('can.isView'); + const Scope = require('can-view-scope'); + function rendererWasCalledWithData(scope) { + return scope instanceof Scope && scope._parent && scope._parent._context instanceof Scope.TemplateContext; + } + function addContext(rawRenderer, tagData) { + function renderer(data) { + if (rendererWasCalledWithData(data)) { + return rawRenderer(tagData.scope.addLetContext(data._context)); + } else { + return rawRenderer(tagData.scope.addLetContext(data)); + } + } + renderer[isViewSymbol] = true; + return renderer; + } + function DeriveElement(BaseElement = HTMLElement) { + class StacheElement extends mixinLifecycleMethods(mixinBindings(mixinBindBehaviour(mixinInitializeBindings(mixinViewModelSymbol(mixinStacheView(mixinProps(BaseElement))))))) { + [initializeSymbol](el, tagData) { + const teardownBindings = canStacheBindings.behaviors.viewModel(el, tagData, function makeViewModel(initialViewmodelData) { + for (let prop in tagData.templates) { + initialViewmodelData[prop] = addContext(tagData.templates[prop], tagData); + } + el.render(initialViewmodelData); + return el; + }); + if (el[teardownHandlersSymbol]) { + el[teardownHandlersSymbol].push(teardownBindings); + } + } + } + const StacheElementConstructorFunction = createConstructorFunction(StacheElement); + initializeObservedAttributes(StacheElementConstructorFunction); + return StacheElementConstructorFunction; + } + module.exports = namespace.StacheElement = DeriveElement(); +}); +/*can-stache-element@1.2.0#test/helpers*/ +define('can-stache-element@1.2.0#test/helpers', [ + 'require', + 'exports', + 'module', + 'can-globals', + 'can-dom-mutate', + 'can-dom-mutate/node' +], function (require, exports, module) { + (function (global, require, exports, module) { + const globals = require('can-globals'); + const domMutate = require('can-dom-mutate'); + const domMutateNode = require('can-dom-mutate/node'); + const helpers = { + afterMutation: function (cb) { + var doc = globals.getKeyValue('document'); + var div = doc.createElement('div'); + var insertionDisposal = domMutate.onNodeInsertion(div, function () { + insertionDisposal(); + doc.body.removeChild(div); + setTimeout(cb, 5); + }); + setTimeout(function () { + domMutateNode.appendChild.call(doc.body, div); + }, 10); + }, + browserSupports: { + customElements: 'customElements' in window, + shadowDom: typeof document.body.attachShadow === 'function' + } + }; + module.exports = helpers; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-global@1.0.1#can-global*/ +define('can-global@1.0.1#can-global', function (require, exports, module) { + (function (global, require, exports, module) { + var GLOBAL; + module.exports = function (setGlobal) { + if (setGlobal !== undefined) { + GLOBAL = setGlobal; + } + if (GLOBAL) { + return GLOBAL; + } else { + return GLOBAL = typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope ? self : typeof process === 'object' && {}.toString.call(process) === '[object process]' ? global : window; + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-test-helpers@1.1.4#lib/dev*/ +define('can-test-helpers@1.1.4#lib/dev', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + 'can-reflect', + 'can-global' +], function (require, exports, module) { + (function (global, require, exports, module) { + var dev = require('can-log/dev/dev'); + var canReflect = require('can-reflect'); + var GLOBAL = require('can-global'); + function makeExpectation(type) { + var original; + var expectedResults = []; + function stubbed() { + var message = canReflect.toArray(arguments).map(function (token) { + if (typeof token !== 'string' && token.message) { + return token.message; + } else { + return token; + } + }).join(' '); + expectedResults.forEach(function (expected) { + var matched = typeof expected.source === 'string' ? message === expected.source : expected.source.test(message); + if (matched) { + expected.count++; + } + if (typeof expected.fn === 'function') { + expected.fn.call(null, message, matched); + } + }); + } + return function (expected, fn) { + var matchData = { + source: expected, + fn: fn, + count: 0 + }; + expectedResults.push(matchData); + if (!original) { + original = dev[type]; + dev[type] = stubbed; + } + return function () { + expectedResults.splice(expectedResults.indexOf(matchData), 1); + if (original && expectedResults.length < 1) { + dev[type] = original; + original = null; + } + return matchData.count; + }; + }; + } + module.exports = { + willWarn: makeExpectation('warn'), + willError: makeExpectation('error'), + devOnlyTest: function () { + var global = GLOBAL(); + if (!global.System || !global.System.env || global.System.env.indexOf('production') < 0) { + if (!global.test && global.QUnit) { + global.test = global.QUnit.test; + } + global.test.apply(null, arguments); + } + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-test-helpers@1.1.4#can-test-helpers*/ +define('can-test-helpers@1.1.4#can-test-helpers', [ + 'require', + 'exports', + 'module', + 'can-test-helpers/lib/dev' +], function (require, exports, module) { + var dev = require('can-test-helpers/lib/dev'); + module.exports = { dev: dev }; +}); +/*can-stache-element@1.2.0#src/can-stache-element-test*/ +define('can-stache-element@1.2.0#src/can-stache-element-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-view-scope', + 'can-view-callbacks', + 'can-stache-bindings', + 'can-stache', + 'can-simple-observable', + './can-stache-element', + 'can-type', + '../test/helpers', + 'can-reflect', + 'can-test-helpers' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const Scope = require('can-view-scope'); + const viewCallbacks = require('can-view-callbacks'); + const stacheBindings = require('can-stache-bindings'); + const stache = require('can-stache'); + const SimpleObservable = require('can-simple-observable'); + const StacheElement = require('./can-stache-element'); + const type = require('can-type'); + const browserSupports = require('../test/helpers').browserSupports; + const canReflect = require('can-reflect'); + const dev = require('can-test-helpers').dev; + QUnit.module('can-stache-element'); + if (browserSupports.customElements) { + QUnit.test('basics', function (assert) { + const fixture = document.querySelector('#qunit-fixture'); + class Input extends StacheElement { + static get view() { + return `

      `; + } + handleChange(val) { + this.handler(val); + } + } + customElements.define('in-put', Input); + class Basic extends StacheElement { + static get view() { + return ` + + +

      {{this.fullName}}

      + `; + } + static get props() { + return { + first: { + type: String, + default: 'Kevin' + }, + last: { + type: String, + default: 'McCallister' + } + }; + } + get fullName() { + return `${ this.first } ${ this.last }`; + } + setFirst(val) { + this.first = val; + } + setLast(val) { + this.last = val; + } + } + customElements.define('basic-app', Basic); + const el = document.createElement('basic-app'); + fixture.appendChild(el); + const inputs = el.querySelectorAll('input'); + const firstNameInput = inputs[0]; + const lastNameInput = inputs[1]; + const fullNameP = el.querySelectorAll('p')[2]; + assert.equal(firstNameInput.value, 'Kevin', 'firstName input has correct default value'); + assert.equal(lastNameInput.value, 'McCallister', 'lastName input has correct default value'); + assert.equal(fullNameP.innerHTML, 'Kevin McCallister', 'fullName paragraph has correct default value'); + firstNameInput.value = 'Marty'; + firstNameInput.dispatchEvent(new Event('change')); + assert.equal(fullNameP.innerHTML, 'Marty McCallister', 'fullName paragraph changes when firstName input changes'); + lastNameInput.value = 'McFly'; + lastNameInput.dispatchEvent(new Event('change')); + assert.equal(fullNameP.innerHTML, 'Marty McFly', 'fullName paragraph changes when lastName input changes'); + }); + QUnit.test('can be rendered by canViewCallbacks.tagHandler', function (assert) { + class App extends StacheElement { + static get view() { + return 'Hello {{greeting}}'; + } + } + customElements.define('stache-viewcallbacks-app', App); + const el = document.createElement('stache-viewcallbacks-app'); + el.setAttribute('greeting:bind', 'greeting'); + const scope = new Scope({ greeting: 'World' }); + viewCallbacks.tagHandler(el, 'stache-viewcallbacks-app', { scope: scope }); + assert.equal(el.innerHTML, 'Hello World'); + }); + QUnit.test('Can initialize with el.initialize()', function (assert) { + class El extends StacheElement { + static get props() { + return { prop: 'default' }; + } + } + customElements.define('stache-element-initialized', El); + const el = new El(); + el.initialize({ prop: 'value' }); + assert.equal(el.prop, 'value', 'initialized with values provided to initialize'); + }); + QUnit.test('programatically instantiated elements get disconnected when removed', function (assert) { + let done = assert.async(); + class Person extends StacheElement { + static get view() { + return ` +

      person

      + `; + } + disconnected() { + assert.ok(true, 'connected'); + done(); + } + } + customElements.define('per-son', Person); + class App extends StacheElement { + static get view() { + return ` +

      + {{#if(person)}} + {{{person}}} + {{/if}} +

      + `; + } + static get props() { + return { + showPerson: true, + person: { + get() { + if (this.showPerson) { + let person = new Person(); + person.connect(); + return person; + } + } + } + }; + } + } + customElements.define('person-app', App); + let app = new App(); + app.connect(); + const nameDiv = app.querySelector('per-son p'); + assert.equal(nameDiv.innerHTML, 'person'); + app.showPerson = false; + }); + QUnit.test('element can be used directly in a stache view', function (assert) { + const fixture = document.querySelector('#qunit-fixture'); + assert.expect(2); + const done = assert.async(); + const show = new SimpleObservable(false); + class El extends StacheElement { + connected() { + assert.ok(true, 'connected'); + } + disconnected() { + assert.ok(true, 'disconnected'); + done(); + } + } + customElements.define('stache-el-in-stache', El); + const el = new El(); + const frag = stache(` +
      + {{#if(show)}} + {{el}} + {{/if}} +
      + `)({ + el, + show + }); + show.value = true; + fixture.appendChild(frag); + show.value = false; + }); + QUnit.test('addEventListener and removeEventListener work for DOM events', function (assert) { + const done = assert.async(); + class El extends StacheElement { + } + customElements.define('add-event-listener-el', El); + const el = new El(); + el.addEventListener('an-event', function handler() { + el.removeEventListener('an-event', handler); + el.dispatchEvent(new Event('an-event')); + assert.ok(true, 'addEventListener works'); + done(); + }); + el.dispatchEvent(new Event('an-event')); + }); + QUnit.test('value() updates', function (assert) { + class Foo extends StacheElement { + static get view() { + return '{{second}}'; + } + static get props() { + return { + first: 'one', + second: { + value({listenTo, resolve}) { + resolve(this.first); + listenTo('first', (ev, val) => { + resolve(val); + }); + } + } + }; + } + } + customElements.define('value-should-update', Foo); + let updated = false; + let foo = new Foo(); + foo.connect(); + canReflect.onKeyValue(foo, 'second', () => { + updated = true; + }); + assert.equal(foo.second, 'one', 'initial value'); + foo.first = 'two'; + assert.ok(updated, 'onKeyValue called'); + assert.equal(foo.second, 'two', 'updated'); + let foo2 = new Foo(); + foo2.connect(); + updated = false; + canReflect.onKeyValue(foo2, 'second', () => { + updated = true; + }); + assert.equal(foo2.second, 'one', 'initial value'); + foo2.first = 'two'; + assert.ok(updated, 'onKeyValue called'); + assert.equal(foo2.second, 'two', 'updated'); + }); + dev.devOnlyTest('Warns when a property matches an event name', function (assert) { + class ClickPropEl extends StacheElement { + static get props() { + return { + click: String, + get other() { + throw new Error('Don\'t get me'); + } + }; + } + } + customElements.define('click-prop-should-warn', ClickPropEl); + let undo = dev.willWarn(/click/); + new ClickPropEl(); + assert.equal(undo(), 1, 'Warned for the \'click\' prop'); + }); + dev.devOnlyTest('Warns when a property matches a built in property', function (assert) { + class ClickPropEl extends StacheElement { + static get props() { + return { + tagName: String, + get other() { + throw new Error('Don\'t get me'); + } + }; + } + } + customElements.define('tag-name-prop-should-warn', ClickPropEl); + let undo = dev.willWarn(/tagName/); + new ClickPropEl(); + assert.equal(undo(), 1, 'Warned for the \'tagName\' prop'); + }); + QUnit.test('bindings run once (#72)', function (assert) { + class CreateBindingsOnce extends StacheElement { + static get props() { + return { value: Number }; + } + } + customElements.define('create-bindings-once', CreateBindingsOnce); + var calls = 0; + stache('')({ + read() { + calls++; + return 1; + } + }); + assert.equal(calls, 1, 'only called once'); + }); + QUnit.test('initializeViewModel called once for elements rendered with stache', function (assert) { + const origInitializeViewModel = stacheBindings.behaviors.initializeViewModel; + let calls = 0; + stacheBindings.behaviors.initializeViewModel = function () { + calls++; + return origInitializeViewModel.apply(this, arguments); + }; + class InitializeViewModelOnce extends StacheElement { + static get props() { + return { num: type.convert(Number) }; + } + } + customElements.define('initialize-viewmodel-once', InitializeViewModelOnce); + const frag = stache('')({}); + document.querySelector('#qunit-fixture').appendChild(frag); + assert.equal(calls, 1, 'only called once'); + }); + QUnit.test('initializeViewModel not called if there are no bindings', function (assert) { + const origInitializeViewModel = stacheBindings.behaviors.initializeViewModel; + let calls = 0; + stacheBindings.behaviors.initializeViewModel = function () { + calls++; + return origInitializeViewModel.apply(this, arguments); + }; + class InitializeViewModelZeroTimes extends StacheElement { + static get props() { + return { num: type.convert(Number) }; + } + } + customElements.define('initialize-viewmodel-zero-times', InitializeViewModelZeroTimes); + new InitializeViewModelZeroTimes().initialize(); + assert.equal(calls, 0, 'initializeViewModel not called'); + }); + QUnit.test('can-template support (#77)', function (assert) { + class CanGetTemplates extends StacheElement { + static get view() { + return stache('can-get-templates.stache', '{{this.foo( passed=\'PASSED\' )}}'); + } + static get props() { + return { inner: 'INNER' }; + } + } + customElements.define('can-get-templates', CanGetTemplates); + var template = stache('outer.stache', '{{let letScope=\'LETSCOPE\'}}' + '' + '' + '
      {{this.outer}}
      ' + '
      {{letScope}}
      ' + '
      {{passed}}
      ' + '
      ' + '
      '); + var frag = template({ outer: 'OUTER' }); + assert.equal(frag.firstElementChild.querySelector('.outer').innerHTML, 'OUTER', 'Access OUTER scope'); + assert.equal(frag.firstElementChild.querySelector('.let-scope').innerHTML, 'LETSCOPE', 'Access let scope scope'); + assert.equal(frag.firstElementChild.querySelector('.passed').innerHTML, 'PASSED', 'Access passed scope'); + }); + QUnit.test('can-template called outside stache works (#77)', function (assert) { + class CanGetTemplatesInCode extends StacheElement { + static get view() { + return `{{ this.bar() }}`; + } + static get props() { + return { inner: 'INNER' }; + } + bar() { + return this.foo({ passed: 'PASSED' }); + } + } + customElements.define('can-get-templates-in-code', CanGetTemplatesInCode); + var template = stache('outer.stache', `{{ let letScope="LETSCOPE" }} + + +
      {{ this.outer }}
      +
      {{ letScope }}
      +
      {{ passed }}
      +
      +
      `); + var frag = template({ outer: 'OUTER' }); + assert.equal(frag.firstElementChild.querySelector('.outer').innerHTML, 'OUTER', 'Access OUTER scope'); + assert.equal(frag.firstElementChild.querySelector('.let-scope').innerHTML, 'LETSCOPE', 'Access let scope scope'); + assert.equal(frag.firstElementChild.querySelector('.passed').innerHTML, 'PASSED', 'Access passed scope'); + }); + } +}); +/*can-stache-element@1.2.0#src/mixin-props-test*/ +define('can-stache-element@1.2.0#src/mixin-props-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './mixin-props', + 'can-type' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const mixinDefine = require('./mixin-props'); + const type = require('can-type'); + QUnit.module('can-stache-element - mixin-props'); + QUnit.test('basics', function (assert) { + class DefineElement extends mixinDefine(Object) { + static get props() { + return { + age: { + type: type.convert(Number), + default: 32 + } + }; + } + } + const el = new DefineElement(); + el.initialize(); + assert.equal(el.age, 32, 'default age'); + el.age = '33'; + assert.equal(el.age, 33, 'updated age'); + }); +}); +/*can-stache-element@1.2.0#src/mixin-lifecycle-methods-test*/ +define('can-stache-element@1.2.0#src/mixin-lifecycle-methods-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './mixin-lifecycle-methods', + '../test/helpers' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const mixinLifecycleMethods = require('./mixin-lifecycle-methods'); + const browserSupports = require('../test/helpers').browserSupports; + const inSetupSymbol = Symbol.for('can.initializing'); + QUnit.module('can-stache-element - mixin-lifecycle-methods'); + QUnit.test('connectedCallback calls hooks - initialize, render, connect', function (assert) { + assert.expect(3); + class Obj { + initialize() { + assert.ok(true, 'initialize called'); + } + render() { + assert.ok(true, 'render called'); + } + connect() { + assert.ok(true, 'connect called'); + } + } + const LifecycleObj = mixinLifecycleMethods(Obj); + const obj = new LifecycleObj(); + obj.connectedCallback(); + }); + QUnit.test('disconnectedCallback calls disconnect, teardown returned by connected, and stopListening', function (assert) { + assert.expect(3); + let obj; + class Obj { + connected() { + return function () { + assert.ok(true, 'teardown handler returned from `connect` is called'); + }; + } + disconnect() { + assert.ok(true, 'disconnect called'); + } + stopListening() { + assert.ok(true, 'stopListening called'); + } + } + const LifecycleObj = mixinLifecycleMethods(Obj); + obj = new LifecycleObj(); + obj.connectedCallback(); + obj.disconnectedCallback(); + }); + if (browserSupports.customElements) { + QUnit.test('lifecycle works with document.createElement', function (assert) { + assert.expect(4); + const fixture = document.querySelector('#qunit-fixture'); + class Obj extends HTMLElement { + initialize() { + assert.ok(true, 'initialize called'); + } + render() { + assert.ok(true, 'render called'); + } + connect() { + assert.ok(true, 'connect called'); + } + disconnect() { + assert.ok(true, 'disconnect called'); + } + } + const LifecycleObj = mixinLifecycleMethods(Obj); + customElements.define('created-el', LifecycleObj); + const el = document.createElement('created-el'); + fixture.appendChild(el); + fixture.removeChild(el); + }); + } + QUnit.test('events are not dispatched in initialize, are dispatched during render|connect', function (assert) { + assert.expect(3); + class Obj extends mixinLifecycleMethods(Object) { + initialize() { + assert.equal(this[inSetupSymbol], true, 'inSetupSymbol is true during initialize'); + super.initialize(); + } + render() { + assert.equal(this[inSetupSymbol], false, 'inSetupSymbol is false during render'); + super.render(); + } + connect() { + assert.equal(this[inSetupSymbol], false, 'inSetupSymbol is false during connect'); + } + } + const obj = new Obj(); + obj.connectedCallback(); + }); + QUnit.test('events are not dispatched in initialize, are dispatched during render|connect when methods are called directly', function (assert) { + assert.expect(3); + class Obj extends mixinLifecycleMethods(Object) { + initialize() { + assert.equal(this[inSetupSymbol], true, 'inSetupSymbol is true during initialize'); + super.initialize(); + } + render() { + assert.equal(this[inSetupSymbol], false, 'inSetupSymbol is false during render'); + super.render(); + } + connect() { + assert.equal(this[inSetupSymbol], false, 'inSetupSymbol is false during connect'); + } + } + const obj = new Obj(); + obj.initialize(); + obj.render(); + obj.connect(); + }); + QUnit.test('initialize, render, and connect are only called the first time connectedCallback is called', function (assert) { + assert.expect(3); + class Obj { + initialize() { + assert.ok(true, 'initialize'); + } + render() { + assert.ok(true, 'render'); + } + connect() { + assert.ok(true, 'connect'); + } + } + const LifecycleObj = mixinLifecycleMethods(Obj); + const obj = new LifecycleObj(); + obj.connectedCallback(); + obj.connectedCallback(); + }); + QUnit.test('disconnect is only called the first time disconnectedCallback is called', function (assert) { + assert.expect(1); + class Obj { + disconnect() { + assert.ok(true, 'connect'); + } + } + const LifecycleObj = mixinLifecycleMethods(Obj); + const obj = new LifecycleObj(); + obj.disconnectedCallback(); + obj.disconnectedCallback(); + }); + QUnit.test('render calls initialize if it was not called', function (assert) { + assert.expect(2); + class Obj extends mixinLifecycleMethods(Object) { + initialize() { + super.initialize(); + assert.ok(true, 'initialize'); + } + render() { + super.render(); + assert.ok(true, 'render'); + } + } + const obj = new Obj(); + obj.render(); + }); + QUnit.test('constructor throws if passed arguments', function (assert) { + class Obj extends mixinLifecycleMethods(Object) { + } + try { + new Obj({ foo: 'bar' }); + } catch (e) { + assert.ok(true); + } + }); + QUnit.test('initial props should always be passed to initialize', function (assert) { + assert.expect(4); + const props = { + foo: 'bar', + baz: 'bap' + }; + class Obj extends mixinLifecycleMethods(Object) { + initialize(initializeProps) { + super.initialize(); + assert.equal(initializeProps, props, 'Correct props passed to initialize'); + } + } + const initializeObj = new Obj(); + initializeObj.initialize(props); + const renderObj = new Obj(); + renderObj.render(props); + const connectObj = new Obj(); + connectObj.connect(props); + const connectedCallbackObj = new Obj(); + connectedCallbackObj.connectedCallback(props); + }); + QUnit.test('connect calls `connected` hook', function (assert) { + assert.expect(1); + class Obj extends mixinLifecycleMethods(Object) { + connected() { + assert.ok(true, 'connected hook called'); + } + } + const obj = new Obj(); + obj.connect(); + }); + QUnit.test('disconnect calls `disconnected` hook', function (assert) { + assert.expect(1); + class Obj extends mixinLifecycleMethods(Object) { + disconnected() { + assert.ok(true, 'disconnected hook called'); + } + } + const obj = new Obj(); + obj.disconnect(); + }); + QUnit.test('lifecycle methods return the obj', function (assert) { + class Obj extends mixinLifecycleMethods(Object) { + } + let obj = new Obj().connectedCallback().disconnectedCallback(); + assert.ok(obj instanceof Obj, 'connectedCallback and disconnectedCallback'); + obj = new Obj().initialize().render().connect().disconnect(); + assert.ok(obj instanceof Obj, 'initialize, render, connect, disconnect'); + obj = new Obj().initialize().initialize().render().render().connect().connect().disconnect().disconnect(); + assert.ok(obj instanceof Obj, 'initialize, render, connect, disconnect called twice'); + }); + QUnit.test('connect and disconnect always toggle each other', function (assert) { + assert.expect(4); + class Sup { + connect() { + assert.ok(true, 'connect'); + } + disconnect() { + assert.ok(true, 'disconnect'); + } + } + class Obj extends mixinLifecycleMethods(Sup) { + } + const obj = new Obj(); + obj.connect().disconnect().connect().disconnect(); + }); +}); +/*can-stache-element@1.2.0#src/mixin-stache-view-test*/ +define('can-stache-element@1.2.0#src/mixin-stache-view-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-stache', + './mixin-stache-view', + '../test/helpers' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const stache = require('can-stache'); + const mixinStacheView = require('./mixin-stache-view'); + const browserSupports = require('../test/helpers').browserSupports; + QUnit.module('can-stache-element - mixin-stache-view'); + if (browserSupports.customElements) { + QUnit.test('basics', function (assert) { + class StacheElement extends mixinStacheView(HTMLElement) { + } + class App extends StacheElement { + static get view() { + return '{{greeting}} World'; + } + constructor() { + super(); + this.greeting = 'Hello'; + } + } + customElements.define('stache-app', App); + const app = new App(); + assert.equal(typeof app.render, 'function', 'mixin adds a render method on class instances'); + app.render(); + assert.equal(app.innerHTML, 'Hello World', 'render method renders the static `view` property as stache'); + }); + if (browserSupports.shadowDOM) { + QUnit.test('can render into shadowDOM', function (assert) { + class StacheElement extends mixinStacheView(HTMLElement) { + } + class App extends StacheElement { + static get view() { + return '{{greeting}} World'; + } + constructor() { + super(); + this.viewRoot = this.attachShadow({ mode: 'open' }); + this.greeting = 'Hello'; + } + } + customElements.define('stache-shadow-dom-app', App); + const app = new App(); + assert.equal(typeof app.render, 'function', 'mixin adds a render method on class instances'); + app.render(); + assert.equal(app.shadowRoot.innerHTML, 'Hello World', 'render method renders the static `view` property as stache'); + }); + } + QUnit.test('caches renderer function', function (assert) { + assert.expect(3); + class App extends mixinStacheView(HTMLElement) { + static get view() { + assert.ok(true, 'view property read'); + return '{{greeting}} World'; + } + constructor() { + super(); + this.greeting = 'Hello'; + } + } + customElements.define('stache-caches-view-app', App); + const app = new App(); + app.render(); + assert.equal(app.innerHTML, 'Hello World', 'renders first app'); + const app2 = new App(); + app2.render(); + assert.equal(app2.innerHTML, 'Hello World', 'renders second app'); + }); + QUnit.test('can be passed a renderer function as the view', function (assert) { + const renderer = stache('{{greeting}} World'); + class App extends mixinStacheView(HTMLElement) { + static get view() { + return renderer; + } + constructor() { + super(); + this.greeting = 'Hello'; + } + } + customElements.define('stache-renderer-app', App); + const app = new App(); + app.render(); + assert.equal(app.innerHTML, 'Hello World', 'render method renders the static `view` property as stache'); + }); + QUnit.test('element works without a `view`', function (assert) { + class App extends mixinStacheView(HTMLElement) { + } + customElements.define('stache-no-renderer-app', App); + const app = new App(); + app.render({}); + assert.ok(true, 'doesn\'t throw'); + }); + QUnit.test('supports `scope.vm` lookups in the view', function (assert) { + class StacheElement extends mixinStacheView(HTMLElement) { + } + class App extends StacheElement { + static get view() { + return '{{ scope.vm.greeting }} World'; + } + constructor() { + super(); + this.greeting = 'Hello'; + } + } + customElements.define('stache-scope-vm', App); + const app = new App(); + assert.equal(typeof app.render, 'function', 'mixin adds a render method on class instances'); + app.render(); + assert.equal(app.innerHTML, 'Hello World', 'render method renders the static `view` property as stache'); + }); + } +}); +/*can-stache-element@1.2.0#src/mixin-viewmodel-symbol-test*/ +define('can-stache-element@1.2.0#src/mixin-viewmodel-symbol-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './mixin-viewmodel-symbol' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const mixinViewModelSymbol = require('./mixin-viewmodel-symbol'); + const viewModelSymbol = Symbol.for('can.viewModel'); + QUnit.module('can-stache-element - mixin-viewmodel-symbol'); + QUnit.test('basics', function (assert) { + class App extends mixinViewModelSymbol(class A { + }) { + } + const app = new App(); + assert.equal(app[viewModelSymbol], app, 'instances get assigned viewModel Symbol'); + }); +}); +/*can-stache-element@1.2.0#src/import-export-steal-test*/ +define('can-stache-element@1.2.0#src/import-export-steal-test', [ + 'steal-qunit@2.0.0#steal-qunit', + 'can-stache-element@1.2.0#src/can-stache-element', + 'can-stache-element@1.2.0#test/helpers' +], function (_stealQunit, _canStacheElement, _helpers) { + 'use strict'; + var _stealQunit2 = _interopRequireDefault(_stealQunit); + var _canStacheElement2 = _interopRequireDefault(_canStacheElement); + var _helpers2 = _interopRequireDefault(_helpers); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) + descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + return function (Constructor, protoProps, staticProps) { + if (protoProps) + defineProperties(Constructor.prototype, protoProps); + if (staticProps) + defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } + } + function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError('this hasn\'t been initialised - super() hasn\'t been called'); + } + return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === 'object' || typeof call === 'function') ? call : self; + } + function _inherits(subClass, superClass) { + if (typeof superClass !== 'function' && superClass !== null) { + throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass))); + } + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) + Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } + var browserSupports = _helpers2.default.browserSupports; + _stealQunit2.default.module('can-stache-element - import/export syntax in steal'); + if (browserSupports.customElements) { + _stealQunit2.default.test('Works when import/export syntax is transpiled by steal to ES5 constructor functions', function (assert) { + var tag = 'import-export-steal'; + var MyElement = function (_StacheElement) { + _inherits(MyElement, _StacheElement); + function MyElement() { + _classCallCheck(this, MyElement); + return _possibleConstructorReturn(this, (MyElement.__proto__ || Object.getPrototypeOf(MyElement)).apply(this, arguments)); + } + _createClass(MyElement, null, [{ + key: 'view', + get: function get() { + return 'Hello world'; + } + }]); + return MyElement; + }(_canStacheElement2.default); + customElements.define(tag, MyElement); + var el = document.createElement(tag); + el.connect(); + assert.equal(el.textContent, 'Hello world', 'rendered successfully'); + }); + } +}); +/*can-value@1.1.2#can-value*/ +define('can-value@1.1.2#can-value', [ + 'require', + 'exports', + 'module', + 'can-key', + 'can-reflect', + 'can-simple-observable/key/key', + 'can-namespace', + 'can-observation', + 'can-simple-observable', + 'can-simple-observable/settable/settable' +], function (require, exports, module) { + 'use strict'; + var canKey = require('can-key'); + var canReflect = require('can-reflect'); + var keyObservable = require('can-simple-observable/key/key'); + var namespace = require('can-namespace'); + var Observation = require('can-observation'); + var SimpleObservable = require('can-simple-observable'); + var SettableObservable = require('can-simple-observable/settable/settable'); + module.exports = namespace.value = { + bind: function (object, keyPath) { + return keyObservable(object, keyPath); + }, + from: function (object, keyPath) { + var observationFunction = function () { + return canKey.get(object, keyPath); + }; + return new Observation(observationFunction); + }, + returnedBy: function (getter, context, initialValue) { + if (getter.length === 1) { + return new SettableObservable(getter, context, initialValue); + } else { + return new Observation(getter, context); + } + }, + to: function (object, keyPath) { + var observable = keyObservable(object, keyPath); + var symbolsToAssign = { 'can.getValue': null }; + return canReflect.assignSymbols(observable, symbolsToAssign); + }, + with: function (initialValue) { + return new SimpleObservable(initialValue); + } + }; +}); +/*can-stache-element@1.2.0#src/mixin-bindings-test*/ +define('can-stache-element@1.2.0#src/mixin-bindings-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './can-stache-element', + 'can-value', + 'can-simple-observable', + '../test/helpers', + 'can-reflect' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const StacheElement = require('./can-stache-element'); + const value = require('can-value'); + const SimpleObservable = require('can-simple-observable'); + const testHelpers = require('../test/helpers'); + const browserSupports = testHelpers.browserSupports; + const canReflect = require('can-reflect'); + let fixture; + QUnit.module('can-stache-element - mixin-bindings', { + beforeEach() { + fixture = document.querySelector('#qunit-fixture'); + } + }); + if (browserSupports.customElements) { + QUnit.test('basics work', function (assert) { + const done = assert.async(); + class BasicBindingsElement extends StacheElement { + static get view() { + return `

      {{message}}

      `; + } + static get props() { + return { + message: { + type: String, + default: 'Hi' + } + }; + } + } + customElements.define('basic-bindings', BasicBindingsElement); + var basicBindingsElement = new BasicBindingsElement(); + var messageObservable = value.with('Hello'); + basicBindingsElement.bindings({ message: messageObservable }); + assert.equal(basicBindingsElement.message, 'Hi', 'properties initialized later'); + fixture.appendChild(basicBindingsElement); + testHelpers.afterMutation(() => { + assert.equal(basicBindingsElement.message, 'Hello', 'properties initialized'); + assert.equal(basicBindingsElement.innerHTML, '

      Hello

      ', 'template rendered'); + messageObservable.value = 'HOWDY'; + assert.equal(basicBindingsElement.message, 'HOWDY', 'element property value changed'); + assert.equal(basicBindingsElement.innerHTML, '

      HOWDY

      ', 'html updated'); + testHelpers.afterMutation(() => { + basicBindingsElement.message = 'Hola!'; + assert.equal(messageObservable.value, 'Hola!', 'observable updated via two-way binding'); + fixture.removeChild(basicBindingsElement); + testHelpers.afterMutation(() => { + assert.equal(canReflect.isBound(messageObservable), false, 'the observable is not bound'); + assert.equal(canReflect.isBound(basicBindingsElement), false, 'the element is not bound'); + messageObservable.value = 'GOODBYE'; + fixture.appendChild(basicBindingsElement); + testHelpers.afterMutation(() => { + assert.equal(basicBindingsElement.message, 'GOODBYE', 'properties initialized after re-insertion'); + assert.equal(basicBindingsElement.innerHTML, '

      GOODBYE

      ', 'template rendered'); + done(); + }); + }); + }); + }); + }); + QUnit.test('Everything is properly torn down', function (assert) { + let done = assert.async(); + let oneId = 0, twoId = 0; + class One extends StacheElement { + static get view() { + return ` + {{this.setId(id)}} +

      {{id}}

      + `; + } + static get props() { + return { id: Number }; + } + setId(val) { + oneId = val; + } + } + customElements.define('o-ne', One); + class Two extends StacheElement { + static get view() { + return ` + {{this.setId(id)}} +

      {{id}}

      + `; + } + static get props() { + return { id: Number }; + } + setId(val) { + twoId = val; + } + } + customElements.define('t-wo', Two); + class App extends StacheElement { + static get view() { + return ` +

      + {{#if(elementPromise.isResolved)}} + {{{element}}} + {{/if}} +

      + + + `; + } + static get props() { + return { + id: 1, + elementPromise: { + get() { + return new Promise(resolve => { + let child = this.id === 1 ? new One() : new Two(); + child.bindings({ id: value.from(this, 'id') }); + child.connect(); + resolve(child); + }); + } + }, + element: { + async(resolve) { + this.elementPromise.then(resolve); + } + } + }; + } + increment() { + this.id++; + } + } + customElements.define('a-pp', App); + let app = new App(); + app.connect(); + app.on('element', function onFirst() { + app.off('element', onFirst); + app.on('element', function onSecond() { + app.off('element', onSecond); + assert.equal(oneId, 1, ' Has its original id'); + assert.equal(twoId, 2, ' Has its own id'); + done(); + }); + let oneEl = app.querySelector('o-ne'); + app.increment(); + assert.equal(oneEl.querySelector('#oneid').textContent, '1', ' Has not changed'); + }); + }); + QUnit.test('All bindings are torn down', function (assert) { + class BindingsTeardownElement extends StacheElement { + static get view() { + return `

      {{greeting}} {{object}}

      `; + } + static get props() { + return { + greeting: { + type: String, + default: 'Hi' + }, + object: { + type: String, + default: 'person' + } + }; + } + } + customElements.define('bindings-teardown-element', BindingsTeardownElement); + var teardownElement = new BindingsTeardownElement(); + var greetingObservable = value.with('Hello'); + var objectObservable = value.with('world'); + teardownElement.bindings({ + greeting: greetingObservable, + object: objectObservable + }); + teardownElement.connect(); + const h1 = teardownElement.firstElementChild; + assert.equal(teardownElement.greeting, 'Hello', 'greetingObservable set up correctly'); + assert.equal(teardownElement.object, 'world', 'objectObservable set up correctly'); + assert.equal(h1.innerHTML, 'Hello world', 'view rendered'); + teardownElement.disconnect(); + greetingObservable.value = 'Howdy'; + objectObservable.value = 'Mars'; + assert.equal(teardownElement.greeting, 'Hello', 'greetingObservable torn down correctly'); + assert.equal(teardownElement.object, 'world', 'objectObservable torn down correctly'); + assert.equal(h1.innerHTML, 'Hello world', 'view not updated'); + }); + QUnit.test('Lifecycle methods return the element', function (assert) { + class BindingsMethodsElement extends StacheElement { + } + customElements.define('bindings-methods-element', BindingsMethodsElement); + let obj = new BindingsMethodsElement().bindings().initialize().render().connect().disconnect(); + assert.ok(obj instanceof BindingsMethodsElement, 'initialize, render, connect, disconnect'); + }); + QUnit.test('bindings work after being torn down and re-initialized', function (assert) { + class ReInitializeBindingsEl extends StacheElement { + static get view() { + return ` +

      Child {{ this.show }}

      + `; + } + static get props() { + return { show: false }; + } + } + customElements.define('reinitialize-bindings-el', ReInitializeBindingsEl); + const parent = new SimpleObservable(true); + const el = new ReInitializeBindingsEl().bindings({ show: parent }).connect(); + assert.equal(el.show, true, 'el.show === true by default'); + el.show = false; + assert.equal(el.show, false, 'el.show toggled to false'); + assert.equal(parent.value, false, 'parent.value changed to false'); + parent.value = true; + assert.equal(el.show, true, 'el.show toggled to true'); + assert.equal(parent.value, true, 'parent.value changed to true'); + el.disconnect().connect(); + el.show = false; + assert.equal(el.show, false, 'el.show toggled to false again'); + assert.equal(parent.value, false, 'parent.value changed to false again'); + }); + } +}); +/*can-stache-element@1.2.0#src/mixin-initialize-bindings-test*/ +define('can-stache-element@1.2.0#src/mixin-initialize-bindings-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './mixin-initialize-bindings' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const mixinInitializeBindings = require('./mixin-initialize-bindings'); + QUnit.module('can-stache-element - mixin-initialize-bindings'); + QUnit.test('disconnect calls super disconnect', function (assert) { + assert.expect(1); + class Obj { + disconnect() { + assert.ok(true, 'disconnect called'); + } + } + const InitializeBindingObj = mixinInitializeBindings(Obj); + const obj = new InitializeBindingObj(); + obj.disconnect(); + }); + QUnit.test('initialize calls super initialize', function (assert) { + assert.expect(1); + const props = { name: 'Matt' }; + class Obj { + initialize(_props) { + assert.equal(_props, props, 'initialize called'); + } + } + const InitializeBindingObj = mixinInitializeBindings(Obj); + const obj = new InitializeBindingObj(); + obj.initialize(props); + }); +}); +/*can-observable-bindings@1.3.3#from-attribute*/ +define('can-observable-bindings@1.3.3#from-attribute', [ + 'require', + 'exports', + 'module', + 'can-value', + 'can-bind', + 'can-reflect', + 'can-string', + 'can-type' +], function (require, exports, module) { + const value = require('can-value'); + const Bind = require('can-bind'); + const canReflect = require('can-reflect'); + const canString = require('can-string'); + const type = require('can-type'); + const metaSymbol = Symbol.for('can.meta'); + function isJSONLike(obj) { + return canReflect.isFunctionLike(obj.parse) && canReflect.isFunctionLike(obj.stringify); + } + function initializeFromAttribute(propertyName, ctr, converter, attributeName) { + if (ctr[metaSymbol] === undefined) { + ctr[metaSymbol] = {}; + } + if (ctr[metaSymbol]._observedAttributes === undefined) { + ctr[metaSymbol]._observedAttributes = []; + } + if (ctr[metaSymbol]._attributeChangedCallbackHandler === undefined) { + ctr[metaSymbol]._attributeChangedCallbackHandler = {}; + } + if (attributeName === undefined) { + attributeName = propertyName; + } + attributeName = canString.hyphenate(attributeName); + if (!ctr[metaSymbol]._hasInitializedAttributeBindings) { + Object.defineProperty(ctr, 'observedAttributes', { + get() { + return ctr[metaSymbol]._observedAttributes; + } + }); + ctr.prototype.attributeChangedCallback = function (prop) { + ctr[metaSymbol]._attributeChangedCallbackHandler[prop].apply(this, arguments); + }; + ctr[metaSymbol]._hasInitializedAttributeBindings = true; + } + ctr[metaSymbol]._observedAttributes.push(attributeName); + ctr[metaSymbol]._attributeChangedCallbackHandler[attributeName] = function (prop, oldVal, newVal) { + if (this[metaSymbol] && this[metaSymbol]._attributeBindings && newVal !== oldVal) { + canReflect.setValue(this[metaSymbol]._attributeBindings[prop], newVal); + } + }; + var lazyGetType = function () { + var Type; + var schema = canReflect.getSchema(ctr); + if (schema) { + Type = schema.keys[propertyName]; + } + if (!Type) { + Type = type.Any; + } + Type = type.convert(Type); + lazyGetType = function () { + return Type; + }; + return Type; + }; + function convertToValue(value) { + if (converter) { + value = converter.parse(value); + } + return canReflect.convert(value, lazyGetType()); + } + return function fromAttributeBind(instance) { + const childValue = value.to(instance, propertyName); + const intermediateValue = {}; + canReflect.assignSymbols(intermediateValue, { + 'can.setValue': function (value) { + canReflect.setValue(childValue, convertToValue(value)); + } + }); + const parentValue = value.from(instance.hasAttribute(attributeName) ? convertToValue(instance.getAttribute(attributeName)) : undefined); + const bind = new Bind({ + parent: parentValue, + child: intermediateValue, + queue: 'dom', + onInitDoNotUpdateChild: true + }); + if (instance[metaSymbol] === undefined) { + instance[metaSymbol] = {}; + } + if (instance[metaSymbol]._attributeBindings === undefined) { + instance[metaSymbol]._attributeBindings = {}; + } + instance[metaSymbol]._attributeBindings[attributeName] = intermediateValue; + return bind; + }; + } + module.exports = function fromAttribute(attributeName, ctr) { + var converter; + if (arguments.length === 2 && canReflect.isConstructorLike(ctr) && !isJSONLike(ctr)) { + return initializeFromAttribute(attributeName, ctr); + } else if (arguments.length === 1 && typeof attributeName === 'object') { + converter = attributeName; + attributeName = undefined; + } else if (typeof ctr === 'object' && isJSONLike(ctr)) { + converter = ctr; + } + return function (propertyName, ctr) { + return initializeFromAttribute(propertyName, ctr, converter, attributeName); + }; + }; +}); +/*can-observable-bindings@1.3.3#can-observable-bindings*/ +define('can-observable-bindings@1.3.3#can-observable-bindings', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './from-attribute' +], function (require, exports, module) { + const namespace = require('can-namespace'); + const fromAttribute = require('./from-attribute'); + namespace.fromAttribute = fromAttribute; + module.exports = { fromAttribute: fromAttribute }; +}); +/*can-stache-element@1.2.0#src/mixin-bind-behaviour-test*/ +define('can-stache-element@1.2.0#src/mixin-bind-behaviour-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './can-stache-element', + 'can-type', + 'can-observable-bindings', + 'can-reflect-dependencies', + 'can-test-helpers', + '../test/helpers' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const StacheElement = require('./can-stache-element'); + const type = require('can-type'); + const {fromAttribute} = require('can-observable-bindings'); + const canReflectDeps = require('can-reflect-dependencies'); + const dev = require('can-test-helpers').dev; + const testHelpers = require('../test/helpers'); + const browserSupports = testHelpers.browserSupports; + let fixture; + QUnit.module('can-stache-element - mixin-bind-behaviour', { + beforeEach() { + fixture = document.querySelector('#qunit-fixture'); + } + }); + if (browserSupports.customElements) { + QUnit.test('can set attribute from properties', function (assert) { + class BasicBindingsElement extends StacheElement { + static get view() { + return `

      {{fname}} {{lname}}

      `; + } + static get props() { + return { + fname: { + type: type.maybeConvert(String), + bind: fromAttribute + }, + lname: { + type: type.maybeConvert(String), + bind: fromAttribute + } + }; + } + } + customElements.define('set-attribute', BasicBindingsElement); + const el = document.createElement('set-attribute'); + fixture.appendChild(el); + assert.equal(el.getAttribute('fname'), undefined, 'We have not initialized the attribute'); + assert.equal(el.fname, undefined, 'We have not initialized the property'); + el.setAttribute('fname', 'Justin'); + assert.equal(el.fname, 'Justin', 'We have set the property from the attribute'); + el.setAttribute('lname', 'Meyer'); + assert.equal(el.lname, 'Meyer', 'We have set the property from the attribute'); + }); + QUnit.test('properties are not set when attribute does not exist', function (assert) { + class BasicBindingsElement extends StacheElement { + static get view() { + return `

      {{name}}

      `; + } + static get props() { + return { + name: { + type: type.maybeConvert(String), + bind: fromAttribute, + set(v) { + return v; + } + } + }; + } + } + customElements.define('no-attribute', BasicBindingsElement); + const el = document.createElement('no-attribute'); + fixture.appendChild(el); + assert.strictEqual(el.getAttribute('name'), null, 'We have not initialized the attribute'); + assert.strictEqual(el.name, undefined, 'We have not initialized the property'); + }); + QUnit.test('property is not called multiple times', function (assert) { + let setCounter = 0; + class BasicBindingsElement extends StacheElement { + static get view() { + return `

      {{name}}

      `; + } + static get props() { + return { + name: { + type: type.maybeConvert(String), + bind: fromAttribute, + set(newVal) { + setCounter++; + return newVal; + } + } + }; + } + } + customElements.define('setter-multiple-check', BasicBindingsElement); + const el = document.createElement('setter-multiple-check'); + el.setAttribute('name', 'Kevin'); + fixture.appendChild(el); + assert.strictEqual(el.getAttribute('name'), 'Kevin', 'We have the attribute'); + assert.strictEqual(el.name, 'Kevin', 'We have initialized the property'); + assert.strictEqual(setCounter, 1, 'We have only called the setter once'); + }); + QUnit.test('camelCase propName', function (assert) { + class BasicBindingsElement extends StacheElement { + static get view() { + return ``; + } + static get props() { + return { + firstName: { + type: type.convert(String), + bind: fromAttribute + } + }; + } + } + customElements.define('camel-case', BasicBindingsElement); + const el = document.createElement('camel-case'); + fixture.appendChild(el); + el.setAttribute('first-name', 'Kevin'); + assert.equal(el.firstName, 'Kevin', 'We have the correct property value'); + }); + dev.devOnlyTest('check graph whatchangesme works', function (assert) { + class BasicBindingsElement extends StacheElement { + static get view() { + return ``; + } + static get props() { + return { + name: { + type: type.convert(String), + bind: fromAttribute + } + }; + } + } + customElements.define('what-changes-me', BasicBindingsElement); + const el = document.createElement('what-changes-me'); + fixture.appendChild(el); + const propDeps = canReflectDeps.getDependencyDataOf(el, 'name').whatChangesMe.mutate.valueDependencies; + assert.equal(propDeps.size, 1, 'We have the graph data'); + for (let dep of propDeps) { + assert.equal(dep[Symbol.for('can.getName')](), 'Observation>', 'We have the correct graph dep'); + } + }); + } +}); +/*can-stache-element@1.2.0#test/test-no-class-fields*/ +define('can-stache-element@1.2.0#test/test-no-class-fields', [ + 'can-stache-element@1.2.0#src/can-stache-element-test', + 'can-stache-element@1.2.0#src/mixin-props-test', + 'can-stache-element@1.2.0#src/mixin-lifecycle-methods-test', + 'can-stache-element@1.2.0#src/mixin-stache-view-test', + 'can-stache-element@1.2.0#src/mixin-viewmodel-symbol-test', + 'can-stache-element@1.2.0#src/import-export-steal-test', + 'can-stache-element@1.2.0#src/mixin-bindings-test', + 'can-stache-element@1.2.0#src/mixin-initialize-bindings-test', + 'can-stache-element@1.2.0#src/mixin-bind-behaviour-test' +], function () { + 'use strict'; +}); +/*can-observable-array@1.1.4#src/helpers*/ +define('can-observable-array@1.1.4#src/helpers', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observable-mixin', + 'can-observation-recorder', + 'can-event-queue/map/map' +], function (require, exports, module) { + const canReflect = require('can-reflect'); + const {mixins} = require('can-observable-mixin'); + const ObservationRecorder = require('can-observation-recorder'); + const mapBindings = require('can-event-queue/map/map'); + const metaSymbol = Symbol.for('can.meta'); + const helpers = { + assignNonEnumerable: function (obj, key, value) { + return Object.defineProperty(obj, key, { + enumerable: false, + writable: true, + configurable: true, + value: value + }); + }, + shouldRecordObservationOnAllKeysExceptFunctionsOnProto: function (keyInfo, meta) { + return meta.preventSideEffects === 0 && !keyInfo.isAccessor && (keyInfo.targetHasOwnKey || !keyInfo.protoHasKey && !Object.isSealed(meta.target) || keyInfo.protoHasKey && typeof targetValue !== 'function'); + }, + dispatchIndexEvent: function (attr, how, newVal, oldVal) { + var index = +attr; + if (!isNaN(index)) { + var itemsDefinition = this._define.definitions['#']; + if (how === 'set') { + this.dispatch({ + type: index, + action: how, + key: index, + value: newVal, + oldValue: oldVal + }, [ + newVal, + oldVal + ]); + let meta = this[metaSymbol]; + if (!('preventSideEffects' in meta) || meta.preventSideEffects === 0) { + let patches = [{ + index: index, + deleteCount: 1, + insert: [newVal], + type: 'splice' + }]; + helpers.dispatchLengthPatch.call(this, how, patches, this.length, this.length); + } + } else if (how === 'add') { + if (itemsDefinition && typeof itemsDefinition.added === 'function') { + ObservationRecorder.ignore(itemsDefinition.added).call(this, newVal, index); + } + this.dispatch({ + type: index, + action: how, + key: index, + value: newVal, + oldValue: oldVal + }, [ + newVal, + oldVal + ]); + let meta = this[metaSymbol]; + if (!('preventSideEffects' in meta) || meta.preventSideEffects === 0) { + let patches = [{ + index: index, + deleteCount: 0, + insert: [newVal], + type: 'splice' + }]; + helpers.dispatchLengthPatch.call(this, how, patches, this.length, this.length - 1); + } + } else if (how === 'remove') { + if (itemsDefinition && typeof itemsDefinition.removed === 'function') { + ObservationRecorder.ignore(itemsDefinition.removed).call(this, oldVal, index); + } + } + } else { + var key = '' + attr; + this.dispatch({ + type: key, + key: key, + action: how, + value: newVal, + oldValue: oldVal, + target: this + }, [ + newVal, + oldVal + ]); + } + }, + dispatchLengthPatch: function (how, patches, newLength, oldLength) { + const dispatchArgs = { + type: 'length', + key: 'length', + action: how, + value: newLength, + oldValue: oldLength, + patches: patches + }; + mapBindings.dispatch.call(this, dispatchArgs, [ + newLength, + oldLength + ]); + }, + convertItem: function (Constructor, item) { + if (Constructor.items) { + const definition = mixins.normalizeTypeDefinition(Constructor.items.type || Constructor.items); + return canReflect.convert(item, definition); + } + return item; + }, + convertItems: function (Constructor, items) { + if (items.length) { + if (Constructor.items) { + for (let i = 0, len = items.length; i < len; i++) { + items[i] = helpers.convertItem(Constructor, items[i]); + } + } + } + return items; + } + }; + module.exports = helpers; +}); +/*can-observable-array@1.1.4#src/computed-helpers*/ +define('can-observable-array@1.1.4#src/computed-helpers', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-event-queue/map/map' +], function (require, exports, module) { + const canReflect = require('can-reflect'); + const mapBindings = require('can-event-queue/map/map'); + var canMeta = Symbol.for('can.meta'); + const computedPropertyDefinitionSymbol = Symbol.for('can.computedPropertyDefinitions'); + const onKeyValueSymbol = Symbol.for('can.onKeyValue'); + const offKeyValueSymbol = Symbol.for('can.offKeyValue'); + function ComputedObjectObservationData(instance, prop, observation) { + this.instance = instance; + this.prop = prop; + this.observation = observation; + this.forward = this.forward.bind(this); + } + ComputedObjectObservationData.prototype.bind = function () { + this.bindingCount++; + if (this.bindingCount === 1) { + this.observation.on(this.forward, 'notify'); + } + }; + ComputedObjectObservationData.prototype.unbind = function () { + this.bindingCount--; + if (this.bindingCount === 0) { + this.observation.off(this.forward, 'notify'); + } + }; + ComputedObjectObservationData.prototype.forward = function (newValue, oldValue) { + mapBindings.dispatch.call(this.instance, { + type: this.prop, + key: this.prop, + target: this.instance, + value: newValue, + oldValue: oldValue + }, [ + newValue, + oldValue + ]); + }; + ComputedObjectObservationData.prototype.bindingCount = 0; + function findComputed(instance, key) { + var meta = instance[canMeta]; + var target = meta.target; + var computedPropertyDefinitions = target[computedPropertyDefinitionSymbol]; + if (computedPropertyDefinitions === undefined) { + return; + } + var computedPropertyDefinition = computedPropertyDefinitions[key]; + if (computedPropertyDefinition === undefined) { + return; + } + if (meta.computedKeys[key] === undefined) { + meta.computedKeys[key] = new ComputedObjectObservationData(instance, key, computedPropertyDefinition(instance, key)); + } + return meta.computedKeys[key]; + } + const computedHelpers = { + bind: function (instance, key) { + let computedObj = findComputed(instance, key); + if (computedObj === undefined) { + return; + } + computedObj.bind(); + }, + addKeyDependencies: function (proxyKeys) { + let onKeyValue = proxyKeys[onKeyValueSymbol]; + let offKeyValue = proxyKeys[offKeyValueSymbol]; + canReflect.assignSymbols(proxyKeys, { + 'can.onKeyValue': function (key) { + computedHelpers.bind(this, key); + return onKeyValue.apply(this, arguments); + }, + 'can.offKeyValue': function (key) { + computedHelpers.unbind(this, key); + return offKeyValue.apply(this, arguments); + }, + 'can.getKeyDependencies': function (key) { + var computedObj = findComputed(this, key); + if (computedObj === undefined) { + return; + } + return { valueDependencies: new Set([computedObj.observation]) }; + } + }); + } + }; + module.exports = computedHelpers; +}); +/*can-observable-array@1.1.4#src/proxy-array*/ +define('can-observable-array@1.1.4#src/proxy-array', [ + 'require', + 'exports', + 'module', + 'can-reflect', + './computed-helpers', + 'can-event-queue/map/map', + 'can-observation-recorder', + './helpers', + 'can-observable-mixin' +], function (require, exports, module) { + const canReflect = require('can-reflect'); + const computedHelpers = require('./computed-helpers'); + const mapBindings = require('can-event-queue/map/map'); + const ObservationRecorder = require('can-observation-recorder'); + const {assignNonEnumerable, convertItem, dispatchIndexEvent, shouldRecordObservationOnAllKeysExceptFunctionsOnProto} = require('./helpers'); + const {mixins} = require('can-observable-mixin'); + const hasOwn = Object.prototype.hasOwnProperty; + const {isSymbolLike} = canReflect; + const metaSymbol = Symbol.for('can.meta'); + const proxiedObjects = new WeakMap(); + const proxies = new WeakSet(); + const proxyKeys = Object.create(null); + Object.getOwnPropertySymbols(mapBindings).forEach(function (symbol) { + assignNonEnumerable(proxyKeys, symbol, mapBindings[symbol]); + }); + computedHelpers.addKeyDependencies(proxyKeys); + const mutateMethods = { + 'push': function (arr, args) { + return [{ + index: arr.length - args.length, + deleteCount: 0, + insert: args, + type: 'splice' + }]; + }, + 'pop': function (arr) { + return [{ + index: arr.length, + deleteCount: 1, + insert: [], + type: 'splice' + }]; + }, + 'shift': function () { + return [{ + index: 0, + deleteCount: 1, + insert: [], + type: 'splice' + }]; + }, + 'unshift': function (arr, args) { + return [{ + index: 0, + deleteCount: 0, + insert: args, + type: 'splice' + }]; + }, + 'splice': function (arr, args) { + return [{ + index: args[0], + deleteCount: args[1], + insert: args.slice(2), + type: 'splice' + }]; + }, + 'sort': function (arr) { + return [{ + index: 0, + deleteCount: arr.length, + insert: arr, + type: 'splice' + }]; + }, + 'reverse': function (arr) { + return [{ + index: 0, + deleteCount: arr.length, + insert: arr, + type: 'splice' + }]; + } + }; + canReflect.eachKey(mutateMethods, function (makePatches, prop) { + var protoFn = Array.prototype[prop]; + var mutateMethod = function () { + var meta = this[metaSymbol], makeSideEffects = meta.preventSideEffects === 0, oldLength = meta.target.length; + meta.preventSideEffects++; + var ret = protoFn.apply(meta.target, arguments); + var patches = makePatches(meta.target, Array.from(arguments), oldLength); + if (makeSideEffects === true) { + var dispatchArgs = { + type: 'length', + key: 'length', + value: meta.target.length, + oldValue: oldLength, + patches: patches + }; + mapBindings.dispatch.call(meta.proxy, dispatchArgs, [ + meta.target.length, + oldLength + ]); + } + meta.preventSideEffects--; + return ret; + }; + proxiedObjects.set(protoFn, mutateMethod); + proxies.add(mutateMethod); + }); + function setValueAndOnChange(key, value, target, proxy, onChange) { + let old, change; + let hadOwn = hasOwn.call(target, key); + let descriptor = Object.getOwnPropertyDescriptor(target, key); + if (descriptor && descriptor.set) { + descriptor.set.call(proxy, value); + } else { + old = target[key]; + change = old !== value; + if (change) { + let keyType = typeof key; + let keyIsString = keyType === 'string'; + if (keyIsString && !(key in target)) { + mixins.expando(target, key, value); + } else { + if (keyType === 'number') { + value = convertItem(target.constructor, value); + } + target[key] = value; + onChange(hadOwn, old); + } + } + } + } + const proxyHandlers = { + get(target, key, receiver) { + if (isSymbolLike(key)) { + return target[key]; + } + let proxy = proxiedObjects.get(target); + ObservationRecorder.add(proxy, key.toString()); + const numberKey = !isSymbolLike(key) && +key; + if (Number.isInteger(numberKey)) { + ObservationRecorder.add(proxy, 'length'); + } + let value = Reflect.get(target, key, receiver); + return value; + }, + set(target, key, newValue, receiver) { + let proxy = proxiedObjects.get(target); + let numberKey = !isSymbolLike(key) && +key; + if (Number.isInteger(numberKey)) { + key = numberKey; + } + setValueAndOnChange(key, newValue, target, proxy, function onChange(hadOwn, oldValue) { + if (Number.isInteger(key)) { + dispatchIndexEvent.call(receiver, key, hadOwn ? typeof newValue !== 'undefined' ? 'set' : 'remove' : 'add', newValue, oldValue); + } + }); + return true; + }, + deleteProperty(target, key) { + let old = this.target[key]; + let deleteSuccessful = delete this.target[key]; + if (deleteSuccessful && this.preventSideEffects === 0 && old !== undefined) { + dispatchIndexEvent.call(this.proxy, key, 'remove', undefined, old); + } + return deleteSuccessful; + }, + ownKeys() { + ObservationRecorder.add(this.proxy, 'can.keys'); + let keysSet = new Set(Object.getOwnPropertyNames(this.target).concat(Object.getOwnPropertySymbols(this.target)).concat(Object.getOwnPropertySymbols(this.proxyKeys))); + return Array.from(keysSet); + } + }; + function makeObservable(array, options) { + let meta = { + target: array, + proxyKeys: options.proxyKeys !== undefined ? options.proxyKeys : Object.create(proxyKeys), + computedKeys: Object.create(null), + options: options, + preventSideEffects: 0 + }; + meta.proxyKeys[metaSymbol] = meta; + meta.proxy = new Proxy(array, { + get: proxyHandlers.get.bind(meta), + set: proxyHandlers.set.bind(meta), + ownKeys: proxyHandlers.ownKeys.bind(meta), + deleteProperty: proxyHandlers.deleteProperty.bind(meta), + meta: meta + }); + mapBindings.addHandlers(meta.proxy, meta); + return meta.proxy; + } + function proxyArray() { + return class ProxyArray extends Array { + constructor(...items) { + super(...items); + let localProxyKeys = Object.create(proxyKeys); + localProxyKeys.constructor = this.constructor; + let observable = makeObservable(this, { + proxyKeys: localProxyKeys, + shouldRecordObservation: shouldRecordObservationOnAllKeysExceptFunctionsOnProto + }); + proxiedObjects.set(this, observable); + proxies.add(observable); + return observable; + } + }; + } + module.exports = proxyArray; +}); +/*can-observable-array@1.1.4#src/can-observable-array*/ +define('can-observable-array@1.1.4#src/can-observable-array', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observable-mixin', + './helpers', + 'can-namespace', + './proxy-array', + 'can-queues', + 'can-type' +], function (require, exports, module) { + const canReflect = require('can-reflect'); + const {createConstructorFunction, makeDefineInstanceKey, mixins, mixinMapProps, mixinTypeEvents} = require('can-observable-mixin'); + const {convertItem, convertItems, dispatchLengthPatch} = require('./helpers'); + const namespace = require('can-namespace'); + const ProxyArray = require('./proxy-array')(); + const queues = require('can-queues'); + const type = require('can-type'); + const localOnPatchesSymbol = 'can.patches'; + const onKeyValueSymbol = Symbol.for('can.onKeyValue'); + const offKeyValueSymbol = Symbol.for('can.offKeyValue'); + const metaSymbol = Symbol.for('can.meta'); + function isListLike(items) { + return canReflect.isListLike(items) && typeof items !== 'string'; + } + const MixedInArray = mixinTypeEvents(mixinMapProps(ProxyArray)); + class ObservableArray extends MixedInArray { + constructor(items, props) { + let isLengthArg = typeof items === 'number'; + if (isLengthArg) { + super(items); + } else if (arguments.length > 0 && !isListLike(items)) { + throw new Error('can-observable-array: Unexpected argument: ' + typeof items); + } else { + super(); + } + mixins.finalizeClass(new.target); + mixins.initialize(this, props || {}); + for (let i = 0, len = items && items.length; i < len; i++) { + this[i] = convertItem(new.target, items[i]); + } + return new Proxy(this, { + defineProperty(target, prop, descriptor) { + if ('items' === prop) { + throw new Error('ObservableArray does not support a class field named items. Try using a different name or using static items'); + } + if (prop === '_instanceDefinitions') { + return Reflect.defineProperty(target, prop, descriptor); + } + let value = descriptor.value; + const props = target.constructor.props; + if (props && props[prop] || target.constructor.propertyDefaults) { + if (value) { + target.set(prop, value); + return true; + } + return Reflect.defineProperty(target, prop, descriptor); + } + return mixins.expando(target, prop, value); + } + }); + } + static get [Symbol.species]() { + return this; + } + static [Symbol.for('can.new')](items) { + let array = items || []; + return new this(array); + } + push(...items) { + return super.push(...items); + } + unshift(...items) { + return super.unshift(...items); + } + filter(callback) { + if (typeof callback === 'object') { + let props = callback; + callback = function (item) { + for (let prop in props) { + if (item[prop] !== props[prop]) { + return false; + } + } + return true; + }; + } + return super.filter(callback); + } + forEach(...args) { + return Array.prototype.forEach.apply(this, args); + } + splice(...args) { + let index = args[0], howMany = args[1], added = [], i, len, listIndex, allSame = args.length > 2; + index = index || 0; + for (i = 0, len = args.length - 2; i < len; i++) { + listIndex = i + 2; + added.push(args[listIndex]); + if (this[i + index] !== args[listIndex]) { + allSame = false; + } + } + if (allSame && this.length <= added.length) { + return added; + } + if (howMany === undefined) { + howMany = args[1] = this.length - index; + } + queues.batch.start(); + var removed = super.splice.apply(this, args); + queues.batch.stop(); + return removed; + } + static convertsTo(Type) { + const ConvertedType = type.convert(Type); + const ArrayType = class extends this { + static get items() { + return ConvertedType; + } + }; + const name = `ConvertedObservableArray<${ canReflect.getName(Type) }>`; + canReflect.setName(ArrayType, name); + return ArrayType; + } + [Symbol.for('can.splice')](index, deleteCount, insert) { + return this.splice(...[ + index, + deleteCount + ].concat(insert)); + } + [Symbol.for('can.onPatches')](handler, queue) { + this[onKeyValueSymbol](localOnPatchesSymbol, handler, queue); + } + [Symbol.for('can.offPatches')](handler, queue) { + this[offKeyValueSymbol](localOnPatchesSymbol, handler, queue); + } + get [Symbol.for('can.isListLike')]() { + return true; + } + [Symbol.for('can.getOwnEnumerableKeys')]() { + let base = super[Symbol.for('can.getOwnEnumerableKeys')](); + let keysSet = new Set([ + ...Object.keys(this), + ...base + ]); + return Array.from(keysSet); + } + } + var mutateMethods = { + 'push': function (arr, args) { + return [{ + index: arr.length - args.length, + deleteCount: 0, + insert: args, + type: 'splice' + }]; + }, + 'pop': function (arr, args, oldLength) { + return [{ + index: arr.length, + deleteCount: oldLength > 0 ? 1 : 0, + type: 'splice' + }]; + }, + 'shift': function (arr, args, oldLength) { + return [{ + index: 0, + deleteCount: oldLength > 0 ? 1 : 0, + type: 'splice' + }]; + }, + 'unshift': function (arr, args) { + return [{ + index: 0, + deleteCount: 0, + insert: args, + type: 'splice' + }]; + }, + 'splice': function (arr, args, oldLength) { + const index = args[0] < 0 ? Math.max(oldLength + args[0], 0) : Math.min(oldLength, args[0]); + return [{ + index, + deleteCount: Math.max(0, Math.min(args[1], oldLength - index)), + insert: args.slice(2), + type: 'splice' + }]; + }, + 'sort': function (arr) { + return [{ + index: 0, + deleteCount: arr.length, + insert: arr, + type: 'splice' + }]; + }, + 'reverse': function (arr) { + return [{ + index: 0, + deleteCount: arr.length, + insert: arr, + type: 'splice' + }]; + } + }; + const convertArgs = { + 'push': function (arr, args) { + return convertItems(arr.constructor, args); + }, + 'unshift': function (arr, args) { + return convertItems(arr.constructor, args); + }, + 'splice': function (arr, args) { + return args.slice(0, 2).concat(convertItems(arr.constructor, args.slice(2))); + } + }; + canReflect.eachKey(mutateMethods, function (makePatches, prop) { + const protoFn = ObservableArray.prototype[prop]; + ObservableArray.prototype[prop] = function () { + const oldLength = this.length; + let args = Array.from(arguments); + if (convertArgs[prop]) { + args = convertArgs[prop](this, args); + } + this[metaSymbol].preventSideEffects = (this[metaSymbol].preventSideEffects || 0) + 1; + const result = protoFn.apply(this, args); + this[metaSymbol].preventSideEffects--; + const patches = makePatches(this, args, oldLength); + dispatchLengthPatch.call(this, prop, patches, this.length, oldLength); + return result; + }; + }); + makeDefineInstanceKey(ObservableArray); + module.exports = namespace.ObservableArray = createConstructorFunction(ObservableArray); +}); +/*can-observable-object@1.1.4#src/can-observable-object*/ +define('can-observable-object@1.1.4#src/can-observable-object', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-observable-mixin' +], function (require, exports, module) { + const namespace = require('can-namespace'); + const {createConstructorFunction, makeDefineInstanceKey, mixins, mixinMapProps, mixinProxy, mixinTypeEvents} = require('can-observable-mixin'); + let ObservableObject = class extends mixinProxy(Object) { + constructor(props) { + super(); + mixins.finalizeClass(this.constructor); + mixins.initialize(this, props); + const proxiedInstance = new Proxy(this, { + defineProperty(target, prop, descriptor) { + const props = target.constructor.props; + let value = descriptor.value; + const specialKeys = [ + '_instanceDefinitions', + '_data', + '_computed' + ]; + if (specialKeys.indexOf(prop) >= 0) { + return Reflect.defineProperty(target, prop, descriptor); + } + if (value) { + if (props && props[prop] || target.constructor.propertyDefaults) { + target.set(prop, value); + return true; + } + return mixins.expando(target, prop, value); + } + return Reflect.defineProperty(target, prop, descriptor); + } + }); + this.constructor.instances.add(proxiedInstance); + return proxiedInstance; + } + }; + ObservableObject = mixinTypeEvents(mixinMapProps(ObservableObject)); + makeDefineInstanceKey(ObservableObject); + module.exports = namespace.ObservableObject = createConstructorFunction(ObservableObject); +}); +/*can-observable-array@1.1.4#test/array-test*/ +define('can-observable-array@1.1.4#test/array-test', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation', + '../src/can-observable-array', + 'can-observable-object', + 'steal-qunit', + 'can-type' +], function (require, exports, module) { + const canReflect = require('can-reflect'); + const Observation = require('can-observation'); + const ObservableArray = require('../src/can-observable-array'); + const ObservableObject = require('can-observable-object'); + const QUnit = require('steal-qunit'); + const type = require('can-type'); + module.exports = function () { + QUnit.test('Adds proxyability to arrays', function (assert) { + class Todos extends ObservableArray { + } + let todos = new Todos(); + let calls = 0; + let expected = 2; + canReflect.onKeyValue(todos, 0, newValue => { + calls++; + assert.equal(newValue, 'get this working', 'able to listen to push'); + }); + canReflect.onKeyValue(todos, 14, newValue => { + calls++; + assert.equal(newValue, 'some value', 'able to listen to property setter'); + }); + todos.push('get this working'); + todos[14] = 'some value'; + assert.equal(calls, expected, 'Got all of the values I expected'); + }); + QUnit.test('.filter can be provided an object', function (assert) { + class Todos extends ObservableArray { + } + let todos = new Todos([ + { name: 'walk the dog' }, + { + name: 'cook dinner', + completed: true + } + ]); + let completed = todos.filter({ completed: true }); + assert.equal(completed.length, 1, 'only one'); + assert.equal(completed[0].name, 'cook dinner'); + assert.ok(completed instanceof Todos, 'Filtered item is of right type'); + }); + QUnit.test('canReflect.new creates a new array with items', function (assert) { + class Todos extends ObservableArray { + } + let todos = canReflect.new(Todos, [ + { name: 'walk the dog' }, + { + name: 'cook dinner', + completed: true + } + ]); + assert.equal(todos.length, 2, 'There are 2 items'); + assert.equal(todos[0].name, 'walk the dog'); + }); + QUnit.test('forEach works', function (assert) { + class Todos extends ObservableArray { + } + let todos = new Todos([ + { name: 'walk the dog' }, + { + name: 'cook dinner', + completed: true + } + ]); + let expected = 2; + let actual = 0; + todos.forEach(() => { + actual++; + }); + assert.equal(actual, expected, 'Looped over each item'); + }); + QUnit.test('for...in works', function (assert) { + class Todos extends ObservableArray { + } + let todos = new Todos([ + { name: 'walk the dog' }, + { + name: 'cook dinner', + completed: true + } + ]); + let props = []; + for (let prop in todos) { + props.push(prop); + } + assert.ok(props, 'for...in should not throw'); + }); + QUnit.test('splice dispatches patches and length events', function (assert) { + class Todos extends ObservableArray { + } + let todos = new Todos([ + { name: 'walk the dog' }, + { + name: 'cook dinner', + completed: true + } + ]); + let expected = 2, actual = 0; + canReflect.onPatches(todos, patches => { + if (patches[0].type === 'splice') { + assert.ok(true, 'splice patch called'); + actual++; + } + }); + canReflect.onKeyValue(todos, 'length', () => { + actual++; + }); + todos.splice(0, 1); + assert.equal(actual, expected, 'Length and patches called'); + }); + QUnit.test('can.splice dispatches patches and length events', function (assert) { + class Todos extends ObservableArray { + } + let todos = new Todos([ + { name: 'walk the dog' }, + { + name: 'cook dinner', + completed: true + } + ]); + let expected = 2, actual = 0; + canReflect.onPatches(todos, patches => { + if (patches[0].type === 'splice') { + assert.ok(true, 'set patch called'); + actual++; + } + }); + canReflect.onKeyValue(todos, 'length', () => { + actual++; + }); + canReflect.splice(todos, 0, 1); + assert.equal(actual, expected, 'Length and patches called'); + }); + QUnit.test('isListLike', function (assert) { + let array = new ObservableArray([ + 'one', + 'two' + ]); + assert.equal(canReflect.isListLike(array), true, 'it is list like'); + class Extended extends ObservableArray { + } + let extended = new Extended([ + 'one', + 'two' + ]); + assert.equal(canReflect.isListLike(extended), true, 'It is list like'); + }); + QUnit.test('getOwnKeys', function (assert) { + let empty = new ObservableArray(); + assert.deepEqual(canReflect.getOwnKeys(empty), []); + let array = new ObservableArray([ + 1, + 2, + 3 + ]); + assert.deepEqual(canReflect.getOwnKeys(array), [ + '0', + '1', + '2' + ]); + class EnumerableComputed extends ObservableArray { + static get props() { + return { + computed: { + enumerable: true, + default: 'a computed property' + } + }; + } + } + let enumerable = new EnumerableComputed([ + 1, + 2, + 3 + ]); + assert.deepEqual(canReflect.getOwnKeys(enumerable), [ + '0', + '1', + '2', + 'computed' + ], 'should include enumerables'); + class Extended extends ObservableArray { + static get props() { + return { + get computed() { + return 'a computed property'; + } + }; + } + } + let extended = new Extended([ + 1, + 2, + 3 + ]); + assert.deepEqual(canReflect.getOwnKeys(extended), [ + '0', + '1', + '2', + 'computed' + ], 'should include non-enumerables'); + }); + QUnit.test('getOwnEnumerableKeys', function (assert) { + let empty = new ObservableArray(); + assert.deepEqual(canReflect.getOwnEnumerableKeys(empty), []); + let array = new ObservableArray([ + 1, + 2, + 3 + ]); + assert.deepEqual(canReflect.getOwnEnumerableKeys(array), [ + '0', + '1', + '2' + ]); + class Extended extends ObservableArray { + static get props() { + return { + get computed() { + return 'a computed property'; + } + }; + } + } + let extended = new Extended([ + 1, + 2, + 3 + ]); + assert.deepEqual(canReflect.getOwnEnumerableKeys(extended), [ + '0', + '1', + '2' + ], 'should NOT include non-enumerables'); + class EnumerableComputed extends ObservableArray { + static get props() { + return { + computed: { + enumerable: true, + default: 'a computed property' + } + }; + } + } + let enumerable = new EnumerableComputed([ + 1, + 2, + 3 + ]); + assert.deepEqual(canReflect.getOwnEnumerableKeys(enumerable), [ + '0', + '1', + '2', + 'computed' + ], 'should NOT include non-enumerables'); + }); + QUnit.test('push dispatches patches and length events', function (assert) { + class Hobbies extends ObservableArray { + } + const hobbies = new Hobbies(); + let expected = 2, actual = 0; + canReflect.onPatches(hobbies, patches => { + if (patches[0].type === 'splice') { + assert.ok(true, 'splice patches called'); + actual++; + } + }); + canReflect.onKeyValue(hobbies, 'length', () => { + actual++; + }); + hobbies.push('cooking'); + assert.equal(actual, expected, 'Length and patches called'); + }); + QUnit.test('can take undefined as a value with can.new', function (assert) { + let array = canReflect.new(ObservableArray, undefined); + assert.deepEqual(array, [], 'no values, just like with DefineList'); + }); + QUnit.test('setting values dispatch the correct events', function (assert) { + var testSteps = [ + { + prop: 0, + value: 'hi', + events: [ + { + type: 0, + newVal: 'hi', + oldVal: undefined + }, + { + type: 'length', + newVal: 1, + oldVal: 0 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 0, + insert: ['hi'] + }]] + }, + { + prop: 0, + value: 'hello', + events: [ + { + type: 0, + newVal: 'hello', + oldVal: 'hi' + }, + { + type: 'length', + newVal: 1, + oldVal: 1 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 1, + insert: ['hello'] + }]] + }, + { + prop: 1, + value: 'there', + events: [ + { + type: 1, + newVal: 'there', + oldVal: undefined + }, + { + type: 'length', + newVal: 2, + oldVal: 1 + } + ], + patches: [[{ + type: 'splice', + index: 1, + deleteCount: 0, + insert: ['there'] + }]] + } + ]; + const arr = new ObservableArray(); + let actualEvents, actualPatches; + canReflect.onKeyValue(arr, 0, (newVal, oldVal) => { + actualEvents.push({ + type: 0, + newVal, + oldVal + }); + }); + canReflect.onKeyValue(arr, 1, (newVal, oldVal) => { + actualEvents.push({ + type: 1, + newVal, + oldVal + }); + }); + canReflect.onKeyValue(arr, 'length', (newVal, oldVal) => { + actualEvents.push({ + type: 'length', + newVal, + oldVal + }); + }); + canReflect.onPatches(arr, patches => { + actualPatches.push(patches); + }); + testSteps.forEach(step => { + actualEvents = []; + actualPatches = []; + const {prop, value, events, patches} = step; + arr[prop] = value; + assert.deepEqual(actualEvents, events, `arr[${ prop }] = "${ value }" dispatched correct events`); + assert.deepEqual(actualPatches, patches, `arr[${ prop }] = "${ value }" dispatched correct patches`); + }); + }); + QUnit.test('array methods dispatch the correct events', function (assert) { + var testSteps = [ + { + method: 'push', + args: ['hi'], + events: [ + { + type: 0, + newVal: 'hi', + oldVal: undefined + }, + { + type: 'length', + newVal: 1, + oldVal: 0 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 0, + insert: ['hi'] + }]] + }, + { + method: 'push', + args: [ + 'hi', + 'there' + ], + events: [ + { + type: 0, + newVal: 'hi', + oldVal: undefined + }, + { + type: 1, + newVal: 'there', + oldVal: undefined + }, + { + type: 'length', + newVal: 2, + oldVal: 0 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 0, + insert: [ + 'hi', + 'there' + ] + }]] + }, + { + initialData: ['there'], + method: 'unshift', + args: ['hello'], + events: [ + { + type: 1, + newVal: 'there', + oldVal: undefined + }, + { + type: 0, + newVal: 'hello', + oldVal: 'there' + }, + { + type: 'length', + newVal: 2, + oldVal: 1 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 0, + insert: ['hello'] + }]] + }, + { + initialData: ['you'], + method: 'unshift', + args: [ + 'how', + 'are' + ], + events: [ + { + type: 2, + newVal: 'you', + oldVal: undefined + }, + { + type: 0, + newVal: 'how', + oldVal: 'you' + }, + { + type: 1, + newVal: 'are', + oldVal: undefined + }, + { + type: 'length', + newVal: 3, + oldVal: 1 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 0, + insert: [ + 'how', + 'are' + ] + }]] + }, + { + initialData: [ + 'hi', + 'there' + ], + method: 'pop', + args: [], + events: [{ + type: 'length', + newVal: 1, + oldVal: 2 + }], + patches: [[{ + type: 'splice', + index: 1, + deleteCount: 1 + }]] + }, + { + initialData: [ + 'hi', + 'there' + ], + method: 'shift', + args: [], + events: [ + { + type: 0, + newVal: 'there', + oldVal: 'hi' + }, + { + type: 'length', + newVal: 1, + oldVal: 2 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 1 + }]] + }, + { + initialData: ['hi'], + method: 'splice', + args: [ + 0, + 1 + ], + events: [{ + type: 'length', + newVal: 0, + oldVal: 1 + }], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 1, + insert: [] + }]] + }, + { + initialData: ['there'], + method: 'splice', + args: [ + 0, + 0, + 'hi' + ], + events: [ + { + type: 1, + newVal: 'there', + oldVal: undefined + }, + { + type: 0, + newVal: 'hi', + oldVal: 'there' + }, + { + type: 'length', + newVal: 2, + oldVal: 1 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 0, + insert: ['hi'] + }]] + }, + { + initialData: ['hi'], + method: 'splice', + args: [ + 0, + 1, + 'hello', + 'there' + ], + events: [ + { + type: 0, + newVal: 'hello', + oldVal: 'hi' + }, + { + type: 1, + newVal: 'there', + oldVal: undefined + }, + { + type: 'length', + newVal: 2, + oldVal: 1 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 1, + insert: [ + 'hello', + 'there' + ] + }]] + }, + { + initialData: [ + 'fff', + 'xxx', + 'aaa' + ], + method: 'sort', + args: [], + events: [ + { + type: 0, + newVal: 'aaa', + oldVal: 'fff' + }, + { + type: 1, + newVal: 'fff', + oldVal: 'xxx' + }, + { + type: 2, + newVal: 'xxx', + oldVal: 'aaa' + }, + { + type: 'length', + newVal: 3, + oldVal: 3 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 3, + insert: [ + 'aaa', + 'fff', + 'xxx' + ] + }]] + }, + { + initialData: [ + 'fff', + 'xxx', + 'aaa' + ], + method: 'reverse', + args: [], + events: [ + { + type: 0, + newVal: 'aaa', + oldVal: 'fff' + }, + { + type: 2, + newVal: 'fff', + oldVal: 'aaa' + }, + { + type: 'length', + newVal: 3, + oldVal: 3 + } + ], + patches: [[{ + type: 'splice', + index: 0, + deleteCount: 3, + insert: [ + 'aaa', + 'xxx', + 'fff' + ] + }]] + } + ]; + class Arr extends ObservableArray { + static get items() { + return String; + } + } + testSteps.forEach(step => { + const {method, args, events, patches, initialData = []} = step; + const arr = new Arr(initialData); + const actualEvents = [], actualPatches = []; + [ + 0, + 1, + 2, + 3, + 5, + 6 + ].forEach(index => { + canReflect.onKeyValue(arr, index, (newVal, oldVal) => { + actualEvents.push({ + type: index, + newVal, + oldVal + }); + }); + }); + canReflect.onKeyValue(arr, 'length', (newVal, oldVal) => { + actualEvents.push({ + type: 'length', + newVal, + oldVal + }); + }); + canReflect.onPatches(arr, patches => { + actualPatches.push(patches); + }); + arr[method].apply(arr, args); + assert.deepEqual(actualEvents, events, `arr[${ method }](${ args.join(',') }) dispatched correct events`); + assert.deepEqual(actualPatches, patches, `arr[${ method }](${ args.join(',') }) dispatched correct patches`); + }); + }); + QUnit.test('new ObservableArray([items])', function (assert) { + let array = new ObservableArray([ + 1, + 2 + ]); + assert.deepEqual(array, [ + 1, + 2 + ], 'Takes an array'); + array = new ObservableArray([1]); + assert.deepEqual(array, [1], 'Takes an array of 1 item'); + }); + QUnit.test('new ExtendedObservableArray(items)', function (assert) { + let ExtendedArray = class extends ObservableArray { + }; + let array = new ExtendedArray([ + 1, + 2 + ]); + assert.deepEqual(array, [ + 1, + 2 + ], 'Takes an array'); + array = new ExtendedArray([1]); + assert.deepEqual(array, [1], 'Takes an array of 1 item'); + }); + QUnit.test('new ObservableArray(num)', function (assert) { + let array = new ObservableArray(10); + assert.equal(array.length, 10, '10 items'); + assert.deepEqual(array, Array.from({ length: 10 }), 'Is an item with 10 undefined slots'); + }); + QUnit.test('new ObservableArray(items, {props})', function (assert) { + let array = new ObservableArray([], { foo: 'bar' }); + assert.equal(array.foo, 'bar', 'Properties are set'); + }); + QUnit.test('new ExtendedObservableArray(items, {props})', function (assert) { + class ExtendedObservableArray extends ObservableArray { + static get props() { + return { age: type.convert(Number) }; + } + } + let array = new ExtendedObservableArray([], { age: '13' }); + assert.equal(array.age, 13, 'Converted works too'); + }); + QUnit.test('new ObservableArray(num, props)', function (assert) { + let array = new ObservableArray(0, { foo: 'bar' }); + assert.deepEqual(array, [], 'Array of no items'); + assert.equal(array.foo, 'bar', 'props works'); + }); + QUnit.test('new ObservableArray(arg) throws if not an array or number', function (assert) { + [ + 'string', + /regexp/, + {}, + false + ].forEach(function (arg) { + try { + let arr = new ObservableArray(arg); + assert.notOk(arr, 'Unexpected argument' + arg); + } catch (e) { + assert.ok(true, 'Threw, and it was supposed to'); + } + }); + }); + QUnit.test('ObservableArray.convertsTo(Type) creates a converter type', function (assert) { + let Type = class extends ObservableObject { + }; + let type = ObservableArray.convertsTo(Type); + let array = canReflect.convert([ + { one: 'one' }, + { two: 'two' } + ], type); + assert.equal(array.length, 2); + assert.ok(array[0] instanceof Type, 'Each item is of the type'); + }); + QUnit.test('value, oldValue, action, key on event object', function (assert) { + assert.expect(26); + let Type = class extends ObservableArray { + }; + let array1 = new Type(); + let array2 = new ObservableArray(); + for (let array of [ + array1, + array2 + ]) { + array.listenTo('prop', ev => { + assert.equal(ev.action, 'add'); + assert.equal(ev.key, 'prop'); + assert.equal(ev.value, 'value'); + }); + array.prop = 'value'; + let first = true; + array.listenTo('0', ev => { + if (first) { + first = false; + assert.equal(ev.key, '0'); + assert.equal(ev.value, 'value1'); + assert.equal(ev.oldValue, undefined); + } else { + assert.equal(ev.key, '0'); + assert.equal(ev.value, 'value2'); + assert.equal(ev.oldValue, 'value1'); + } + }); + array.listenTo('length', ev => { + assert.ok('value' in ev); + assert.ok('oldValue' in ev); + }); + array.push('value1'); + array[0] = 'value2'; + } + }); + QUnit.test('Works with list likes', function (assert) { + let list = { + 0: 'one', + 1: 'two', + length: 2 + }; + let array = new ObservableArray(list); + assert.equal(array.length, 2, 'two items'); + assert.equal(array[0], 'one', 'first item'); + assert.equal(array[1], 'two', 'second item'); + }); + QUnit.test('index events should be fired', function (assert) { + const fallback = { name: 'fallback' }; + const list = new ObservableArray([ + { name: 'first' }, + { name: 'second' } + ]); + const first = new Observation(function () { + return list[0] || fallback; + }); + const second = new Observation(function () { + return list[1] || fallback; + }); + const noop = () => { + }; + canReflect.onValue(first, noop); + canReflect.onValue(second, noop); + assert.equal(canReflect.getValue(first).name, 'first'); + assert.equal(canReflect.getValue(second).name, 'second'); + list.shift(); + assert.equal(canReflect.getValue(first).name, 'second'); + assert.equal(canReflect.getValue(second).name, 'fallback'); + list.shift(); + assert.equal(canReflect.getValue(first).name, 'fallback'); + assert.equal(canReflect.getValue(second).name, 'fallback'); + }); + QUnit.test('mutateMethods should return the base method value', function (assert) { + const mutateMethods = { + 'push': { + array: [ + 1, + 2, + 3 + ], + args: [4], + expected: 4 + }, + 'pop': { + array: [ + 1, + 2, + 3 + ], + args: [], + expected: 3 + }, + 'shift': { + array: [ + 1, + 2, + 3 + ], + args: [], + expected: 1 + }, + 'unshift': { + array: [ + 3, + 2, + 1 + ], + args: [4], + expected: 4 + }, + 'splice': { + array: [ + 1, + 3, + 4 + ], + args: [ + 1, + 0, + 2 + ], + expected: [] + }, + 'sort': { + array: [ + 4, + 3, + 2, + 1 + ], + args: [], + expected: [ + 1, + 2, + 3, + 4 + ] + }, + 'reverse': { + array: [ + 4, + 3, + 2, + 1 + ], + args: [], + expected: [ + 1, + 2, + 3, + 4 + ] + } + }; + Object.keys(mutateMethods).forEach(method => { + const {array, args, expected} = mutateMethods[method]; + const observable = new ObservableArray(array); + assert.deepEqual(observable[method](...args), expected, `${ method } should return expected value`); + }); + }); + QUnit.test('mutateMethods should dispatch patches with correct index/deleteCount when array is too short', function (assert) { + const testSteps = [ + { + method: 'splice', + args: [ + 0, + 1 + ] + }, + { + method: 'pop', + args: [] + }, + { + method: 'shift', + args: [] + }, + { + method: 'splice', + args: [ + 1, + 4 + ], + initialData: [ + 1, + 2, + 3, + 4 + ], + deleteCount: 3 + }, + { + method: 'splice', + args: [ + 3, + 4 + ], + initialData: [ + 1, + 2 + ], + index: 2 + }, + { + method: 'splice', + args: [ + -1, + 4 + ], + initialData: [ + 1, + 2 + ], + index: 1, + deleteCount: 1 + }, + { + method: 'splice', + args: [ + 1, + -4 + ], + initialData: [ + 1, + 2 + ], + index: 1, + deleteCount: 0 + } + ]; + testSteps.forEach(step => { + const {method, args, initialData = [], deleteCount = 0} = step; + const index = step.index != null ? step.index : args[0] || 0; + const arr = new ObservableArray(initialData); + canReflect.onPatches(arr, patches => { + patches.forEach(patch => { + assert.equal(patch.deleteCount, deleteCount, `calling ${ method } returned correct deleteCount`); + assert.equal(patch.index, index, `calling ${ method } returned correct index`); + }); + }); + arr[method].apply(arr, args); + }); + }); + QUnit.test('Dispatch events for mutation with 0 integer value', function (assert) { + assert.expect(2); + const order = new ObservableArray([ + 0, + 1 + ]); + canReflect.onPatches(order, patches => { + assert.equal(patches[0].index, 1); + assert.equal(order[1], 0); + }); + order[1] = 0; + }); + QUnit.test('Dispatch events after swapping items that have 0 value', function (assert) { + assert.expect(2); + const order = new ObservableArray([ + 0, + 1 + ]); + const first = new Observation(function () { + return order[0]; + }); + const second = new Observation(function () { + return order[1]; + }); + canReflect.onValue(first, function () { + assert.equal(1, order[0]); + }); + canReflect.onValue(second, function () { + assert.equal(0, order[1]); + }); + const tmp = order[0]; + order[0] = order[1]; + order[1] = tmp; + }); + QUnit.test('metaSymbol preventSideEffects should allow array mutation functions', function (assert) { + assert.expect(2); + const myList = new ObservableArray([ + 0, + 1 + ]); + myList.push('I am going to hide some changes.'); + canReflect.onPatches(myList, function (patches) { + assert.equal(patches[0].index, 1); + assert.equal(patches[0].insert[0], 'Patched after push'); + }); + myList[1] = 'Patched after push'; + }); + }; +}); +/*can-observable-array@1.1.4#test/items-test*/ +define('can-observable-array@1.1.4#test/items-test', [ + 'require', + 'exports', + 'module', + '../src/can-observable-array', + 'can-observable-object', + 'can-type', + 'steal-qunit', + 'can-reflect' +], function (require, exports, module) { + const ObservableArray = require('../src/can-observable-array'); + const ObservableObject = require('can-observable-object'); + const type = require('can-type'); + const QUnit = require('steal-qunit'); + const canReflect = require('can-reflect'); + module.exports = function () { + QUnit.module('ExtendedObservableArray.items'); + QUnit.test('calling new with items', function (assert) { + class Todo extends ObservableObject { + } + class TodoList extends ObservableArray { + static get items() { + return type.convert(Todo); + } + } + let todos = new TodoList([{ label: 'Walk the dog' }]); + let firstTodo = todos[0]; + assert.ok(firstTodo instanceof Todo, 'Item worked'); + }); + QUnit.test('.splice', function (assert) { + class Todo extends ObservableObject { + } + class TodoList extends ObservableArray { + static get items() { + return type.convert(Todo); + } + } + let todos = new TodoList(); + todos.splice(0, 0, { label: 'Walk the dog' }); + let firstTodo = todos[0]; + assert.ok(firstTodo instanceof Todo, 'Item worked'); + }); + QUnit.test('.push', function (assert) { + class Todo extends ObservableObject { + } + class TodoList extends ObservableArray { + static get items() { + return type.convert(Todo); + } + } + let todos = new TodoList(); + todos.push({ label: 'Walk the dog' }); + let firstTodo = todos[0]; + assert.ok(firstTodo instanceof Todo, 'Item worked'); + }); + QUnit.test('.unshift', function (assert) { + class Todo extends ObservableObject { + } + class TodoList extends ObservableArray { + static get items() { + return type.convert(Todo); + } + } + let todos = new TodoList(); + todos.unshift({ label: 'Walk the dog' }); + let firstTodo = todos[0]; + assert.ok(firstTodo instanceof Todo, 'Item worked'); + }); + QUnit.test('The new Array(length) form works', function (assert) { + class Pet extends ObservableObject { + static get props() { + return { + name: { + type: String, + required: true + } + }; + } + } + class Pets extends ObservableArray { + static get items() { + return Pet; + } + } + try { + let array = new Pets(5); + assert.equal(array.length, 5, 'have an array of 5 nothings'); + } catch (e) { + assert.notOk(e, 'threw :('); + } + }); + QUnit.test('#29 items property definition as object', function (assert) { + class Person extends ObservableObject { + static get props() { + return { + name: { + type: String, + required: true + } + }; + } + } + class Persons extends ObservableArray { + static get items() { + return { type: type.convert(Person) }; + } + } + try { + let array = new Persons([ + { name: 'Matt' }, + { name: 'Kevin' } + ]); + array.splice(1, 1, { name: 'Justin' }); + assert.deepEqual(array[0].name, 'Matt', 'should have Matt'); + assert.ok(array[1] instanceof Person, 'should be an instance of Person'); + assert.deepEqual(array[1].name, 'Justin', 'should have Justin'); + } catch (e) { + assert.notOk(e, 'threw :('); + } + }); + QUnit.test('#67 Setting an item at an index', function (assert) { + class MyObject extends ObservableObject { + } + class MyArray extends ObservableArray { + static get items() { + return type.convert(MyObject); + } + } + let arr = new MyArray(); + arr.push({ num: 5 }); + assert.ok(arr[0] instanceof MyObject, 'Converts on a push'); + arr[0] = { num: 6 }; + assert.ok(arr[0] instanceof MyObject, 'Converts on an index setter'); + }); + QUnit.test('patches dispatched with converted members', function (assert) { + assert.expect(6); + const ObserveType = class extends ObservableObject { + }; + const TypedArray = class extends ObservableArray { + static get items() { + return type.convert(ObserveType); + } + }; + const observable = new TypedArray([]); + canReflect.onPatches(observable, function (patches) { + assert.ok(patches[0].insert[0] instanceof ObserveType, 'type is correct'); + assert.deepEqual(patches[0].insert[0].get(), { foo: 'bar' }, 'props copied over'); + }); + observable.push({ foo: 'bar' }); + observable.unshift({ foo: 'bar' }); + observable.splice(2, 0, { foo: 'bar' }); + }); + }; +}); +/*can-observable-array@1.1.4#test/propdefaults-test*/ +define('can-observable-array@1.1.4#test/propdefaults-test', [ + 'require', + 'exports', + 'module', + '../src/can-observable-array', + 'steal-qunit', + 'can-type' +], function (require, exports, module) { + const ObservableArray = require('../src/can-observable-array'); + const QUnit = require('steal-qunit'); + const type = require('can-type'); + module.exports = function () { + QUnit.module('ExendedObservableArray.propertyDefaults'); + QUnit.test('Does type conversion', function (assert) { + class Players extends ObservableArray { + static get propertyDefaults() { + return { type: type.convert(Number) }; + } + } + const team = new Players(); + team.rank = '5'; + assert.deepEqual(team.rank, 5); + }); + }; +}); +/*can-observable-array@1.1.4#test/steal-import-test*/ +define('can-observable-array@1.1.4#test/steal-import-test', [ + 'steal-qunit@2.0.0#steal-qunit', + 'can-observable-array@1.1.4#src/can-observable-array' +], function (_stealQunit, _canObservableArray) { + 'use strict'; + var _stealQunit2 = _interopRequireDefault(_stealQunit); + var _canObservableArray2 = _interopRequireDefault(_canObservableArray); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } + } + function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError('this hasn\'t been initialised - super() hasn\'t been called'); + } + return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === 'object' || typeof call === 'function') ? call : self; + } + function _inherits(subClass, superClass) { + if (typeof superClass !== 'function' && superClass !== null) { + throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass))); + } + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) + Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } + _stealQunit2.default.module('using steal import'); + _stealQunit2.default.test('it works', function (assert) { + var Todos = function (_ObservableArray) { + _inherits(Todos, _ObservableArray); + function Todos() { + _classCallCheck(this, Todos); + return _possibleConstructorReturn(this, (Todos.__proto__ || Object.getPrototypeOf(Todos)).apply(this, arguments)); + } + return Todos; + }(_canObservableArray2.default); + var todos = new Todos([ + { name: 'walk the dog' }, + { + name: 'cook dinner', + completed: true + } + ]); + assert.equal(todos.length, 2); + }); +}); +/*can-observable-array@1.1.4#test/test-no-class-fields*/ +define('can-observable-array@1.1.4#test/test-no-class-fields', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './array-test', + './items-test', + './propdefaults-test', + './steal-import-test' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + QUnit.module('can-observable-array', function () { + require('./array-test')(); + require('./items-test')(); + require('./propdefaults-test')(); + require('./steal-import-test'); + }); +}); +/*can-observable-bindings@1.3.3#test-helpers*/ +define('can-observable-bindings@1.3.3#test-helpers', function (require, exports, module) { + const helpers = { + browserSupports: { + customElements: 'customElements' in window, + shadowDom: typeof document.body.attachShadow === 'function' + } + }; + module.exports = helpers; +}); +/*can-observable-bindings@1.3.3#from-attribute-test*/ +define('can-observable-bindings@1.3.3#from-attribute-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './from-attribute', + './test-helpers', + 'can-type', + 'can-test-helpers' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const fromAttribute = require('./from-attribute'); + const browserSupports = require('./test-helpers').browserSupports; + const type = require('can-type'); + const dev = require('can-test-helpers').dev; + let fixture; + QUnit.module('can-observable-bindings - from-attribute', { + beforeEach() { + fixture = document.querySelector('#qunit-fixture'); + } + }); + if (browserSupports.customElements) { + QUnit.test('setting attribute will set property', function (assert) { + const attributes = [ + 'fname', + 'lname', + 'city' + ]; + const bindings = []; + let attributeChangedCallbackCount = 0; + class MyEl extends HTMLElement { + static get observedAttributes() { + return attributes; + } + } + attributes.forEach(attribute => { + bindings.push(fromAttribute(attribute, MyEl)); + }); + const originalCallback = MyEl.prototype.attributeChangedCallback; + MyEl.prototype.attributeChangedCallback = function () { + attributeChangedCallbackCount++; + originalCallback.apply(this, arguments); + }; + customElements.define('my-el', MyEl); + const el = document.createElement('my-el'); + fixture.appendChild(el); + bindings.forEach(bindFn => { + const binding = bindFn(el); + binding.start(); + }); + el.setAttribute('fname', 'Matt'); + el.setAttribute('lname', 'Chaffe'); + assert.equal(el.fname, 'Matt', 'Setting attribute sets a property'); + assert.equal(el.lname, 'Chaffe', 'Setting attribute sets a property'); + assert.equal(attributeChangedCallbackCount, 2, 'attributeChangedCallback fires twice'); + }); + QUnit.test('Does not set properties when attributes do not exist', function (assert) { + const attributes = ['fname']; + const bindings = []; + class MyEl extends HTMLElement { + get fname() { + } + set fname(val) { + assert.ok(!val, 'This should not be set'); + } + static get observedAttributes() { + return attributes; + } + } + attributes.forEach(attribute => { + bindings.push(fromAttribute(attribute, MyEl)); + }); + customElements.define('my-el-1', MyEl); + const el = document.createElement('my-el-1'); + fixture.appendChild(el); + bindings.forEach(bindFn => { + const binding = bindFn(el); + binding.start(); + }); + assert.strictEqual(el.fname, undefined, 'Property not set'); + }); + QUnit.test('Can pass a custom prop name', function (assert) { + const attributes = ['fname']; + const bindings = []; + class MyEl extends HTMLElement { + static get observedAttributes() { + return ['my-prop']; + } + } + attributes.forEach(attribute => { + const makeFromAttribute = fromAttribute('my-prop'); + bindings.push(makeFromAttribute(attribute, MyEl)); + }); + customElements.define('my-el-2', MyEl); + const el = document.createElement('my-el-2'); + fixture.appendChild(el); + bindings.forEach(bindFn => { + const binding = bindFn(el); + binding.start(); + }); + el.setAttribute('my-prop', 'Matt'); + assert.strictEqual(el.fname, 'Matt', 'Property is set'); + }); + QUnit.test('Can handle camelCase props', function (assert) { + const attributes = ['firstName']; + const bindings = []; + class MyEl extends HTMLElement { + static get observedAttributes() { + return attributes; + } + } + attributes.forEach(attribute => { + bindings.push(fromAttribute(attribute, MyEl)); + }); + customElements.define('my-el-3', MyEl); + const el = document.createElement('my-el-3'); + fixture.appendChild(el); + bindings.forEach(bindFn => { + const binding = bindFn(el); + binding.start(); + }); + el.setAttribute('first-name', 'Matt'); + assert.strictEqual(el.firstName, 'Matt', 'Property is set'); + }); + QUnit.test('Converts to a type by default', function (assert) { + const tag = 'convert-this-prop-please'; + const attributes = ['age']; + const bindings = []; + class MyEl extends HTMLElement { + static get observedAttributes() { + return attributes; + } + static [Symbol.for('can.getSchema')]() { + return { keys: { age: type.check(Number) } }; + } + } + attributes.forEach(attribute => { + bindings.push(fromAttribute(attribute, MyEl)); + }); + customElements.define(tag, MyEl); + const el = document.createElement(tag); + fixture.appendChild(el); + bindings.forEach(bindFn => { + const binding = bindFn(el); + binding.start(); + }); + el.setAttribute('age', '13'); + assert.strictEqual(el.age, 13, 'Property is converted'); + }); + QUnit.test('Can pass a converter', function (assert) { + const attributes = ['info']; + const bindings = []; + class MyEl extends HTMLElement { + static get observedAttributes() { + return attributes; + } + } + attributes.forEach(attribute => { + const makeFromAttribute = fromAttribute(JSON); + bindings.push(makeFromAttribute(attribute, MyEl)); + }); + customElements.define('my-el-4', MyEl); + const el = document.createElement('my-el-4'); + fixture.appendChild(el); + fixture.appendChild(el); + bindings.forEach(bindFn => { + const binding = bindFn(el); + binding.start(); + }); + el.setAttribute('info', '{"foo": "bar"}'); + assert.deepEqual(el.info, { foo: 'bar' }, 'JSON is converted to object'); + }); + QUnit.test('Can pass an attribute name and a converter', function (assert) { + const attributes = ['info']; + const bindings = []; + class MyEl extends HTMLElement { + static get observedAttributes() { + return attributes; + } + } + attributes.forEach(attribute => { + const makeFromAttribute = fromAttribute(attribute, JSON); + bindings.push(makeFromAttribute(attribute, MyEl)); + }); + customElements.define('my-el-5', MyEl); + const el = document.createElement('my-el-5'); + fixture.appendChild(el); + fixture.appendChild(el); + bindings.forEach(bindFn => { + const binding = bindFn(el); + binding.start(); + }); + el.setAttribute('info', '{"foo": "bar"}'); + assert.deepEqual(el.info, { foo: 'bar' }, 'JSON is converted to object'); + }); + dev.devOnlyTest('Throws an error when the converter is not valid', function (assert) { + const attributes = ['info']; + const bindings = []; + class MyEl extends HTMLElement { + static get observedAttributes() { + return attributes; + } + } + attributes.forEach(attribute => { + try { + const makeFromAttribute = fromAttribute(attribute, {}); + bindings.push(makeFromAttribute(attribute, MyEl)); + assert.ok(true); + } catch (e) { + assert.ok(true, 'Throws when the wrong object converter is passed'); + } + }); + }); + QUnit.test('Works correctly if attribute is different from the attribute passed in setAttribute.', function (assert) { + const attributes = ['info']; + const bindings = []; + class MyEl extends HTMLElement { + static get observedAttributes() { + return ['my-attr']; + } + } + attributes.forEach(attribute => { + const makeFromAttribute = fromAttribute('my-attr', JSON); + bindings.push(makeFromAttribute(attribute, MyEl)); + }); + customElements.define('my-el-6', MyEl); + const el = document.createElement('my-el-6'); + fixture.appendChild(el); + bindings.forEach(bindFn => { + const binding = bindFn(el); + binding.start(); + }); + el.setAttribute('my-attr', '{"foo": "bar"}'); + assert.deepEqual(el.info, { foo: 'bar' }, 'JSON is converted to object'); + }); + QUnit.test('fromAttribute does not initialize with converted value (#18)', function (assert) { + const attributes = ['info']; + const bindings = []; + class MyEl extends HTMLElement { + static get observedAttributes() { + return ['my-attr']; + } + } + attributes.forEach(attribute => { + const makeFromAttribute = fromAttribute('my-attr', JSON); + bindings.push(makeFromAttribute(attribute, MyEl)); + }); + customElements.define('my-el-7', MyEl); + const el = document.createElement('my-el-7'); + el.setAttribute('my-attr', '5'); + fixture.appendChild(el); + bindings.forEach(bindFn => { + const binding = bindFn(el); + binding.startParent(); + assert.strictEqual(binding.parent.value, 5, 'initial value run through parser'); + }); + }); + } +}); +/*can-observable-bindings@1.3.3#test*/ +define('can-observable-bindings@1.3.3#test', ['can-observable-bindings@1.3.3#from-attribute-test'], function () { + 'use strict'; +}); +/*can-observable-object@1.1.4#test/can-observable-object-test*/ +define('can-observable-object@1.1.4#test/can-observable-object-test', [ + 'require', + 'exports', + 'module', + '../src/can-observable-object', + 'steal-qunit', + 'can-reflect' +], function (require, exports, module) { + const ObservableObject = require('../src/can-observable-object'); + const QUnit = require('steal-qunit'); + const canReflect = require('can-reflect'); + QUnit.module('can-observable-object'); + QUnit.test('Basics', function (assert) { + class Faves extends ObservableObject { + static get props() { + return { color: 'red' }; + } + } + let faves = new Faves(); + assert.equal(faves.color, 'red', 'yup'); + }); + QUnit.test('Passing undefined props into ObservableObject', function (assert) { + let inst = new ObservableObject({ a: 'b' }); + assert.equal(inst.a, 'b', 'passed them on'); + canReflect.onKeyValue(inst, 'a', function () { + assert.equal(inst.a, 'c'); + }); + inst.a = 'c'; + }); + QUnit.test('Passing undefined props into extended ObservableObject', function (assert) { + class ExtendedObservableObject extends ObservableObject { + } + let inst = new ExtendedObservableObject({ a: 'b' }); + assert.equal(inst.a, 'b', 'passed them on'); + canReflect.onKeyValue(inst, 'a', function () { + assert.equal(inst.a, 'c'); + }); + inst.a = 'c'; + }); + QUnit.test('Primitives can be provided as the default as the property value', function (assert) { + class Person extends ObservableObject { + static get props() { + return { + age: 13, + likesChocolate: false, + favoriteColor: 'green' + }; + } + } + let person = new Person(); + assert.equal(person.age, 13, 'Number works'); + assert.equal(person.likesChocolate, false, 'Boolean works'); + assert.equal(person.favoriteColor, 'green', 'Strings work'); + }); +}); +/*can-observable-object@1.1.4#test/import-steal-test*/ +define('can-observable-object@1.1.4#test/import-steal-test', [ + 'steal-qunit@2.0.0#steal-qunit', + 'can-observable-object@1.1.4#src/can-observable-object' +], function (_stealQunit, _canObservableObject) { + 'use strict'; + var _stealQunit2 = _interopRequireDefault(_stealQunit); + var _canObservableObject2 = _interopRequireDefault(_canObservableObject); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj; + }; + var _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) + descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + return function (Constructor, protoProps, staticProps) { + if (protoProps) + defineProperties(Constructor.prototype, protoProps); + if (staticProps) + defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } + } + function _possibleConstructorReturn(self, call) { + if (!self) { + throw new ReferenceError('this hasn\'t been initialised - super() hasn\'t been called'); + } + return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === 'object' || typeof call === 'function') ? call : self; + } + function _inherits(subClass, superClass) { + if (typeof superClass !== 'function' && superClass !== null) { + throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass))); + } + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) + Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + } + _stealQunit2.default.module('can-observable-object with steal import'); + _stealQunit2.default.test('it works', function (assert) { + var Faves = function (_ObservableObject) { + _inherits(Faves, _ObservableObject); + function Faves() { + _classCallCheck(this, Faves); + return _possibleConstructorReturn(this, (Faves.__proto__ || Object.getPrototypeOf(Faves)).apply(this, arguments)); + } + _createClass(Faves, null, [{ + key: 'props', + get: function get() { + return { color: 'red' }; + } + }]); + return Faves; + }(_canObservableObject2.default); + var faves = new Faves(); + assert.equal(faves.color, 'red', 'yup'); + }); +}); +/*can-observable-object@1.1.4#test/test-no-class-fields*/ +define('can-observable-object@1.1.4#test/test-no-class-fields', [ + 'require', + 'exports', + 'module', + './can-observable-object-test', + './import-steal-test' +], function (require, exports, module) { + require('./can-observable-object-test'); + require('./import-steal-test'); +}); +/*can-observable-mixin@1.0.10#test/create-constructor-function-test*/ +define('can-observable-mixin@1.0.10#test/create-constructor-function-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../src/mixins' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const {createConstructorFunction} = require('../src/mixins'); + QUnit.module('can-observable-mixin - createConstructorFunction'); + QUnit.test('basics', function (assert) { + class Foo { + static get bar() { + return 'bar'; + } + static getIndex() { + return 0; + } + static get [Symbol.species]() { + return this; + } + } + const FooConstructor = createConstructorFunction(Foo); + assert.equal(FooConstructor.bar, 'bar', 'should keep static props'); + assert.ok(FooConstructor[Symbol.species], 'should keep symbols'); + assert.equal(FooConstructor.getIndex(), 0, 'should keep static methods'); + }); + QUnit.test('walks up the prototype chain', function (assert) { + class Foo { + static get bar() { + return 'bar'; + } + static getIndex() { + return 0; + } + static get [Symbol.species]() { + return this; + } + } + const Bar = Object.create(Foo); + const BarConstructor = createConstructorFunction(Bar); + assert.equal(BarConstructor.bar, 'bar', 'should keep static props'); + assert.ok(BarConstructor[Symbol.species], 'should keep symbols'); + assert.equal(BarConstructor.getIndex(), 0, 'should keep static methods'); + }); + QUnit.test('it should keep static getters', function (assert) { + class Foo { + static get foo() { + return 'foo'; + } + } + const Bar = Object.create(Foo); + const BarConstructor = createConstructorFunction(Bar); + assert.equal(BarConstructor.foo, 'foo', 'should keep the static foo getter'); + }); + QUnit.test('it should keep property descriptors', function (assert) { + class Foo { + static get foo() { + return 'foo'; + } + } + const Bar = Object.create(Foo); + const BarConstructor = createConstructorFunction(Bar); + assert.deepEqual(Object.getOwnPropertyDescriptor(Foo, 'foo'), Object.getOwnPropertyDescriptor(BarConstructor, 'foo'), 'should be the same descriptor'); + }); + QUnit.test('can stop prototype chain walk at indicated object', function (assert) { + class Foo { + static get foo() { + return 'bar'; + } + } + const Bar = Object.create(Foo); + Bar.getIndex = () => 10; + Bar[Symbol.for('can.new')] = () => true; + const Baz = Object.create(Bar); + const BazConstructor = createConstructorFunction(Baz, Foo); + assert.equal(typeof BazConstructor.foo, 'undefined', 'should not walk up to Foo'); + assert.ok(BazConstructor[Symbol.for('can.new')], 'should keep symbols'); + assert.equal(BazConstructor.getIndex(), 10, 'should keep static methods'); + }); + QUnit.test('Symbol.species should work on the constructor', function (assert) { + class MyArray extends Array { + static get [Symbol.species]() { + return Array; + } + } + const MyArrayConstructor = createConstructorFunction(MyArray); + const array = new MyArrayConstructor(); + assert.ok(array instanceof Array); + }); +}); +/*can-observable-mixin@1.0.10#test/helpers*/ +define('can-observable-mixin@1.0.10#test/helpers', [ + 'require', + 'exports', + 'module', + '../src/define', + '../src/mixin-mapprops', + '../src/mixin-proxy', + '../src/mixin-typeevents' +], function (require, exports, module) { + const {hooks, makeDefineInstanceKey} = require('../src/define'); + const mixinMapProps = require('../src/mixin-mapprops'); + const mixinProxy = require('../src/mixin-proxy'); + const mixinTypeEvents = require('../src/mixin-typeevents'); + exports.mixinObject = function (Base = Object) { + let ChildClass = class extends mixinProxy(Base) { + constructor(props) { + super(); + hooks.finalizeClass(this.constructor); + hooks.initialize(this, props); + } + }; + ChildClass = mixinTypeEvents(mixinMapProps(ChildClass)); + makeDefineInstanceKey(ChildClass); + return ChildClass; + }; +}); +/*can-observable-mixin@1.0.10#test/props-mixin-test*/ +define('can-observable-mixin@1.0.10#test/props-mixin-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-reflect', + 'can-type', + 'can-test-helpers' +], function (require, exports, module) { + 'use strict'; + const QUnit = require('steal-qunit'); + const {mixinObject} = require('./helpers'); + const canReflect = require('can-reflect'); + const types = require('can-type'); + const dev = require('can-test-helpers').dev; + QUnit.module('can-observable-mixin - mixins(Object)'); + QUnit.test('Can define properties', function (assert) { + class Faves extends mixinObject() { + static get props() { + return { color: { default: 'blue' } }; + } + } + let faves = new Faves(); + assert.equal(faves.color, 'blue', 'Got the value'); + }); + QUnit.test('Changes are observed', function (assert) { + class Faves extends mixinObject() { + static get props() { + return { color: { default: 'blue' } }; + } + } + let faves = new Faves(); + canReflect.onKeyValue(faves, 'color', () => { + assert.equal(faves.color, 'red'); + }); + faves.color = 'red'; + }); + QUnit.test('async(resolve) resolves async values', function (assert) { + let done = assert.async(); + class Faves extends mixinObject() { + static get props() { + return { + age: { + async(resolve, last = 1) { + this.birthday.then(() => { + resolve(last + 1); + }); + } + } + }; + } + get birthday() { + return Promise.resolve(); + } + } + let faves = new Faves(); + canReflect.onKeyValue(faves, 'age', value => { + assert.equal(value, 2, 'Age set when `resolve` is called'); + done(); + }); + }); + QUnit.test('async() returning a promise resolves', function (assert) { + let done = assert.async(); + class Faves extends mixinObject() { + static get props() { + return { + age: { + async(resolve, last = 1) { + return Promise.resolve(this.birthday).then(() => last + 1); + } + } + }; + } + get birthday() { + return Promise.resolve(); + } + } + let faves = new Faves(); + assert.equal(faves.age, undefined, 'Age has correct initial value'); + canReflect.onKeyValue(faves, 'age', value => { + assert.equal(value, 2, 'Age set when promise resolves'); + done(); + }); + }); + QUnit.test('listenTo to listen to property changes', function (assert) { + class Faves extends mixinObject() { + static get props() { + return { color: {} }; + } + } + let faves = new Faves(); + faves.listenTo('color', function () { + assert.equal(faves.color, 'red', 'got the change'); + }); + faves.color = 'red'; + }); + QUnit.test('value(prop) can be used to resolve a property based on others', function (assert) { + class Person extends mixinObject() { + static get props() { + return { + isBirthday: { default: false }, + age: { + value({listenTo, resolve}) { + let current = 1; + listenTo('isBirthday', isBirthday => { + if (isBirthday) { + resolve(current = current + 1); + } + }); + resolve(current); + } + } + }; + } + } + let p = new Person(); + canReflect.onKeyValue(p, 'age', function () { + assert.equal(p.age, 2, 'Now is two'); + }); + p.isBirthday = true; + }); + QUnit.test('getSchema returns the schema', function (assert) { + class Faves extends mixinObject() { + static get props() { + return { age: {} }; + } + } + let schema = canReflect.getSchema(Faves); + assert.deepEqual(Object.keys(schema.keys), ['age'], 'has the schema'); + }); + QUnit.test('getSchema still works when further deriving', function (assert) { + class Base extends mixinObject() { + } + class Faves extends Base { + static get props() { + return { age: {} }; + } + } + let schema = canReflect.getSchema(Faves); + assert.deepEqual(Object.keys(schema.keys), ['age'], 'has the schema'); + }); + QUnit.test('Does not throw if no define is provided', function (assert) { + class Faves extends mixinObject() { + } + assert.ok(true, 'Did not throw'); + }); + QUnit.test('JavaScript setters work', function (assert) { + class Faves extends mixinObject() { + static get props() { + return {}; + } + set color(v) { + return 'blue'; + } + } + let faves = new Faves(); + faves.color = 'red'; + assert.equal(faves.color, 'blue', 'Did not change'); + }); + QUnit.test('Setters on the define override those on the prototype', function (assert) { + class Faves extends mixinObject() { + static get props() { + return { + color: { + enumerable: false, + set(v) { + return 'green'; + } + } + }; + } + set color(v) { + return 'blue'; + } + } + let faves = new Faves(); + faves.color = 'red'; + assert.equal(faves.color, 'green', 'Changed to green'); + let props = []; + for (let prop in faves) { + props.push(prop); + } + assert.deepEqual(props, [], 'Not enumerable too'); + }); + QUnit.test('set() can return a different value', function (assert) { + class Faves extends mixinObject() { + static get props() { + return { + color: { + set() { + return 'blue'; + } + } + }; + } + } + let faves = new Faves(); + faves.color = 'red'; + assert.equal(faves.color, 'blue', 'Did not change'); + }); + QUnit.test('Passing props into the constructor', function (assert) { + class Person extends mixinObject() { + static get props() { + return { age: { default: 1 } }; + } + } + assert.equal(new Person().age, 1, 'the default'); + assert.equal(new Person({ age: 2 }).age, 2, 'can be passed as a prop'); + }); + QUnit.test('seal: false prevents the object from being sealed', function (assert) { + class Thing extends mixinObject() { + static get seal() { + return false; + } + } + let p = new Thing(); + p.set('expando', 11); + canReflect.onKeyValue(p, 'expando', () => { + assert.equal(p.get('expando'), 15, 'Not sealed'); + }); + p.set('expando', 15); + }); + QUnit.test('enumerable: false prevents the property from being enumerable', function (assert) { + class Thing extends mixinObject() { + static get props() { + return { + shouldEnumerate: { default: 'foo' }, + shouldNotEnumerate: { + default: 'bar', + enumerable: false + } + }; + } + } + let thing = new Thing(); + let enumerated = []; + for (let prop in thing) { + enumerated.push(prop); + } + assert.deepEqual(enumerated, ['shouldEnumerate'], 'Only enumerable properties'); + }); + QUnit.test('canReflect.hasKey works', function (assert) { + class Thing extends mixinObject() { + static get props() { + return { + prop: String, + derivedProp: { + get: function () { + if (this.prop) { + return this.prop + ' World'; + } + } + } + }; + } + } + let thing = new Thing({ prop: 'Hello' }); + let testCases = [ + { + method: 'hasKey', + prop: 'prop', + expected: true + }, + { + method: 'hasKey', + prop: 'derivedProp', + expected: true + } + ]; + testCases.forEach(function (test) { + assert.equal(canReflect[test.method](thing, test.prop), test.expected, 'canReflect.' + test.method + '(thing, \'' + test.prop + '\') should be ' + test.expected); + }); + }); + QUnit.test('setters get the lastSet value', function (assert) { + let setLastSet; + class Faves extends mixinObject() { + static get props() { + return { + food: { + set(newValue, lastSet) { + setLastSet = lastSet; + return newValue; + } + } + }; + } + } + let faves = new Faves(); + faves.food = 'pizza'; + faves.food = 'pie'; + assert.equal(setLastSet, 'pizza', 'lastSet provided to the setter'); + }); + QUnit.test('propertyDefaults becomes the default properties', function (assert) { + class Person extends mixinObject() { + static get propertyDefaults() { + return { type: types.convert(Number) }; + } + } + let p = new Person({ age: '32' }); + assert.deepEqual(p.age, 32, 'Converted because of defaults'); + }); + QUnit.test('propertyDefaults runs on expando properties', function (assert) { + class Player extends mixinObject() { + static get propertyDefaults() { + return { type: types.convert(Number) }; + } + } + let p = new Player(); + p.age = '32'; + assert.deepEqual(p.age, 32, 'Converted because of defaults'); + }); + dev.devOnlyTest('Adding expando properties on sealed objects', function (assert) { + class MyType extends mixinObject() { + static get props() { + return { myProp: String }; + } + static get seal() { + return true; + } + } + const myType = new MyType(); + try { + myType.otherProp = 'value'; + assert.ok(false, 'Should have thrown'); + } catch (e) { + assert.ok(true, 'Threw because it is sealed'); + } + }); + QUnit.test('getters on the define object work', function (assert) { + class MyType extends mixinObject() { + static get props() { + return { + noun: 'World', + get greeting() { + return `Hello ${ this.noun }`; + } + }; + } + } + const myType = new MyType(); + assert.equal(myType.greeting, 'Hello World'); + }); + QUnit.test('Error for required properties includes the function name', function (assert) { + class MySpecialThing extends mixinObject() { + static get props() { + return { prop: { required: true } }; + } + } + try { + new MySpecialThing({}); + } catch (err) { + assert.ok(/MySpecialThing/.test(err.message), 'Required message includes the funtion name'); + } + }); + QUnit.test('Warn of async(resolve) is an async function', function (assert) { + class MyThing extends mixinObject() { + static get props() { + return { + todos: { + async async(resolve) { + } + } + }; + } + } + let count = dev.willWarn(/async function/); + new MyThing(); + assert.equal(count(), 1, '1 warning'); + }); + dev.devOnlyTest('warnings are given when type or default is ignored', function (assert) { + const testCases = [ + { + name: 'zero-arg getter, no setter when property is set', + definition: { + get() { + return 'whatever'; + } + }, + warning: /Set value for property .* ignored/, + setProp: true, + expectedWarnings: 1 + }, + { + name: 'type with zero-arg getter, no setter', + definition: { + type: String, + get() { + return 'whatever'; + } + }, + warning: /type value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'only default type with zero-arg getter, no setter - should not warn', + definition: { + get() { + return 'whatever'; + } + }, + warning: /type value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'type with zero-arg getter, with setter - should not warn', + definition: { + type: String, + get() { + return 'whatever'; + }, + set(val) { + return val; + } + }, + warning: /type value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'default with zero-arg getter, no setter', + definition: { + default: 'some thing', + get() { + return 'whatever'; + } + }, + warning: /default value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'default with zero-arg getter, with setter - should not warn', + definition: { + default: 'some thing', + get() { + return 'whatever'; + }, + set(val) { + return val; + } + }, + warning: /default value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + } + ]; + testCases.forEach(testCase => { + let Obj = class extends mixinObject() { + static get props() { + return { prop: testCase.definition }; + } + }; + let count = dev.willWarn(testCase.warning); + let o = new Obj(); + if (testCase.setProp) { + o.prop = 'a value'; + } + assert.equal(count(), testCase.expectedWarnings, `got correct number of warnings for "${ testCase.name }"`); + }); + }); + QUnit.test('Properties can be deleted', function (assert) { + const MyObject = class extends mixinObject() { + }; + let obj = new MyObject({ + foo: 'foo', + bar: 'bar', + qux: 'qux' + }); + canReflect.deleteKeyValue(obj, 'foo'); + assert.equal(obj.foo, undefined, 'no longer exists'); + obj.foo = 'test'; + assert.equal(obj.foo, 'test', 'can add back'); + obj.deleteKey('bar'); + assert.equal(obj.bar, undefined, 'no longer exists'); + assert.equal(Object.keys(obj).length, 2, '2 props now'); + obj.bar = 'test'; + assert.equal(obj.bar, 'test', 'can add back'); + }); + QUnit.test('ownKeys only gets keys of props', function (assert) { + class MyType extends mixinObject() { + static get props() { + return { + fullName: { + get() { + return this.first + ' ' + this.last; + } + } + }; + } + } + let type = new MyType({ + first: 'Matthew', + last: 'Phillips' + }); + let keys = canReflect.getOwnKeys(type); + assert.deepEqual(keys, [ + 'first', + 'last', + 'fullName' + ]); + }); +}); +/*can-observable-mixin@1.0.10#test/props-test*/ +define('can-observable-mixin@1.0.10#test/props-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + '../src/define', + 'can-reflect' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const {mixinObject} = require('./helpers'); + const {hooks} = require('../src/define'); + const canReflect = require('can-reflect'); + QUnit.module('can-observable-mixin - props()'); + QUnit.test('Can define stuff', function (assert) { + class Faves extends mixinObject() { + static get props() { + return { color: { default: 'blue' } }; + } + } + let faves = new Faves(); + assert.equal(faves.color, 'blue', 'Got the value'); + }); + QUnit.test('Does not throw if no define is provided', function (assert) { + class Faves extends mixinObject() { + } + new Faves(); + assert.ok(true, 'Did not throw'); + }); + QUnit.test('Stuff is defined in constructor for non-element classes', function (assert) { + class Faves extends mixinObject(Object) { + static get props() { + return { color: { default: 'blue' } }; + } + constructor() { + super(); + assert.equal(this.color, 'blue', 'color exists after constructor'); + } + } + new Faves(); + }); + QUnit.test('Default strings work when they are like can-define types', function (assert) { + class Person extends mixinObject() { + static get props() { + return { someProp: 'number' }; + } + } + let p = new Person(); + assert.equal(p.someProp, 'number', 'Is the string \'number\''); + }); + QUnit.test('initialize can be called multiple times if Symbol is reset', function (assert) { + const metaSymbol = Symbol.for('can.meta'); + class Obj extends mixinObject() { + static get props() { + return { age: Number }; + } + } + const obj = new Obj({ age: 30 }); + assert.equal(obj.age, 30, 'initialized once by constructor'); + obj[metaSymbol].initialized = false; + hooks.initialize(obj, { age: 35 }); + assert.equal(obj.age, 35, 'initialized again'); + }); + QUnit.test('defineInstanceKey does not add to the base prototype', function (assert) { + const Base = mixinObject(); + class Obj extends Base { + } + canReflect.defineInstanceKey(Obj, '_saving', { + configurable: true, + default: false, + enumerable: false, + writable: true + }); + new Obj(); + let desc = Object.getOwnPropertyDescriptor(Base.prototype, '_saving'); + assert.ok(!desc, 'There is no descriptor on the Base class'); + }); +}); +/*can-observable-mixin@1.0.10#test/props-types-test*/ +define('can-observable-mixin@1.0.10#test/props-types-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-reflect', + './helpers', + 'can-type', + 'can-test-helpers' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const canReflect = require('can-reflect'); + const {mixinObject} = require('./helpers'); + const types = require('can-type'); + const dev = require('can-test-helpers').dev; + const ObservableObject = mixinObject(); + QUnit.module('can-observable-mixin - Types'); + function strictEqual(instance, props) { + QUnit.assert.strictEqual(instance.prop, props.prop, 'Prop added exactly'); + } + function equal(instance, props) { + QUnit.assert.equal(instance.prop, props.prop, 'Prop added exactly'); + } + function propEqualTo(expectedValue) { + return function (instance) { + QUnit.assert.equal(instance.prop, expectedValue, `Prop is value ${ expectedValue }`); + }; + } + function isNaN(instance) { + QUnit.assert.ok(Number.isNaN(instance.prop), 'Is NaN value'); + } + function ok(reason = 'Expected to throw') { + QUnit.assert.ok(true, reason); + } + function notOk(reason = 'Should not have thrown') { + QUnit.assert.ok(false, reason); + } + function throwBecauseRequired(props, err) { + let isFromRequired = /required/.test(err.message); + QUnit.assert.ok(isFromRequired, 'Failed expectedly because missing required properties'); + } + const throwsBecauseOfWrongType = ok.bind(null, 'Throws when the wrong type is provided'); + const shouldHaveThrownBecauseRequired = notOk.bind(null, 'Should have thrown because required.'); + const shouldNotThrowBecauseShouldConvert = notOk.bind(null, 'This should not have thrown, should have converted'); + let matrix = { + maybeConvertNotRequired: { + method: 'maybeConvert', + check: equal, + throws: shouldNotThrowBecauseShouldConvert + }, + maybeConvertRequired: { + method: 'maybeConvert', + required: true, + check: equal, + throws: shouldNotThrowBecauseShouldConvert + }, + convertNotRequired: { + method: 'convert', + check: equal, + throws: shouldNotThrowBecauseShouldConvert + }, + convertRequired: { + method: 'convert', + required: true, + check: equal, + throws: shouldNotThrowBecauseShouldConvert + } + }; + if ("production" !== 'production') { + canReflect.assignMap(matrix, { + checkNoMaybeNotRequired: { + method: 'check', + check: strictEqual, + throws: throwsBecauseOfWrongType + }, + checkNoMaybeRequired: { + method: 'check', + required: true, + check: strictEqual, + throws: throwsBecauseOfWrongType + }, + maybeNotRequired: { + method: 'maybe', + check: strictEqual, + throws: throwsBecauseOfWrongType + }, + maybeRequired: { + method: 'maybe', + required: true, + check: strictEqual, + throws: throwsBecauseOfWrongType + } + }); + } + let checkIsNaN = { check: isNaN }; + let checkDateMatchesNumber = { + check: function (instance, props) { + let date = instance.prop; + let num = props.prop; + QUnit.assert.strictEqual(date.getTime(), num, 'Converted number to date'); + } + }; + let expectedToThrowBecauseRequired = { + check: shouldHaveThrownBecauseRequired, + throws: throwBecauseRequired + }; + let dateAsNumber = new Date(1815, 11, 10).getTime(); + let cases = [ + { + type: Number, + value: 36 + }, + { + type: Number, + value: 'not a number', + maybeConvertNotRequired: checkIsNaN, + maybeConvertRequired: checkIsNaN, + convertNotRequired: checkIsNaN, + convertRequired: checkIsNaN + }, + { + type: String, + value: 'some string' + }, + { + type: Boolean, + value: true + }, + { + type: Date, + value: new Date(1815, 11, 10) + }, + { + type: Date, + value: dateAsNumber, + maybeConvertNotRequired: checkDateMatchesNumber, + maybeConvertRequired: checkDateMatchesNumber, + convertNotRequired: checkDateMatchesNumber, + convertRequired: checkDateMatchesNumber + }, + { + type: Number, + value: '36' + }, + { + type: Number, + value: null, + convertNotRequired: { check: propEqualTo(0) }, + convertRequired: { check: propEqualTo(0) } + }, + { + type: Number, + value: undefined, + convertNotRequired: checkIsNaN, + convertRequired: checkIsNaN + }, + { + type: Number, + checkNoMaybeRequired: expectedToThrowBecauseRequired, + maybeRequired: expectedToThrowBecauseRequired, + maybeConvertRequired: expectedToThrowBecauseRequired, + convertRequired: expectedToThrowBecauseRequired + } + ]; + cases.forEach(testCase => { + let {type, value} = testCase; + let hasValue = 'value' in testCase; + for (let [caseName, caseDefinition] of Object.entries(matrix)) { + let typeName = canReflect.getName(type); + let testName = `${ typeName } - ${ caseName } - value (${ !hasValue ? 'NO VALUE' : typeof value === 'string' ? `"${ value }"` : value })`; + QUnit.test(testName, function () { + class MyType extends ObservableObject { + static get props() { + return { + prop: { + type: types[caseDefinition.method](type), + required: caseDefinition.required || false + } + }; + } + } + let props = {}; + if (hasValue) { + props.prop = value; + } + try { + let inst = new MyType(props); + if (testCase[caseName] && testCase[caseName].check) { + testCase[caseName].check(inst, props); + } else { + caseDefinition.check(inst, props); + } + } catch (err) { + if (testCase[caseName] && testCase[caseName].throws) { + testCase[caseName].throws(props, err); + } else { + caseDefinition.throws(props, err); + } + } + }); + } + }); + QUnit.test('Can pass common/primitive types as the type option', function (assert) { + class MyThing extends ObservableObject { + static get props() { + return { + num: Number, + str: String, + bool: Boolean, + date: Date + }; + } + } + let now = new Date(); + let thing = new MyThing({ + num: 33, + str: 'Hello world', + bool: false, + date: now + }); + assert.equal(thing.num, 33, 'Number accepted'); + assert.equal(thing.str, 'Hello world', 'String accepted'); + assert.equal(thing.bool, false, 'Boolean accepted'); + assert.equal(thing.date, now, 'Passed a date'); + }); + QUnit.test('Can pass common/primitive types in a property definition', function (assert) { + class MyThing extends ObservableObject { + static get props() { + return { + num: Number, + numProp: { type: Number }, + numPropWithDefault: { + type: Number, + default: 33 + } + }; + } + } + let thing = new MyThing({ + num: 33, + numProp: 33 + }); + assert.strictEqual(thing.num, 33, 'prop: Number works'); + assert.strictEqual(thing.numProp, 33, '{ type: Number } works'); + assert.strictEqual(thing.numPropWithDefault, 33, '{ type: Number, default: } works'); + }); + dev.devOnlyTest('types throw when value is set to a different type', function (assert) { + function Thing() { + } + Thing.prototype = Object.create(Thing); + class ExtendedObservableObject extends ObservableObject { + } + class Defined extends ObservableObject { + static get props() { + return { + num: Number, + str: String, + bool: Boolean, + date: Date, + numDefinition: { type: Number }, + strDefinition: { type: String }, + boolDefinition: { type: Boolean }, + dateDefinition: { type: Date }, + thing: Thing, + defineObject: ObservableObject, + extendedObservableObject: ExtendedObservableObject, + thingDefinition: { type: Thing }, + defineObjectDefinition: { type: ObservableObject }, + extendedObservableObjectDefinition: { type: ExtendedObservableObject } + }; + } + } + let now = new Date(); + const testCases = { + num: '33', + str: 33, + bool: 'not a boolean', + date: now.toString(), + numDefinition: '33', + strDefinition: 33, + boolDefinition: 'not a boolean', + dateDefinition: now.toString(), + thing: {}, + defineObject: {}, + extendedObservableObject: {}, + thingDefinition: {}, + defineObjectDefinition: {}, + extendedObservableObjectDefinition: {} + }; + canReflect.eachKey(testCases, function (value, prop) { + try { + new Defined({ [prop]: value }); + assert.ok(false, `${ prop } = ${ value } should throw but didn't`); + } catch (err) { + assert.ok(true, 'should throw: ' + err); + } + }); + }); + QUnit.test('Can pass Function as the type option', function (assert) { + assert.expect(2); + class MyThing extends ObservableObject { + static get props() { + return { func: Function }; + } + } + let thing = new MyThing({ + func: function () { + return 33; + } + }); + assert.equal(thing.func(), 33, 'function accepted'); + thing.func = function () { + return 30; + }; + assert.equal(thing.func(), 30, 'function can be overwritten'); + }); + dev.devOnlyTest('Function as the type option type checks', function (assert) { + assert.expect(1); + class MyThing extends ObservableObject { + static get props() { + return { func: Function }; + } + } + let thing = new MyThing({ + func: function () { + return 33; + } + }); + try { + thing.func = 50; + } catch (e) { + assert.ok(true, 'error thrown when set to non-function'); + } + }); + QUnit.test('Can pass Function in a property definition', function (assert) { + assert.expect(6); + class MyThing extends ObservableObject { + static get props() { + return { + func: Function, + funcProp: { type: Function }, + funcPropWithDefault: { + type: Function, + default() { + return 33; + } + } + }; + } + } + let thing = new MyThing({ + func: function () { + return 33; + }, + funcProp: function () { + return 33; + } + }); + assert.strictEqual(thing.func(), 33, 'prop: Function works'); + assert.strictEqual(thing.funcProp(), 33, '{ type: Function } works'); + assert.strictEqual(thing.funcPropWithDefault(), 33, '{ type: Function, default: } works'); + thing.func = function () { + return 30; + }; + thing.funcProp = function () { + return 30; + }; + thing.funcPropWithDefault = function () { + return 30; + }; + assert.strictEqual(thing.func(), 30, 'prop: Function can be overwritten'); + assert.strictEqual(thing.funcProp(), 30, '{ type: Function } can be overwritten'); + assert.strictEqual(thing.funcPropWithDefault(), 30, '{ type: Function, default: } can be overwritten'); + }); + dev.devOnlyTest('Function in a property definition type checks', function (assert) { + assert.expect(3); + class MyThing extends ObservableObject { + static get props() { + return { + func: Function, + funcProp: { type: Function }, + funcPropWithDefault: { + type: Function, + default() { + return 33; + } + } + }; + } + } + let thing = new MyThing({ + func: function () { + return 33; + }, + funcProp: function () { + return 33; + } + }); + try { + thing.func = 50; + } catch (e) { + assert.ok(true, 'prop: Function error thrown when set to non-function'); + } + try { + thing.funcProp = 50; + } catch (e) { + assert.ok(true, '{ type: Function } error thrown when set to non-function'); + } + try { + thing.funcPropWithDefault = 50; + } catch (e) { + assert.ok(true, '{ type: Function, default: } error thrown when set to non-function'); + } + }); +}); +/*can-observable-mixin@1.0.10#test/props-mixin-default-test*/ +define('can-observable-mixin@1.0.10#test/props-mixin-default-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-type', + 'can-test-helpers' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const {mixinObject} = require('./helpers'); + const type = require('can-type'); + const dev = require('can-test-helpers').dev; + const ObservableObject = mixinObject(); + QUnit.test('Primitives can be provided as the default in the PropDefinition', function (assert) { + assert.expect(6); + class Person extends ObservableObject { + static get props() { + return { + age: { default: 13 }, + likesChocolate: { default: false }, + favoriteColor: { default: 'green' } + }; + } + } + let person = new Person(); + assert.equal(person.age, 13, 'Number works'); + assert.equal(person.likesChocolate, false, 'Boolean works'); + assert.equal(person.favoriteColor, 'green', 'Strings work'); + person.age = 30; + person.likesChocolate = true; + person.favoriteColor = 'red'; + assert.equal(person.age, 30, 'Number can be set to another number'); + assert.equal(person.likesChocolate, true, 'Boolean can be set to another boolean'); + assert.equal(person.favoriteColor, 'red', 'Strings can be set to another string'); + }); + dev.devOnlyTest('Primitives can be provided as the default in the PropDefinition should type check', function (assert) { + assert.expect(3); + class Person extends ObservableObject { + static get props() { + return { + age: { default: 13 }, + likesChocolate: { default: false }, + favoriteColor: { default: 'green' } + }; + } + } + let person = new Person(); + try { + person.age = '50'; + } catch (e) { + assert.ok(true, 'Number cannot be set to a non-number'); + } + try { + person.likesChocolate = 'not a boolean'; + } catch (e) { + assert.ok(true, 'Boolean cannot be set to a non-boolean'); + } + try { + person.favoriteColor = undefined; + } catch (e) { + assert.ok(true, 'String cannot be set to a non-string'); + } + }); + QUnit.test('Primitives can be provided as the default as the property value', function (assert) { + assert.expect(6); + class Person extends ObservableObject { + static get props() { + return { + age: 13, + likesChocolate: false, + favoriteColor: 'green' + }; + } + } + let person = new Person(); + assert.equal(person.age, 13, 'Number works'); + assert.equal(person.likesChocolate, false, 'Boolean works'); + assert.equal(person.favoriteColor, 'green', 'Strings work'); + person.age = 30; + person.likesChocolate = true; + person.favoriteColor = 'red'; + assert.equal(person.age, 30, 'Number can be set to another number'); + assert.equal(person.likesChocolate, true, 'Boolean can be set to another boolean'); + assert.equal(person.favoriteColor, 'red', 'Strings can be set to another string'); + }); + dev.devOnlyTest('Primitives can be provided as the default as the property value should type check', function (assert) { + assert.expect(3); + class Person extends ObservableObject { + static get props() { + return { + age: 13, + likesChocolate: false, + favoriteColor: 'green' + }; + } + } + let person = new Person(); + try { + person.age = '50'; + } catch (e) { + assert.ok(true, 'Number cannot be set to a non-number'); + } + try { + person.likesChocolate = 'not a boolean'; + } catch (e) { + assert.ok(true, 'Boolean cannot be set to a non-boolean'); + } + try { + person.favoriteColor = undefined; + } catch (e) { + assert.ok(true, 'String cannot be set to a non-string'); + } + }); + dev.devOnlyTest('Primitives provided as the default sets the type as strict', function (assert) { + class Person extends ObservableObject { + static get props() { + return { age: 13 }; + } + } + let person = new Person(); + assert.equal(person.age, 13, 'Set the value'); + try { + person.age = 'fourteen'; + assert.ok(false, 'Should have thrown'); + } catch (e) { + assert.ok(true, 'Threw because its type number'); + } + }); + QUnit.test('Extended ObservableObjects can be used to set the type', function (assert) { + class One extends ObservableObject { + } + class Two extends ObservableObject { + static get props() { + return { one: One }; + } + } + let one = new One(); + let two = new Two({ one }); + assert.equal(two.one, one, 'Able to pass the instance'); + if ("production" !== 'production') { + try { + new Two({ one: {} }); + assert.ok(false, 'Should have thrown'); + } catch (e) { + assert.ok(true, 'Throws because it is a strict type'); + } + } + }); + QUnit.test('Allow a default object to be provided by using a getter', function (assert) { + class Thing extends ObservableObject { + static get props() { + return { + prop: { + get default() { + return { foo: 'bar' }; + } + } + }; + } + } + let one = new Thing(); + let two = new Thing(); + assert.deepEqual(one.prop, { foo: 'bar' }, 'Sets the default'); + assert.notEqual(one.prop, two.prop, 'Different instances'); + }); + QUnit.test('Functions can be provided as the default in the PropDefinition', function (assert) { + assert.expect(2); + class Person extends ObservableObject { + static get props() { + return { + getAge: { + default() { + return 13; + } + } + }; + } + } + let person = new Person(); + assert.equal(person.getAge(), 13, 'property is a function'); + person.getAge = function () { + return 30; + }; + assert.equal(person.getAge(), 30, 'function can be overwritten'); + }); + dev.devOnlyTest('Functions provided as the default in the PropDefinition should type check', function (assert) { + assert.expect(1); + class Person extends ObservableObject { + static get props() { + return { + getAge: { + default() { + return 13; + } + } + }; + } + } + let person = new Person(); + try { + person.getAge = 50; + } catch (e) { + assert.ok(true, 'setting property to a non-function throws an error'); + } + }); + QUnit.test('Functions can be provided as the default as the property value', function (assert) { + assert.expect(2); + class Person extends ObservableObject { + static get props() { + return { + getAge() { + return 13; + } + }; + } + } + let person = new Person(); + assert.equal(person.getAge(), 13, 'property is a function'); + person.getAge = function () { + return 30; + }; + assert.equal(person.getAge(), 30, 'function can be overwritten'); + }); + dev.devOnlyTest('Functions provided as the default as the property value should type check', function (assert) { + assert.expect(1); + class Person extends ObservableObject { + static get props() { + return { + getAge() { + return 13; + } + }; + } + } + let person = new Person(); + try { + person.getAge = 50; + } catch (e) { + assert.ok(true, 'setting property to a non-function throws an error'); + } + }); + QUnit.test('Primitives provided as the default are not strict if there is a propertyDefaults type', function (assert) { + assert.expect(4); + class Person extends ObservableObject { + static get propertyDefaults() { + return { type: type.Any }; + } + static get props() { + return { + age: 13, + ageProp: { default: 14 } + }; + } + } + let person = new Person(); + assert.equal(person.age, 13, 'Default for prop'); + assert.equal(person.ageProp, 14, 'Default for prop with definition'); + person.age = 'thirteen'; + assert.equal(person.age, 'thirteen', 'Setting the value of prop to another type works'); + person.ageProp = 'fourteen'; + assert.equal(person.ageProp, 'fourteen', 'Setting the value of prop with definition to another type works'); + }); + QUnit.test('Primitives provided as the default are not strict if they have a type', function (assert) { + assert.expect(4); + class Person extends ObservableObject { + static get props() { + return { + age: { + default: 13, + type: type.Any + }, + ageFunc: { + default() { + return 14; + }, + type: type.Any + } + }; + } + } + let person = new Person(); + assert.equal(person.age, 13, 'Default for primitive default'); + assert.equal(person.ageFunc(), 14, 'Default for function default'); + person.age = 'thirteen'; + assert.equal(person.age, 'thirteen', 'Setting the value of prop to another type works'); + person.ageFunc = 'fourteen'; + assert.equal(person.ageFunc, 'fourteen', 'Setting the value of prop to another type works'); + }); +}); +/*can-observable-mixin@1.0.10#test/props-mixin-new-test*/ +define('can-observable-mixin@1.0.10#test/props-mixin-new-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const {mixinObject} = require('./helpers'); + const ObservableObject = mixinObject(); + QUnit.test('Calling an extended ObservableObject with undefined props when sealed', function (assert) { + class Person extends ObservableObject { + static get seal() { + return true; + } + } + try { + new Person({ name: 'Matthew' }); + assert.ok(false, 'Should not have allowed these undefined properties'); + } catch (e) { + assert.ok(true, 'Throw because undefined props were passed'); + } + }); + QUnit.test('Calling an extended ObservableObject with undefined props when unsealed', function (assert) { + class Person extends ObservableObject { + static get seal() { + return false; + } + } + try { + let p = new Person({ name: 'Matthew' }); + assert.equal(p.name, 'Matthew', 'set the undefined property'); + } catch (e) { + assert.ok(false, 'Should have set these properties'); + } + }); + QUnit.test('Calling new ObservableObject does not interfere with extended types', function (assert) { + new ObservableObject(); + class Person extends ObservableObject { + static get props() { + return { age: 5 }; + } + } + let p = new Person(); + assert.equal(p.age, 5, 'Defaults applied'); + }); +}); +/*can-observable-mixin@1.0.10#test/array-mixin-test*/ +define('can-observable-mixin@1.0.10#test/array-mixin-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + '../src/mixin-mapprops' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const canSymbol = require('can-symbol'); + const mixinMapProps = require('../src/mixin-mapprops'); + QUnit.module('can-observable-mixin - mixins(Array)'); + QUnit.test('.update works', function (assert) { + class MyArray extends mixinMapProps(Array) { + } + let arr = new MyArray(); + arr.push(1, 2, 3, 4); + assert.equal(arr.length, 4); + arr.update([]); + assert.equal(arr.length, 0); + }); + QUnit.test('.updateDeep works', function (assert) { + class MyArray extends mixinMapProps(Array) { + } + let arr = new MyArray(); + arr.push(1, 2, 3, 4); + assert.equal(arr.length, 4); + arr.updateDeep([]); + assert.equal(arr.length, 0); + }); + QUnit.test('implements \'can.updateDeep\' symbol', function (assert) { + class MyArray extends mixinMapProps(Array) { + } + let arr = new MyArray(); + arr.push(1, 2, 3, 4); + assert.equal(typeof arr[canSymbol.for('can.updateDeep')], 'function'); + arr[canSymbol.for('can.updateDeep')]([]); + assert.equal(arr.length, 0); + }); +}); +/*can-reflect-tests@1.0.0#observables/map-like/type/define-instance-key*/ +define('can-reflect-tests@1.0.0#observables/map-like/type/define-instance-key', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeType) { + QUnit.test(name + ' canReflect.defineInstanceKey', function (assert) { + var Type = makeType(); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { + value: 0, + configurable: true, + writable: true, + enumerable: true + }); + var t = new Type(); + assert.equal(canReflect.getKeyValue(t, 'prop'), 0, 'default value used'); + canReflect.setKeyValue(t, 'prop', '5'); + t.prop = '5'; + assert.equal(t.prop, '5', 'value set'); + }); + }; +}); +/*can-reflect-tests@1.0.0#observables/map-like/type/define-instance-key-enumerable*/ +define('can-reflect-tests@1.0.0#observables/map-like/type/define-instance-key-enumerable', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeType) { + QUnit.test(name + ' canReflect.defineInstanceKey with enumerable', function (assert) { + var Type = makeType(); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { + configurable: true, + writable: true, + enumerable: true + }); + Type[canSymbol.for('can.defineInstanceKey')]('nonEnum', { + enumerable: false, + value: 0, + configurable: true, + writable: true + }); + var t = new Type(); + assert.equal(canReflect.getKeyValue(t, 'nonEnum'), 0, 'default value used'); + canReflect.setKeyValue(t, 'prop', '5'); + t.prop = '5'; + assert.equal(t.prop, '5', 'value set'); + assert.deepEqual(canReflect.serialize(t), { prop: '5' }, 'enumerable respected'); + }); + }; +}); +/*can-reflect-tests@1.0.0#observables/map-like/type/on-instance-bound-change*/ +define('can-reflect-tests@1.0.0#observables/map-like/type/on-instance-bound-change', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeType) { + QUnit.test(name + ' canReflect.onInstanceBoundChange', function (assert) { + var Type = makeType(); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { + configurable: true, + writable: true, + enumerable: true + }); + var calls = []; + function handler(obj, patches) { + calls.push([ + obj, + patches + ]); + } + Type[canSymbol.for('can.onInstanceBoundChange')](handler); + var instance = new Type({ prop: 'value' }); + var bindHandler = function () { + }; + canReflect.onKeyValue(instance, 'prop', bindHandler); + canReflect.offKeyValue(instance, 'prop', bindHandler); + Type[canSymbol.for('can.offInstanceBoundChange')](handler); + canReflect.onKeyValue(instance, 'prop', bindHandler); + canReflect.offKeyValue(instance, 'prop', bindHandler); + assert.deepEqual(calls, [ + [ + instance, + true + ], + [ + instance, + false + ] + ]); + }); + }; +}); +/*can-reflect-tests@1.0.0#observables/map-like/type/on-instance-patches*/ +define('can-reflect-tests@1.0.0#observables/map-like/type/on-instance-patches', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeType) { + QUnit.test(name + ' canReflect.onInstancePatches', function (assert) { + var Type = makeType(); + Type[canSymbol.for('can.defineInstanceKey')]('first', { + configurable: true, + writable: true, + enumerable: true + }); + Type[canSymbol.for('can.defineInstanceKey')]('last', { + configurable: true, + writable: true, + enumerable: true + }); + Type[canSymbol.for('can.defineInstanceKey')]('middle', { + configurable: true, + writable: true, + enumerable: true + }); + var calls = []; + function handler(obj, patches) { + calls.push([ + obj, + patches + ]); + } + Type[canSymbol.for('can.onInstancePatches')](handler); + var instance = new Type({ + first: 'Justin', + last: 'Meyer' + }); + canReflect.setKeyValue(instance, 'first', 'Payal'); + canReflect.setKeyValue(instance, 'last', 'Shah'); + canReflect.setKeyValue(instance, 'middle', 'p'); + Type[canSymbol.for('can.offInstancePatches')](handler); + canReflect.setKeyValue(instance, 'first', 'Ramiya'); + canReflect.setKeyValue(instance, 'last', 'Mayer'); + canReflect.setKeyValue(instance, 'middle', 'P'); + assert.deepEqual(calls, [ + [ + instance, + [{ + type: 'set', + key: 'first', + value: 'Payal' + }] + ], + [ + instance, + [{ + type: 'set', + key: 'last', + value: 'Shah' + }] + ], + [ + instance, + [{ + type: 'set', + key: 'middle', + value: 'p' + }] + ] + ]); + }); + }; +}); +/*can-reflect-tests@1.0.0#observables/map-like/type/type*/ +define('can-reflect-tests@1.0.0#observables/map-like/type/type', [ + 'require', + 'exports', + 'module', + './define-instance-key', + './define-instance-key-enumerable', + './on-instance-bound-change', + './on-instance-patches' +], function (require, exports, module) { + var defineInstanceKey = require('./define-instance-key'); + var defineInstanceKeyEnumerable = require('./define-instance-key-enumerable'); + var onInstanceBoundChange = require('./on-instance-bound-change'); + var onInstanceBatches = require('./on-instance-patches'); + module.exports = function (name, makeType) { + defineInstanceKey(name, makeType); + defineInstanceKeyEnumerable(name, makeType); + onInstanceBoundChange(name, makeType); + onInstanceBatches(name, makeType); + }; +}); +/*can-reflect-tests@1.0.0#observables/map-like/instance/on-event-get-set-delete-key*/ +define('can-reflect-tests@1.0.0#observables/map-like/instance/on-event-get-set-delete-key', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canReflect = require('can-reflect'); + module.exports = function (name, makeInstance) { + QUnit.test(name + ' onEvent, setKeyValue, getKeyValue, deleteKeyValue, getOwnKeys', function (assert) { + var instance = makeInstance(); + var events = []; + assert.notOk(canReflect.isBound(instance), 'not bound'); + canReflect.onEvent(instance, 'prop', function (event) { + events.push(event); + }); + assert.ok(canReflect.isBound(instance), 'bound'); + canReflect.setKeyValue(instance, 'prop', 'FIRST'); + canReflect.getOwnKeys(instance, ['prop'], '.getOwnKeys has set prop'); + assert.equal(canReflect.getKeyValue(instance, 'prop'), 'FIRST', '.getKeyValue'); + canReflect.deleteKeyValue(instance, 'prop'); + assert.equal(canReflect.getKeyValue(instance, 'prop'), undefined, '.deleteKeyValue made it undefined'); + assert.deepEqual(events.map(function (event) { + return { + action: event.action, + value: event.value, + oldValue: event.oldValue, + key: event.key, + target: instance + }; + }), [ + { + action: 'add', + value: 'FIRST', + oldValue: undefined, + key: 'prop', + target: instance + }, + { + action: 'delete', + value: undefined, + oldValue: 'FIRST', + key: 'prop', + target: instance + } + ], 'onEvent'); + assert.deepEqual(canReflect.getOwnEnumerableKeys(instance), [], '.getOwnKeys loses deleted prop'); + }); + }; +}); +/*can-observable-mixin@1.0.10#test/type-events-test*/ +define('can-observable-mixin@1.0.10#test/type-events-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-reflect', + 'can-reflect-tests/observables/map-like/type/type', + 'can-reflect-tests/observables/map-like/instance/on-event-get-set-delete-key' +], function (require, exports, module) { + 'use strict'; + const QUnit = require('steal-qunit'); + const {mixinObject} = require('./helpers'); + const canReflect = require('can-reflect'); + QUnit.module('can-observable-mixin Type events'); + require('can-reflect-tests/observables/map-like/type/type')('Defined', function () { + return class Type extends mixinObject() { + }; + }); + require('can-reflect-tests/observables/map-like/instance/on-event-get-set-delete-key')('ObservableObject', function () { + class Type extends mixinObject() { + } + return new Type(); + }); + QUnit.test('ObservableObject has onEvent', function (assert) { + assert.expect(3); + class Type extends mixinObject() { + } + assert.notOk(canReflect.isBound(Type), 'not bound'); + canReflect.onEvent(Type, 'created', function () { + assert.ok(true, 'event occured'); + }); + assert.ok(canReflect.isBound(Type), 'bound'); + Type.dispatch('created', { foo: 'bar' }); + }); +}); +/*can-observable-mixin@1.0.10#test/props-mixin-proxy-object-test*/ +define('can-observable-mixin@1.0.10#test/props-mixin-proxy-object-test', [ + 'require', + 'exports', + 'module', + './helpers', + '../src/define', + 'can-reflect', + 'can-observation-recorder', + 'can-type' +], function (require, exports, module) { + const {mixinObject} = require('./helpers'); + const addDefinedProps = require('../src/define'); + const {hooks} = addDefinedProps; + const canReflect = require('can-reflect'); + const ObservationRecorder = require('can-observation-recorder'); + const type = require('can-type'); + const ObservableObject = mixinObject(); + QUnit.module('can-observable-mixin - Proxy Objects'); + QUnit.test('Can bind on properties not defined', function (assert) { + class Favorites extends ObservableObject { + } + let faves = new Favorites(); + canReflect.onKeyValue(faves, 'food', function () { + assert.ok(true); + }); + faves.food = 'pizza'; + }); + QUnit.test('Can listen to changes when listening to undefined props', function (assert) { + let map = new ObservableObject(); + ObservationRecorder.start(); + map.first; + let records = ObservationRecorder.stop(); + let entries = Array.from(records.keyDependencies.get(map)); + assert.deepEqual(entries, ['first'], 'Has the right entries'); + }); + QUnit.test('Adding a property on the prototype works', function (assert) { + class Favorites extends ObservableObject { + } + hooks.finalizeClass(Favorites); + Favorites.prototype.aFunction = function () { + }; + let myFaves = new Favorites({ food: 'pizza' }); + let yourFaves = new Favorites({ food: 'tacos' }); + assert.equal(myFaves.food, 'pizza', 'myFaves.food is pizza'); + assert.equal(yourFaves.food, 'tacos', 'yourFaves.food is tacos'); + }); + QUnit.test('Symbols are not observable', function (assert) { + let map = new ObservableObject(); + let sym = Symbol.for('can.something'); + ObservationRecorder.start(); + map[sym]; + let records = ObservationRecorder.stop(); + let entries = Array.from(records.keyDependencies.get(map) || []); + assert.deepEqual(entries, [], 'no observations are created'); + ObservationRecorder.start(); + map[sym] = 'Hi'; + records = ObservationRecorder.stop(); + entries = Array.from(records.keyDependencies.get(map) || []); + assert.deepEqual(entries, [], 'no observations are created'); + }); + QUnit.test('Does not observe __proto__', function (assert) { + class Parent extends ObservableObject { + fn() { + } + } + class Child extends Parent { + fn() { + super.fn(); + } + } + let instance = new Child(); + ObservationRecorder.start(); + instance.fn(); + let records = ObservationRecorder.stop(); + let deps = Array.from(records.keyDependencies); + assert.equal(deps.length, 0, 'Nothing recorded just by calling super.fn()'); + }); + QUnit.test('Self-referential typing', function (assert) { + class Faves extends ObservableObject { + static get define() { + return { faves: type.late(() => type.convert(Faves)) }; + } + } + let faves = new Faves({ faves: {} }); + assert.ok(faves instanceof Faves); + assert.ok(faves.faves instanceof Faves); + }); + QUnit.test('oldValue and value are on event object', function (assert) { + assert.expect(2); + class Faves extends ObservableObject { + static get props() { + return { prop: String }; + } + } + let faves = new Faves({ prop: 'value' }); + faves.listenTo('prop', ev => { + assert.equal(ev.value, 'value2', 'has the new value'); + assert.equal(ev.oldValue, 'value', 'has the old value'); + }); + faves.prop = 'value2'; + }); + QUnit.test('deleteKey includes the oldValue', function (assert) { + assert.expect(1); + class Faves extends ObservableObject { + static get props() { + return { prop: type.Any }; + } + } + let faves = new Faves({ prop: 'value' }); + faves.listenTo('prop', ev => { + assert.equal(ev.oldValue, 'value', 'includes the old value'); + }); + faves.deleteKey('prop'); + }); + QUnit.test('Changes in getters includes the old and new values', function (assert) { + class Faves extends ObservableObject { + static get props() { + return { + one: String, + two: { + get() { + return this.one; + } + } + }; + } + } + let faves = new Faves({ one: 'one' }); + faves.listenTo('one', ev => { + assert.equal(ev.value, 'two', 'has the new value'); + assert.equal(ev.oldValue, 'one', 'Has the old value'); + }); + faves.one = 'two'; + }); +}); +/*can-observable-mixin@1.0.10#test/props-mixin-proxy-htmlelement-test*/ +define('can-observable-mixin@1.0.10#test/props-mixin-proxy-htmlelement-test', [ + 'require', + 'exports', + 'module', + '../src/mixins', + 'can-reflect' +], function (require, exports, module) { + const {mixinElement} = require('../src/mixins'); + const canReflect = require('can-reflect'); + const supportsCustomElements = 'customElements' in window; + if (supportsCustomElements) { + QUnit.module('can-observable-mixin - Proxy HTMLElement'); + QUnit.test('Can bind on properties not defined', function (assert) { + const Base = mixinElement(HTMLElement); + class Favorites extends Base { + } + customElements.define('my-favorites', Favorites); + let faves = new Favorites(); + faves.connectedCallback(); + canReflect.onKeyValue(faves, 'food', function () { + assert.ok(true); + }); + faves.food = 'pizza'; + }); + QUnit.test('Can have functions on the prototype', function (assert) { + const Base = mixinElement(HTMLElement); + class Favorites extends Base { + listFavorites() { + } + } + customElements.define('my-favorites2', Favorites); + let f1 = new Favorites(); + let f2 = new Favorites(); + assert.equal(typeof f1.listFavorites, 'function', 'It is a function'); + assert.equal(f1.listFavorites, f2.listFavorites, 'Share the same function instance because it\'s on the prototype'); + assert.equal(Favorites.prototype.listFavorites, f1.listFavorites, 'It is really on the prototype'); + }); + QUnit.test('Can have functions on the derived classes', function (assert) { + const Base = mixinElement(HTMLElement); + class One extends Base { + } + class Two extends One { + aFunction() { + } + } + customElements.define('my-two1', Two); + let two = new Two(); + let two2 = new Two(); + assert.equal(typeof two.aFunction, 'function', 'It is a function'); + assert.equal(two.aFunction, two2.aFunction, 'Share the same function instance because it\'s on the prototype'); + }); + QUnit.test('Can set a property of HTMLElement on the instance', function (assert) { + const Base = mixinElement(HTMLElement); + class Instance extends Base { + } + customElements.define('my-instance', Instance); + let onclick = function () { + }; + let instance = new Instance(); + instance.connectedCallback(); + instance.onclick = onclick; + assert.equal(instance.onclick, onclick, 'The onclick is there'); + assert.equal(document.createElement('button').onclick, null, 'Didn\'t mess with the HTMLElement\'s onclick'); + let newonclick; + canReflect.onKeyValue(instance, 'onclick', function (newValue) { + assert.equal(newValue, newonclick, 'Changed to the new value'); + }); + instance.onclick; + newonclick = function () { + }; + instance.onclick = newonclick; + }); + QUnit.test('initial props should always be passed to initialize', function (assert) { + assert.expect(4); + const props = { + foo: 'bar', + baz: 'bap' + }; + class Obj extends mixinElement(Object) { + static get props() { + return { + foo: String, + baz: String + }; + } + } + const initializeObj = new Obj(); + initializeObj.initialize(props); + assert.equal(initializeObj.foo, 'bar'); + assert.equal(initializeObj.baz, 'bap'); + const renderObj = new Obj(); + renderObj.render(props); + assert.equal(renderObj.foo, 'bar'); + assert.equal(renderObj.baz, 'bap'); + }); + QUnit.test('initialize, render, and connect are only called the first time connectedCallback is called', function (assert) { + assert.expect(3); + class Base extends HTMLElement { + initialize() { + assert.ok(true, 'initialize'); + } + render() { + assert.ok(true, 'render'); + } + connectedCallback() { + assert.ok(true, 'connect'); + } + } + class Obj extends mixinElement(Base) { + } + customElements.define('some-obj2', Obj); + const obj = new Obj(); + obj.initialize(); + obj.connectedCallback(); + }); + } +}); +/*can-observable-mixin@1.0.10#test/define-test*/ +define('can-observable-mixin@1.0.10#test/define-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + '../src/define', + 'can-reflect', + 'can-type', + 'can-test-helpers' +], function (require, exports, module) { + const QUnit = require('steal-qunit'); + const {mixinObject} = require('./helpers'); + const {hooks} = require('../src/define'); + const canReflect = require('can-reflect'); + const type = require('can-type'); + const dev = require('can-test-helpers').dev; + QUnit.module('can-observable-mixin - define()'); + QUnit.test('Can define stuff', function (assert) { + class Faves extends mixinObject() { + static get props() { + return { color: { default: 'blue' } }; + } + } + let faves = new Faves(); + assert.equal(faves.color, 'blue', 'Got the value'); + }); + QUnit.test('Does not throw if no define is provided', function (assert) { + class Faves extends mixinObject() { + } + new Faves(); + assert.ok(true, 'Did not throw'); + }); + QUnit.test('Stuff is defined in constructor for non-element classes', function (assert) { + class Faves extends mixinObject(Object) { + static get props() { + return { color: { default: 'blue' } }; + } + constructor() { + super(); + assert.equal(this.color, 'blue', 'color exists after constructor'); + } + } + new Faves(); + }); + QUnit.test('Default strings work when they are like can-define types', function (assert) { + class Person extends mixinObject() { + static get props() { + return { someProp: 'number' }; + } + } + let p = new Person(); + assert.equal(p.someProp, 'number', 'Is the string \'number\''); + }); + QUnit.test('initialize can be called multiple times if Symbol is reset', function (assert) { + const metaSymbol = Symbol.for('can.meta'); + class Obj extends mixinObject() { + static get props() { + return { age: Number }; + } + } + const obj = new Obj({ age: 30 }); + assert.equal(obj.age, 30, 'initialized once by constructor'); + obj[metaSymbol].initialized = false; + hooks.initialize(obj, { age: 35 }); + assert.equal(obj.age, 35, 'initialized again'); + }); + QUnit.test('defineInstanceKey does not add to the base prototype', function (assert) { + const Base = mixinObject(); + class Obj extends Base { + } + canReflect.defineInstanceKey(Obj, '_saving', { + configurable: true, + default: false, + enumerable: false, + writable: true + }); + new Obj(); + let desc = Object.getOwnPropertyDescriptor(Base.prototype, '_saving'); + assert.ok(!desc, 'There is no descriptor on the Base class'); + }); + QUnit.test('should not serialize properties using value and get behaviors unless they are `enumerable: true`', function (assert) { + const props = { + prop: String, + propValue: { + value({listenTo, resolve}) { + listenTo('prop', ({value}) => resolve(value)); + } + }, + propGetter: { + get() { + return this.prop; + } + }, + propAsync: { + async(resolve) { + resolve(this.prop); + } + } + }; + class Obj extends mixinObject() { + static get props() { + return props; + } + } + let obj = new Obj(); + obj.listenTo('propValue', () => { + }); + obj.listenTo('propGetter', () => { + }); + obj.listenTo('propAsync', () => { + }); + assert.deepEqual(obj.serialize(), {}, '{} by default'); + obj.prop = 'a'; + assert.deepEqual(obj.serialize(), { prop: 'a' }, 'only prop is serialized'); + props.propValue.enumerable = true; + props.propGetter.enumerable = true; + props.propAsync.enumerable = true; + class EnumerableObj extends mixinObject() { + static get props() { + return props; + } + } + obj = new EnumerableObj(); + obj.listenTo('propValue', () => { + }); + obj.listenTo('propGetter', () => { + }); + obj.listenTo('propAsync', () => { + }); + assert.deepEqual(obj.serialize(), {}, '{} by default'); + obj.prop = 'b'; + let expected = { + prop: 'b', + propGetter: 'b', + propValue: 'b', + propAsync: 'b' + }; + assert.deepEqual(obj.serialize(), expected, 'all props are serialized'); + }); + QUnit.test('should implement can.unwrap', function (assert) { + class Obj extends mixinObject() { + static get props() { + return { + definedValue: String, + undefinedValue: String + }; + } + } + const obj = new Obj({ definedValue: 'a' }); + assert.deepEqual(canReflect.unwrap(obj), { definedValue: 'a' }, 'undefined props are not returned by unwrap'); + }); + QUnit.test('properties using value behavior reset when unbound', function (assert) { + class Obj extends mixinObject() { + static get props() { + return { + prop: String, + derivedProp: { + value({listenTo, resolve}) { + listenTo('prop', ({value}) => resolve(value)); + } + } + }; + } + } + let obj = new Obj(); + obj.listenTo('derivedProp', () => { + }); + obj.prop = 'a value'; + assert.equal(obj.derivedProp, 'a value', 'value set'); + obj.stopListening(); + assert.equal(obj.derivedProp, undefined, 'value reset'); + }); + dev.devOnlyTest('On error include the name of the property that is being set', function (assert) { + class Person extends mixinObject() { + static get props() { + return { age: type.check(Number) }; + } + } + const farah = new Person(); + try { + farah.age = '4'; + } catch (error) { + assert.equal(error.message, '"4" (string) is not of type Number. Property age is using "type: Number". Use "age: type.convert(Number)" to automatically convert values to Numbers when setting the "age" property.'); + } + }); + dev.devOnlyTest('Handle types as arrays to fix "Right-hand side of instanceof is not callable for arrays"', function (assert) { + class Foo extends mixinObject() { + static get props() { + return { list: [] }; + } + } + const foo = new Foo(); + foo.list = [ + 'one', + 'two' + ]; + try { + assert.ok(true, 'No errors, it handles arrays values as type'); + } catch (error) { + assert.ok(error.message); + } + }); + dev.devOnlyTest('Only can-type error should be catched', function (assert) { + class T extends mixinObject() { + static get props() { + return { + aStr: { + type: type.maybe(String), + default: 'Hi' + } + }; + } + } + const t = new T(); + t.on('aStr', function (newVal) { + newVal.toUpperCase(); + }); + try { + t.aStr = null; + } catch (error) { + assert.ok(error.message !== '"null" (object) is not of type String. Property aStr is using "type: String". Use "aStr: type.convert(String)" to automatically convert values to Strings when setting the "aStr" property.'); + assert.equal(error.type, undefined, 'can-type error only thrown on wrong types'); + } + }); + dev.devOnlyTest('Raise error if value, getter or setter aren\'t functions', function (assert) { + class Foo extends mixinObject() { + static get props() { + return { prop1: { value: 'Blah' } }; + } + } + class Bar extends mixinObject() { + static get props() { + return { prop1: { get: 'Blah' } }; + } + } + class Baz extends mixinObject() { + static get props() { + return { prop1: { set: 'Blah' } }; + } + } + let undo = dev.willError(/function/); + new Foo(); + new Bar(); + new Baz(); + assert.equal(undo(), 3, 'Errored on the non-function define arguments.'); + }); + QUnit.test('Define default property null or undefined', function (assert) { + class Foo extends mixinObject() { + static get props() { + return { + nullProp: { default: null }, + undefinedProp: { default: undefined } + }; + } + } + const foo = new Foo(); + assert.equal(foo.nullProp, null); + assert.equal(foo.nullProp, undefined); + }); + QUnit.test('Define property null or undefined', function (assert) { + class Foo extends mixinObject() { + static get props() { + return { + nullProp: null, + undefinedProp: null + }; + } + } + const foo = new Foo(); + assert.equal(foo.nullProp, null); + assert.equal(foo.nullProp, undefined); + }); +}); +/*can-observable-mixin@1.0.10#test/test*/ +define('can-observable-mixin@1.0.10#test/test', [ + 'require', + 'exports', + 'module', + './create-constructor-function-test', + './props-mixin-test', + './props-test', + './props-types-test', + './props-mixin-default-test', + './props-mixin-new-test', + './array-mixin-test', + './type-events-test', + './props-mixin-proxy-object-test', + './props-mixin-proxy-htmlelement-test', + './define-test' +], function (require, exports, module) { + require('./create-constructor-function-test'); + require('./props-mixin-test'); + require('./props-test'); + require('./props-types-test'); + require('./props-mixin-default-test'); + require('./props-mixin-new-test'); + require('./array-mixin-test'); + require('./type-events-test'); + require('./props-mixin-proxy-object-test'); + require('./props-mixin-proxy-htmlelement-test'); + require('./define-test'); +}); +/*can-query-logic@1.2.2#src/set*/ +define('can-query-logic@1.2.2#src/set', [ + 'require', + 'exports', + 'module', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var set; + var addSerializeToThis = function (obj) { + return canReflect.assignSymbols(obj, { + 'can.serialize': function () { + return this; + } + }); + }; + function reverseArgs(fn) { + return function (first, second) { + return fn.call(this, second, first); + }; + } + var setComparisonsSymbol = canSymbol.for('can.setComparisons'); + function addComparators(type1, type2, comparators) { + var comparisons = type1[setComparisonsSymbol]; + if (!type1[setComparisonsSymbol]) { + comparisons = type1[setComparisonsSymbol] = new Map(); + } + var subMap = comparisons.get(type1); + if (!subMap) { + subMap = new Map(); + comparisons.set(type1, subMap); + } + var existingComparators = subMap.get(type2); + if (existingComparators) { + for (var prop in comparators) { + if (existingComparators.hasOwnProperty(prop)) { + console.warn('Overwriting ' + type1.name + ' ' + prop + ' ' + type2.name + ' comparitor'); + } + existingComparators[prop] = comparators[prop]; + } + } else { + subMap.set(type2, comparators); + } + } + function Identity() { + } + var typeMap = { + 'number': Identity, + 'string': Identity, + 'undefined': Identity, + 'boolean': Identity + }; + var get = {}; + [ + 'intersection', + 'difference', + 'union' + ].forEach(function (prop) { + get[prop] = function (forwardComparators, value1, value2) { + if (value2 === set.UNIVERSAL) { + if (prop === 'intersection') { + return value1; + } + if (prop === 'union') { + return set.UNIVERSAL; + } + if (prop === 'difference') { + return set.EMPTY; + } + } + if (value1 === set.UNIVERSAL) { + if (prop === 'intersection') { + return value1; + } + if (prop === 'union') { + return set.UNIVERSAL; + } + } + if (forwardComparators && forwardComparators[prop]) { + var result = forwardComparators[prop](value1, value2); + if (result === undefined && forwardComparators.undefinedIsEmptySet === true) { + return set.EMPTY; + } else { + return result; + } + } else { + throw new Error('Unable to perform ' + prop + ' between ' + set.getType(value1).name + ' and ' + set.getType(value2).name); + } + }; + }); + set = { + UNIVERSAL: canReflect.assignSymbols({ name: 'UNIVERSAL' }, { + 'can.serialize': function () { + return this; + }, + 'can.isMember': function () { + return true; + } + }), + EMPTY: canReflect.assignSymbols({ name: 'EMPTY' }, { + 'can.serialize': function () { + return this; + }, + 'can.isMember': function () { + return false; + } + }), + UNDEFINABLE: addSerializeToThis({ name: 'UNDEFINABLE' }), + UNKNOWABLE: addSerializeToThis({ name: 'UNKNOWABLE' }), + Identity: Identity, + isSpecial: function (setA) { + return setA === set.UNIVERSAL || setA === set.EMPTY || setA === set.UNDEFINABLE || setA === set.UNKNOWABLE; + }, + isDefinedAndHasMembers: function (setA) { + if (setA !== set.EMPTY && setA !== set.UNDEFINABLE && setA !== set.UNKNOWABLE) { + return !!setA; + } else { + return false; + } + }, + getType: function (value) { + if (value === set.UNIVERSAL) { + return set.UNIVERSAL; + } + if (value === set.EMPTY) { + return set.EMPTY; + } + if (value === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + if (value === null) { + return Identity; + } + if (typeMap.hasOwnProperty(typeof value)) { + return typeMap[typeof value]; + } + return value.constructor; + }, + ownAndMemberValue: function (startOwnValue, startMemberValue) { + if (startOwnValue != null || startMemberValue != null) { + var ownValue = startOwnValue != null ? startOwnValue.valueOf() : startOwnValue, memberValue = startMemberValue != null ? startMemberValue.valueOf() : startMemberValue; + if (startOwnValue == null || startMemberValue == null) { + return { + own: ownValue, + member: memberValue + }; + } + if (ownValue == null || ownValue.constructor !== memberValue.constructor) { + memberValue = new startOwnValue.constructor(memberValue).valueOf(); + } + return { + own: ownValue, + member: memberValue + }; + } + return { + own: startMemberValue, + member: startOwnValue + }; + }, + getComparisons: function (Type1, Type2) { + var comparisons = Type1[setComparisonsSymbol]; + if (comparisons) { + var subMap = comparisons.get(Type1); + if (subMap) { + return subMap.get(Type2); + } + } + }, + hasComparisons: function (Type) { + return !!Type[setComparisonsSymbol]; + }, + defineComparison: function (type1, type2, comparators) { + addComparators(type1, type2, comparators); + if (type1 !== type2) { + var reverse = {}; + for (var prop in comparators) { + if (prop !== 'difference') { + reverse[prop] = reverseArgs(comparators[prop]); + } + } + addComparators(type2, type1, reverse); + } + }, + isSubset: function (value1, value2) { + if (value1 === value2) { + return true; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + var forwardComparators = set.getComparisons(Type1, Type2); + if (forwardComparators) { + var intersection = get.intersection(forwardComparators, value1, value2); + var difference = get.difference(forwardComparators, value1, value2); + if (intersection === set.UNKNOWABLE || difference === set.UNKNOWABLE) { + return undefined; + } else if (intersection !== set.EMPTY && difference === set.EMPTY) { + return true; + } else { + return false; + } + } else { + throw new Error('Unable to perform subset comparison between ' + Type1.name + ' and ' + Type2.name); + } + }, + isProperSubset: function (setA, setB) { + return set.isSubset(setA, setB) && !set.isEqual(setA, setB); + }, + isEqual: function (value1, value2) { + if (value1 === set.UNKNOWABLE || value2 === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + var isSpecial1 = set.isSpecial(value1), isSpecial2 = set.isSpecial(value2); + if (isSpecial1 && isSpecial2) { + return isSpecial1 === isSpecial2; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + if (value1 === value2) { + return true; + } + var forwardComparators = set.getComparisons(Type1, Type2); + var reverseComparators = set.getComparisons(Type2, Type1); + if (forwardComparators && reverseComparators) { + var intersection = get.intersection(forwardComparators, value1, value2); + var difference = get.difference(forwardComparators, value1, value2); + if (intersection !== set.EMPTY && difference === set.EMPTY) { + var reverseIntersection = get.intersection(reverseComparators, value2, value1); + var reverseDifference = get.difference(reverseComparators, value2, value1); + return reverseIntersection !== set.EMPTY && reverseDifference === set.EMPTY; + } else { + return false; + } + } else { + var values = set.ownAndMemberValue(value1, value2); + if (canReflect.isPrimitive(values.own) && canReflect.isPrimitive(values.member)) { + return values.own === values.member; + } else { + throw new Error('Unable to perform equal comparison between ' + Type1.name + ' and ' + Type2.name); + } + } + }, + union: function (value1, value2) { + if (value1 === set.UNIVERSAL || value2 === set.UNIVERSAL) { + return set.UNIVERSAL; + } + if (value1 === set.EMPTY) { + return value2; + } else if (value2 === set.EMPTY) { + return value1; + } + if (value1 === set.UNKNOWABLE || value2 === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + var forwardComparators = set.getComparisons(Type1, Type2); + return get.union(forwardComparators, value1, value2); + }, + intersection: function (value1, value2) { + if (value1 === set.UNIVERSAL) { + return value2; + } + if (value2 === set.UNIVERSAL) { + return value1; + } + if (value1 === set.EMPTY || value2 === set.EMPTY) { + return set.EMPTY; + } + if (value1 === set.UNKNOWABLE || value2 === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + var forwardComparators = set.getComparisons(Type1, Type2); + if (forwardComparators) { + return get.intersection(forwardComparators, value1, value2); + } else { + throw new Error('Unable to perform intersection comparison between ' + Type1.name + ' and ' + Type2.name); + } + }, + difference: function (value1, value2) { + if (value1 === set.EMPTY) { + return set.EMPTY; + } + if (value2 === set.EMPTY) { + return value1; + } + if (value1 === set.UNKNOWABLE || value2 === set.UNKNOWABLE) { + return set.UNKNOWABLE; + } + var Type1 = set.getType(value1), Type2 = set.getType(value2); + var forwardComparators = set.getComparisons(Type1, Type2); + if (forwardComparators) { + return get.difference(forwardComparators, value1, value2); + } else { + throw new Error('Unable to perform difference comparison between ' + Type1.name + ' and ' + Type2.name); + } + }, + indexWithEqual: function (arr, value) { + for (var i = 0, len = arr.length; i < len; i++) { + if (set.isEqual(arr[i], value)) { + return i; + } + } + return -1; + } + }; + function identityIntersection(v1, v2) { + return v1 === v2 ? v1 : set.EMPTY; + } + function identityDifference(v1, v2) { + return v1 === v2 ? set.EMPTY : v1; + } + function identityUnion(v1, v2) { + return v1 === v2 ? v1 : set.UNDEFINABLE; + } + var identityComparitor = { + intersection: identityIntersection, + difference: identityDifference, + union: identityUnion + }; + set.defineComparison(Identity, Identity, identityComparitor); + set.defineComparison(set.UNIVERSAL, set.UNIVERSAL, identityComparitor); + module.exports = set; +}); +/*can-query-logic@1.2.2#src/array-union-intersection-difference*/ +define('can-query-logic@1.2.2#src/array-union-intersection-difference', [ + 'require', + 'exports', + 'module', + './set' +], function (require, exports, module) { + var SET = require('./set'); + function getValue(value) { + return value == null ? value : value.valueOf(); + } + module.exports = function arrayUnionIntersectionDifference(arr1, arr2) { + var set = new Set(); + var intersection = []; + var union = []; + var difference = arr1.slice(0); + arr1.forEach(function (value) { + set.add(getValue(value)); + union.push(value); + }); + arr2.forEach(function (value) { + if (set.has(getValue(value))) { + intersection.push(value); + var index = SET.indexWithEqual(difference, value); + if (index !== -1) { + difference.splice(index, 1); + } + } else { + union.push(value); + } + }); + return { + intersection: intersection, + union: union, + difference: difference + }; + }; +}); +/*can-query-logic@1.2.2#src/types/comparisons-common*/ +define('can-query-logic@1.2.2#src/types/comparisons-common', function (require, exports, module) { + function isMemberThatUsesTestOnValues(value) { + return this.constructor.test(this.values, value); + } + exports.isMemberThatUsesTestOnValues = isMemberThatUsesTestOnValues; +}); +/*can-query-logic@1.2.2#src/types/types*/ +define('can-query-logic@1.2.2#src/types/types', function (require, exports, module) { + module.exports = {}; +}); +/*can-query-logic@1.2.2#src/types/values-not*/ +define('can-query-logic@1.2.2#src/types/values-not', [ + 'require', + 'exports', + 'module', + '../set', + './types' +], function (require, exports, module) { + var set = require('../set'); + var keysLogic = require('./types'); + function NotIdentity(value) { + this.value = value; + } + var Identity = set.Identity; + set.defineComparison(set.UNIVERSAL, Identity, { + difference: function (universe, value) { + return new NotIdentity(value); + } + }); + set.defineComparison(set.UNIVERSAL, NotIdentity, { + difference: function (universe, not) { + return not.value; + } + }); + set.defineComparison(NotIdentity, NotIdentity, {}); + set.defineComparison(NotIdentity, Identity, { + union: function (not, primitive) { + if (set.isEqual(not.value, primitive)) { + return set.UNIVERSAL; + } else { + throw new Error('Not,Identity Union is not filled out'); + } + }, + intersection: function (not, primitive) { + return set.isEqual(!not.value, primitive) ? primitive : set.EMPTY; + }, + difference: function difference(not, primitive) { + if (set.isEqual(not.value, primitive)) { + return not; + } else { + return set.UNDEFINABLE; + } + } + }); + set.defineComparison(Identity, NotIdentity, { + difference: function (primitive, not) { + if (set.isEqual(primitive, not.value)) { + return primitive; + } else { + return set.UNDEFINABLE; + } + } + }); + NotIdentity.prototype.isMember = function (value) { + if (this.value && typeof this.value.isMember === 'function') { + return !this.value.isMember(value); + } else { + var values = set.ownAndMemberValue(this.value, value); + return values.own !== values.member; + } + }; + module.exports = keysLogic.Not = NotIdentity; +}); +/*can-query-logic@1.2.2#src/types/array-comparisons*/ +define('can-query-logic@1.2.2#src/types/array-comparisons', [ + 'require', + 'exports', + 'module', + './comparisons-common', + '../set', + './values-not' +], function (require, exports, module) { + var common = require('./comparisons-common'); + var set = require('../set'); + var ValuesNot = require('./values-not'); + var comparisons = { + All: function (values) { + this.values = values; + } + }; + comparisons.All.prototype.isMember = common.isMemberThatUsesTestOnValues; + var is = comparisons; + comparisons.All.test = function (allValues, recordValues) { + return allValues.every(function (allValue) { + return recordValues.some(function (recordValue) { + var values = set.ownAndMemberValue(allValue, recordValue); + return values.own === values.member; + }); + }); + }; + function makeThrowCannotCompare(type, left, right) { + return function () { + throw new Error('can-query-logic: Cannot perform ' + type + ' between ' + left + ' and ' + right); + }; + } + function throwComparatorAllTypes(type1, type2) { + return { + union: makeThrowCannotCompare('union', type1, type2), + difference: makeThrowCannotCompare('difference', type1, type2), + intersection: makeThrowCannotCompare('intersection', type1, type2) + }; + } + function throwComparatorDifference(type1, type2) { + return { difference: makeThrowCannotCompare('difference', type1, type2) }; + } + var comparators = { + UNIVERSAL_All: { + difference: function (universe, all) { + return new ValuesNot(all); + } + }, + All_UNIVERSAL: { + difference: function () { + return set.EMPTY; + } + }, + All_All: { + union: function (a, b) { + return new is.Or([ + a, + b + ]); + } + }, + In_All: throwComparatorDifference('In', 'All'), + All_In: throwComparatorAllTypes('All', 'In'), + NotIn_All: throwComparatorDifference('NotIn', 'All'), + All_NotIn: throwComparatorAllTypes('All', 'NotIn'), + GreaterThan_All: throwComparatorDifference('GreaterThan', 'All'), + All_GreaterThan: throwComparatorAllTypes('All', 'GreaterThan'), + GreaterThanEqual_All: throwComparatorDifference('GreaterThanEqual', 'All'), + All_GreaterThanEqual: throwComparatorAllTypes('All', 'GreaterThanEqual'), + LessThan_All: throwComparatorDifference('LessThan', 'All'), + All_LessThan: throwComparatorAllTypes('All', 'LessThan'), + LessThanEqual_All: throwComparatorDifference('LessThanEqual', 'All'), + All_LessThanEqual: throwComparatorAllTypes('All', 'LessThanEqual'), + All_And: throwComparatorDifference('All', 'And'), + And_All: throwComparatorAllTypes('And', 'All'), + All_Or: throwComparatorDifference('All', 'Or'), + Or_All: throwComparatorAllTypes('Or', 'All') + }; + exports.comparisons = comparisons; + exports.comparators = comparators; +}); +/*can-query-logic@1.2.2#src/types/comparisons*/ +define('can-query-logic@1.2.2#src/types/comparisons', [ + 'require', + 'exports', + 'module', + '../set', + '../array-union-intersection-difference', + './comparisons-common', + './array-comparisons', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + var set = require('../set'); + var arrayUnionIntersectionDifference = require('../array-union-intersection-difference'); + var common = require('./comparisons-common'); + var arrayComparisons = require('./array-comparisons'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var isMemberSymbol = canSymbol.for('can.isMember'); + var comparisons = canReflect.assign(arrayComparisons.comparisons, { + In: function In(values) { + this.values = values; + }, + NotIn: function NotIn(values) { + this.values = values; + }, + GreaterThan: function GreaterThan(value) { + this.value = value; + }, + GreaterThanEqual: function GreaterThanEqual(value) { + this.value = value; + }, + LessThan: function LessThan(value) { + this.value = value; + }, + LessThanEqual: function LessThanEqual(value) { + this.value = value; + }, + And: function ValueAnd(ands) { + this.values = ands; + }, + Or: function ValueOr(ors) { + this.values = ors; + } + }); + comparisons.Or.prototype.orValues = function () { + return this.values; + }; + comparisons.In.test = function (values, b) { + return values.some(function (value) { + var values = set.ownAndMemberValue(value, b); + return values.own === values.member; + }); + }; + comparisons.NotIn.test = function (values, b) { + return !comparisons.In.test(values, b); + }; + comparisons.NotIn.testValue = function (value, b) { + return !comparisons.In.testValue(value, b); + }; + function nullIsFalse(test) { + return function (arg1, arg2) { + if (arg1 == null || arg2 == null) { + return false; + } else { + return test(arg1, arg2); + } + }; + } + function nullIsFalseTwoIsOk(test) { + return function (arg1, arg2) { + if (arg1 === arg2) { + return true; + } else if (arg1 == null || arg2 == null) { + return false; + } else { + return test(arg1, arg2); + } + }; + } + comparisons.GreaterThan.test = nullIsFalse(function (a, b) { + return a > b; + }); + comparisons.GreaterThanEqual.test = nullIsFalseTwoIsOk(function (a, b) { + return a >= b; + }); + comparisons.LessThan.test = nullIsFalse(function (a, b) { + return a < b; + }); + comparisons.LessThanEqual.test = nullIsFalseTwoIsOk(function (a, b) { + return a <= b; + }); + function isMemberThatUsesTest(value) { + var values = set.ownAndMemberValue(this.value, value); + return this.constructor.test(values.member, values.own); + } + [ + comparisons.GreaterThan, + comparisons.GreaterThanEqual, + comparisons.LessThan, + comparisons.LessThanEqual, + comparisons.LessThan + ].forEach(function (Type) { + Type.prototype.isMember = isMemberThatUsesTest; + }); + [ + comparisons.In, + comparisons.NotIn + ].forEach(function (Type) { + Type.prototype.isMember = common.isMemberThatUsesTestOnValues; + }); + comparisons.And.prototype.isMember = function (value) { + return this.values.every(function (and) { + return and.isMember(value); + }); + }; + comparisons.Or.prototype.isMember = function (value) { + return this.values.some(function (and) { + return and.isMember(value); + }); + }; + Object.keys(comparisons).forEach(function (name) { + comparisons[name].prototype[isMemberSymbol] = comparisons[name].prototype.isMember; + }); + var is = comparisons; + function makeNot(Type) { + return { + test: function (vA, vB) { + return !Type.test(vA, vB); + } + }; + } + function makeEnum(type, Type, emptyResult) { + return function (a, b) { + var result = arrayUnionIntersectionDifference(a.values, b.values); + if (result[type].length) { + return new Type(result[type]); + } else { + return emptyResult || set.EMPTY; + } + }; + } + function swapArgs(fn) { + return function (a, b) { + return fn(b, a); + }; + } + function makeSecondValue(Type, prop) { + return function (universe, value) { + return new Type(value[prop || 'value']); + }; + } + function returnBiggerValue(gtA, gtB) { + if (gtA.value < gtB.value) { + return gtB; + } else { + return gtA; + } + } + function returnSmallerValue(gtA, gtB) { + if (gtA.value > gtB.value) { + return gtB; + } else { + return gtA; + } + } + function makeAndIf(Comparison, Type) { + return function (ltA, ltB) { + if (Comparison.test(ltA.value, ltB.value)) { + return makeAnd([ + ltA, + new Type(ltB.value) + ]); + } else { + return set.EMPTY; + } + }; + } + function make_InIfEqual_else_andIf(Comparison, Type) { + var elseCase = makeAndIf(Comparison, Type); + return function (a, b) { + if (a.value === b.value) { + return new is.In([a.value]); + } else { + return elseCase(a, b); + } + }; + } + function make_filterFirstValueAgainstSecond(Comparison, Type, defaultReturn) { + return function (inSet, gt) { + var values = inSet.values.filter(function (value) { + return Comparison.test(gt, value); + }); + return values.length ? new Type(values) : defaultReturn || set.EMPTY; + }; + } + var isMemberTest = { + test: function isMemberTest(set, value) { + return set.isMember(value); + } + }; + function isOr(value) { + return value instanceof is.Or; + } + function isAnd(value) { + return value instanceof is.And; + } + function isAndOrOr(value) { + return isAnd(value) || isOr(value); + } + function combineFilterFirstValuesAgainstSecond(options) { + return function (inSet, gt) { + var values = inSet.values.filter(function (value) { + return options.values.test(gt, value); + }); + var range; + if (options.complement) { + range = set.difference(set.UNIVERSAL, gt); + } else if (options.with) { + range = new options.with(gt.value); + } else { + range = gt; + } + return values.length ? options.combinedUsing([ + new options.arePut(values), + range + ]) : range; + }; + } + function makeOrUnless(Comparison, result) { + return function (setA, setB) { + if (Comparison.test(setA.value, setB.value)) { + return result || set.UNIVERSAL; + } else { + return makeOr([ + setA, + setB + ]); + } + }; + } + function makeAndUnless(Comparison, result) { + return function (setA, setB) { + if (Comparison.test(setA.value, setB.value)) { + return result || set.EMPTY; + } else { + return makeAnd([ + setA, + setB + ]); + } + }; + } + function makeComplementSecondArgIf(Comparison) { + return function (setA, setB) { + if (Comparison.test(setA.value, setB.value)) { + return set.difference(set.UNIVERSAL, setB); + } else { + return setA; + } + }; + } + function makeAnd(ands) { + return comparisons.And ? new comparisons.And(ands) : set.UNDEFINABLE; + } + function makeOr(ors) { + return comparisons.Or ? new comparisons.Or(ors) : set.UNDEFINABLE; + } + function combineValueWithRangeCheck(inSet, rangeSet, RangeOrEqType) { + var gte = new RangeOrEqType(rangeSet.value); + var leftValues = inSet.values.filter(function (value) { + return !gte.isMember(value); + }); + if (!leftValues.length) { + return gte; + } + if (leftValues.length < inSet.values.length) { + return makeOr([ + new is.In(leftValues), + gte + ]); + } else { + return makeOr([ + inSet, + rangeSet + ]); + } + } + function makeOrWithInAndRange(inSet, rangeSet) { + if (rangeSet instanceof is.Or) { + var firstResult = makeOrWithInAndRange(inSet, rangeSet.values[0]); + if (!(firstResult instanceof is.Or)) { + return set.union(firstResult, rangeSet.values[1]); + } + var secondResult = makeOrWithInAndRange(inSet, rangeSet.values[1]); + if (!(secondResult instanceof is.Or)) { + return set.union(secondResult, rangeSet.values[0]); + } + return makeOr([ + inSet, + rangeSet + ]); + } else { + if (rangeSet instanceof is.GreaterThan) { + return combineValueWithRangeCheck(inSet, rangeSet, is.GreaterThanEqual); + } + if (rangeSet instanceof is.LessThan) { + return combineValueWithRangeCheck(inSet, rangeSet, is.LessThanEqual); + } + return makeOr([ + inSet, + rangeSet + ]); + } + } + var In_RANGE = { + union: combineFilterFirstValuesAgainstSecond({ + values: makeNot(isMemberTest), + arePut: is.In, + combinedUsing: function (ors) { + return makeOrWithInAndRange(ors[0], ors[1]); + } + }), + intersection: make_filterFirstValueAgainstSecond(isMemberTest, is.In, set.EMPTY), + difference: make_filterFirstValueAgainstSecond(makeNot(isMemberTest), is.In, set.EMPTY) + }; + var RANGE_IN = { + difference: swapArgs(combineFilterFirstValuesAgainstSecond({ + values: isMemberTest, + arePut: is.NotIn, + combinedUsing: makeAnd + })) + }; + var NotIn_RANGE = function () { + return { + union: make_filterFirstValueAgainstSecond(makeNot(isMemberTest), is.NotIn, set.UNIVERSAL), + intersection: combineFilterFirstValuesAgainstSecond({ + values: isMemberTest, + arePut: is.NotIn, + combinedUsing: makeAnd + }), + difference: combineFilterFirstValuesAgainstSecond({ + values: makeNot(isMemberTest), + arePut: is.NotIn, + combinedUsing: makeAnd, + complement: true + }) + }; + }; + var RANGE_NotIn = { difference: swapArgs(make_filterFirstValueAgainstSecond(isMemberTest, is.In, set.EMPTY)) }; + var RANGE_And_Union = function (gt, and) { + var union1 = set.union(gt, and.values[0]); + var union2 = set.union(gt, and.values[1]); + if (!isAndOrOr(union1) && !isAndOrOr(union2)) { + return set.intersection(union1, union2); + } else { + return new is.Or([ + gt, + and + ]); + } + }; + var RANGE_And_Intersection = function (gt, and) { + var and1 = and.values[0], and2 = and.values[1]; + var intersection1 = set.intersection(gt, and1); + var intersection2 = set.intersection(gt, and2); + if (intersection1 === set.EMPTY || intersection2 === set.EMPTY) { + return set.EMPTY; + } + if (!isAndOrOr(intersection1)) { + return new set.intersection(intersection1, and2); + } + if (!isAndOrOr(intersection2)) { + return new set.intersection(intersection2, and1); + } else { + return new is.And([ + gt, + and + ]); + } + }; + var RANGE_And_Difference = function (gt, and) { + var and1 = and.values[0], and2 = and.values[1]; + var difference1 = set.difference(gt, and1); + var difference2 = set.difference(gt, and2); + if (difference1 === set.EMPTY) { + return difference2; + } + if (difference2 === set.EMPTY) { + return difference1; + } + return new is.Or([ + difference1, + difference2 + ]); + }; + var And_RANGE_Difference = function (and, gt) { + var and1 = and.values[0], and2 = and.values[1]; + var difference1 = set.difference(and1, gt); + var difference2 = set.difference(and2, gt); + return set.intersection(difference1, difference2); + }; + var RANGE_Or = { + union: function (gt, or) { + var or1 = or.values[0], or2 = or.values[1]; + var union1 = set.union(gt, or1); + if (!isAndOrOr(union1)) { + return set.union(union1, or2); + } + var union2 = set.union(gt, or2); + if (!isAndOrOr(union2)) { + return set.union(or1, union2); + } else { + return new is.Or([ + gt, + or + ]); + } + }, + intersection: function (gt, or) { + var or1 = or.values[0], or2 = or.values[1]; + var intersection1 = set.intersection(gt, or1); + var intersection2 = set.intersection(gt, or2); + if (intersection1 === set.EMPTY) { + return intersection2; + } + if (intersection2 === set.EMPTY) { + return intersection1; + } + return set.union(intersection1, intersection2); + }, + difference: function (gt, or) { + var or1 = or.values[0], or2 = or.values[1]; + var difference1 = set.difference(gt, or1); + var difference2 = set.difference(gt, or2); + return set.intersection(difference1, difference2); + } + }; + var Or_RANGE = { + difference: function (or, gt) { + var or1 = or.values[0], or2 = or.values[1]; + var difference1 = set.difference(or1, gt); + var difference2 = set.difference(or2, gt); + return set.union(difference1, difference2); + } + }; + var comparators = canReflect.assign(arrayComparisons.comparators, { + In_In: { + union: makeEnum('union', is.In), + intersection: makeEnum('intersection', is.In), + difference: makeEnum('difference', is.In) + }, + UNIVERSAL_In: { difference: makeSecondValue(is.NotIn, 'values') }, + In_NotIn: { + union: swapArgs(makeEnum('difference', is.NotIn, set.UNIVERSAL)), + intersection: makeEnum('difference', is.In), + difference: makeEnum('intersection', is.In) + }, + NotIn_In: { difference: makeEnum('union', is.NotIn) }, + In_GreaterThan: In_RANGE, + GreaterThan_In: RANGE_IN, + In_GreaterThanEqual: In_RANGE, + GreaterThanEqual_In: RANGE_IN, + In_LessThan: In_RANGE, + LessThan_In: RANGE_IN, + In_LessThanEqual: In_RANGE, + LessThanEqual_In: RANGE_IN, + In_And: In_RANGE, + And_In: RANGE_IN, + In_Or: In_RANGE, + Or_In: RANGE_IN, + NotIn_NotIn: { + union: makeEnum('intersection', is.NotIn, set.UNIVERSAL), + intersection: makeEnum('union', is.NotIn), + difference: makeEnum('difference', is.In) + }, + UNIVERSAL_NotIn: { difference: makeSecondValue(is.In, 'values') }, + NotIn_GreaterThan: NotIn_RANGE(), + GreaterThan_NotIn: RANGE_NotIn, + NotIn_GreaterThanEqual: NotIn_RANGE(), + GreaterThanEqual_NotIn: RANGE_NotIn, + NotIn_LessThan: NotIn_RANGE(), + LessThan_NotIn: RANGE_NotIn, + NotIn_LessThanEqual: NotIn_RANGE(), + LessThanEqual_NotIn: RANGE_NotIn, + NotIn_And: NotIn_RANGE(), + And_NotIn: RANGE_NotIn, + NotIn_Or: NotIn_RANGE(), + Or_NotIn: RANGE_NotIn, + GreaterThan_GreaterThan: { + union: returnSmallerValue, + intersection: returnBiggerValue, + difference: makeAndIf(is.LessThan, is.LessThanEqual) + }, + UNIVERSAL_GreaterThan: { difference: makeSecondValue(is.LessThanEqual) }, + GreaterThan_GreaterThanEqual: { + union: returnSmallerValue, + intersection: returnBiggerValue, + difference: makeAndIf(is.LessThan, is.LessThan) + }, + GreaterThanEqual_GreaterThan: { difference: make_InIfEqual_else_andIf(is.LessThan, is.LessThanEqual) }, + GreaterThan_LessThan: { + union: function () { + var makeOrUnlessLessThan = makeOrUnless(is.LessThan); + return function greaterThan_lessThan_union(a, b) { + if (comparisons.In.test([a.value], b.value)) { + return new is.NotIn([a.value]); + } else { + return makeOrUnlessLessThan(a, b); + } + }; + }(), + intersection: makeAndUnless(is.GreaterThan), + difference: makeComplementSecondArgIf(is.LessThan) + }, + LessThan_GreaterThan: { difference: makeComplementSecondArgIf(is.GreaterThan) }, + GreaterThan_LessThanEqual: { + union: makeOrUnless(is.LessThanEqual), + intersection: makeAndUnless(is.GreaterThanEqual), + difference: makeComplementSecondArgIf(is.LessThanEqual) + }, + LessThanEqual_GreaterThan: { difference: makeComplementSecondArgIf(is.GreaterThanEqual) }, + GreaterThan_And: { + union: RANGE_And_Union, + intersection: RANGE_And_Intersection, + difference: RANGE_And_Difference + }, + And_GreaterThan: { difference: And_RANGE_Difference }, + GreaterThan_Or: RANGE_Or, + Or_GreaterThan: Or_RANGE, + GreaterThanEqual_GreaterThanEqual: { + union: returnSmallerValue, + intersection: returnBiggerValue, + difference: makeAndIf(is.LessThan, is.LessThan) + }, + UNIVERSAL_GreaterThanEqual: { difference: makeSecondValue(is.LessThan) }, + GreaterThanEqual_LessThan: { + union: makeOrUnless(is.LessThanEqual), + intersection: makeAndUnless(is.GreaterThanEqual), + difference: makeComplementSecondArgIf(is.LessThanEqual) + }, + LessThan_GreaterThanEqual: { difference: makeComplementSecondArgIf(is.GreaterThanEqual) }, + GreaterThanEqual_LessThanEqual: { + union: makeOrUnless(is.LessThanEqual), + intersection: function () { + var makeAnd = makeAndUnless(is.GreaterThan); + return function gte_lte_intersection(gte, lte) { + var inSet = new is.In([gte.value]); + if (inSet.isMember(lte.value)) { + return inSet; + } else { + return makeAnd(gte, lte); + } + }; + }(), + difference: makeComplementSecondArgIf(is.LessThanEqual) + }, + LessThanEqual_GreaterThanEqual: { difference: makeComplementSecondArgIf(is.GreaterThanEqual) }, + GreaterThanEqual_And: { + union: RANGE_And_Union, + intersection: RANGE_And_Intersection, + difference: RANGE_And_Difference + }, + And_GreaterThanEqual: { difference: And_RANGE_Difference }, + GreaterThanEqual_Or: RANGE_Or, + Or_GreaterThanEqual: Or_RANGE, + LessThan_LessThan: { + union: returnBiggerValue, + intersection: returnSmallerValue, + difference: makeAndIf(is.GreaterThan, is.GreaterThanEqual) + }, + UNIVERSAL_LessThan: { difference: makeSecondValue(is.GreaterThanEqual) }, + LessThan_LessThanEqual: { + union: returnBiggerValue, + intersection: returnSmallerValue, + difference: makeAndIf(is.GreaterThan, is.GreaterThan) + }, + LessThanEqual_LessThan: { difference: make_InIfEqual_else_andIf(is.GreaterThanEqual, is.GreaterThanEqual) }, + LessThan_And: { + union: RANGE_And_Union, + intersection: RANGE_And_Intersection, + difference: RANGE_And_Difference + }, + And_LessThan: { difference: And_RANGE_Difference }, + LessThan_Or: RANGE_Or, + Or_LessThan: Or_RANGE, + LessThanEqual_LessThanEqual: { + union: returnBiggerValue, + intersection: returnSmallerValue, + difference: function (lteA, lteB) { + if (lteA.value >= lteB.value) { + return makeAnd([ + lteA, + new is.GreaterThan(lteB.value) + ]); + } else { + return set.EMPTY; + } + } + }, + UNIVERSAL_LessThanEqual: { difference: makeSecondValue(is.GreaterThan) }, + LessThanEqual_And: { + union: RANGE_And_Union, + intersection: RANGE_And_Intersection, + difference: RANGE_And_Difference + }, + And_LessThanEqual: { difference: And_RANGE_Difference }, + LessThanEqual_Or: RANGE_Or, + Or_LessThanEqual: Or_RANGE, + And_And: { + union: function (and1, and2) { + var union1 = set.union(and1, and2.values[0]); + var union2 = set.union(and1, and2.values[1]); + if (isAndOrOr(union1) || isAndOrOr(union2)) { + union1 = set.union(and2, and1.values[0]); + union2 = set.union(and2, and1.values[1]); + } + if (isAndOrOr(union1) || isAndOrOr(union2)) { + return new is.Or([ + and1, + and2 + ]); + } else { + return set.intersection(union1, union2); + } + }, + intersection: function (and1, and2) { + var intersection1 = set.intersection(and1.values[0], and2.values[0]); + var intersection2 = set.intersection(and1.values[1], and2.values[1]); + if (!isAndOrOr(intersection1) || !isAndOrOr(intersection2)) { + return set.intersection(intersection1, intersection2); + } + intersection1 = set.intersection(and1.values[0], and2.values[1]); + intersection2 = set.intersection(and1.values[1], and2.values[0]); + if (!isAndOrOr(intersection1) || !isAndOrOr(intersection2)) { + return set.intersection(intersection1, intersection2); + } else { + return new is.And([ + and1, + and2 + ]); + } + }, + difference: function () { + return function (and1, and2) { + var d1 = set.difference(and1, and2.values[0]); + var d2 = set.difference(and1, and2.values[1]); + return set.union(d1, d2); + }; + }() + }, + And_Or: { + union: function (and, or) { + var aUnion = set.union(and.values[0], or); + var bUnion = set.union(and.values[1], or); + if (!isAndOrOr(aUnion) || !isAndOrOr(bUnion)) { + return set.intersection(aUnion, bUnion); + } + return new is.Or([ + and, + or + ]); + }, + intersection: function (and, or) { + var aIntersection = set.intersection(and, or.values[0]); + var bIntersection = set.intersection(and, or.values[1]); + if (!isOr(aIntersection) && !isOr(bIntersection)) { + return set.union(aIntersection, bIntersection); + } + return new is.And([ + and, + or + ]); + }, + difference: function (and, or) { + var aDiff = set.difference(and, or.values[0]); + var bDiff = set.difference(and, or.values[1]); + return set.intersection(aDiff, bDiff); + } + }, + Or_And: { + difference: function (or, and) { + var aDiff = set.difference(or, and.values[0]); + var bDiff = set.difference(or, and.values[1]); + return set.union(aDiff, bDiff); + } + }, + UNIVERSAL_And: { + difference: function (universe, and) { + var inverseFirst = set.difference(universe, and.values[0]), inverseSecond = set.difference(universe, and.values[1]); + return set.union(inverseFirst, inverseSecond); + } + }, + Or_Or: { + union: function (or1, or2) { + var union1 = set.union(or1.values[0], or2.values[0]); + var union2 = set.union(or1.values[1], or2.values[1]); + if (!isAndOrOr(union1) || !isAndOrOr(union2)) { + return set.union(union1, union2); + } + union1 = set.union(or1.values[0], or2.values[1]); + union2 = set.union(or1.values[1], or2.values[0]); + if (!isAndOrOr(union1) || !isAndOrOr(union2)) { + return set.union(union1, union2); + } else { + return new is.Or([ + or1, + or2 + ]); + } + }, + intersection: function (or1, or2) { + var c = or2.values[0], d = or2.values[1]; + var intersection1 = set.intersection(or1, c); + var intersection2 = set.intersection(or1, d); + if (!isOr(intersection1) || !isOr(intersection2)) { + return set.union(intersection1, intersection2); + } + intersection1 = set.union(or2, or1.values[0]); + intersection2 = set.union(or2, or1.values[1]); + if (!isOr(intersection1) || !isOr(intersection2)) { + return set.union(intersection1, intersection2); + } else { + return new is.Or([ + or1, + or2 + ]); + } + }, + difference: function (or1, or2) { + var d1 = set.difference(or1, or2.values[0]); + var d2 = set.difference(or1, or2.values[1]); + return set.intersection(d1, d2); + } + }, + UNIVERSAL_Or: { + difference: function (universe, or) { + var inverseFirst = set.difference(universe, or.values[0]), inverseSecond = set.difference(universe, or.values[1]); + return set.intersection(inverseFirst, inverseSecond); + } + } + }); + var names = Object.keys(comparisons); + names.forEach(function (name1, i) { + if (!comparators[name1 + '_' + name1]) { + console.warn('no ' + name1 + '_' + name1); + } else { + set.defineComparison(comparisons[name1], comparisons[name1], comparators[name1 + '_' + name1]); + } + if (!comparators['UNIVERSAL_' + name1]) { + console.warn('no UNIVERSAL_' + name1); + } else { + set.defineComparison(set.UNIVERSAL, comparisons[name1], comparators['UNIVERSAL_' + name1]); + } + for (var j = i + 1; j < names.length; j++) { + var name2 = names[j]; + if (!comparators[name1 + '_' + name2]) { + console.warn('no ' + name1 + '_' + name2); + } else { + set.defineComparison(comparisons[name1], comparisons[name2], comparators[name1 + '_' + name2]); + } + if (!comparators[name2 + '_' + name1]) { + console.warn('no ' + name2 + '_' + name1); + } else { + set.defineComparison(comparisons[name2], comparisons[name1], comparators[name2 + '_' + name1]); + } + } + }); + module.exports = comparisons; +}); +/*can-query-logic@1.2.2#src/types/make-real-number-range-inclusive*/ +define('can-query-logic@1.2.2#src/types/make-real-number-range-inclusive', [ + 'require', + 'exports', + 'module', + '../set', + './comparisons' +], function (require, exports, module) { + var set = require('../set'); + var is = require('./comparisons'); + module.exports = function (min, max) { + function RealNumberRangeInclusive(start, end) { + this.start = arguments.length > 0 ? +start : min; + this.end = arguments.length > 1 ? +end : max; + this.range = new is.And([ + new is.GreaterThanEqual(this.start), + new is.LessThanEqual(this.end) + ]); + } + var universeRange = new RealNumberRangeInclusive(min, max); + function isUniversal(range) { + return set.isSubset(universeRange.range, range.range); + } + function rangeFromAnd(aSet) { + var values = {}; + aSet.values.forEach(function (value) { + if (value instanceof is.GreaterThanEqual) { + values.start = value.value; + } + if (value instanceof is.GreaterThan) { + values.start = value.value + 1; + } + if (value instanceof is.LessThanEqual) { + values.end = value.value; + } + if (value instanceof is.LessThan) { + values.end = value.value - 1; + } + }); + if ('start' in values && 'end' in values) { + return new RealNumberRangeInclusive(values.start, values.end); + } + } + function toRange(aSet) { + var range; + if (aSet instanceof is.And) { + range = rangeFromAnd(aSet); + } + if (aSet instanceof is.Or) { + var first = rangeFromAnd(aSet.values[0]), second = rangeFromAnd(aSet.values[1]); + if (first && second) { + var firstValues = first.range.values, secondValues = second.range.values; + if (firstValues[1].value + 1 === secondValues[0].value) { + range = new RealNumberRangeInclusive(firstValues[0].value, secondValues[1].value); + } else if (secondValues[1].value + 1 === firstValues[0].value) { + range = new RealNumberRangeInclusive(secondValues[0].value, firstValues[1].value); + } else { + return set.UNDEFINABLE; + } + } else { + return set.UNDEFINABLE; + } + } + if (range && isUniversal(range)) { + return set.UNIVERSAL; + } else { + return range; + } + } + function intersection(range1, range2) { + var intersection = toRange(set.intersection(range1.range, range2.range)); + if (intersection) { + return intersection; + } else { + return set.EMPTY; + } + } + function difference(range1, range2) { + var difference = toRange(set.difference(range1.range, range2.range)); + if (difference) { + return difference; + } else { + return set.EMPTY; + } + } + set.defineComparison(RealNumberRangeInclusive, RealNumberRangeInclusive, { + union: function (range1, range2) { + var union = toRange(set.union(range1.range, range2.range)); + if (union) { + return union; + } else { + return set.EMPTY; + } + }, + intersection: intersection, + difference: difference + }); + set.defineComparison(set.UNIVERSAL, RealNumberRangeInclusive, { + difference: function (universe, range) { + if (isUniversal(range)) { + return set.EMPTY; + } else { + return difference(universeRange, range); + } + } + }); + return RealNumberRangeInclusive; + }; +}); +/*can-query-logic@1.2.2#src/types/values-or*/ +define('can-query-logic@1.2.2#src/types/values-or', [ + 'require', + 'exports', + 'module', + '../set', + './types' +], function (require, exports, module) { + var set = require('../set'); + var types = require('./types'); + function ValuesOr(values) { + this.values = values; + } + ValuesOr.prototype.isMember = function (props) { + return this.values.some(function (value) { + return value && value.isMember ? value.isMember(props) : value === props; + }); + }; + set.defineComparison(set.UNIVERSAL, ValuesOr, { + difference: function () { + return set.UNDEFINABLE; + } + }); + module.exports = types.ValuesOr = ValuesOr; +}); +/*can-query-logic@1.2.2#src/types/values-and*/ +define('can-query-logic@1.2.2#src/types/values-and', [ + 'require', + 'exports', + 'module', + './types', + '../set' +], function (require, exports, module) { + var keysLogic = require('./types'); + var set = require('../set'); + function ValuesAnd(values) { + this.values = values; + } + ValuesAnd.prototype.isMember = function (props) { + return this.values.every(function (value) { + return value && value.isMember ? value.isMember(props) : value === props; + }); + }; + set.defineComparison(set.UNIVERSAL, ValuesAnd, { + difference: function () { + return set.UNDEFINABLE; + } + }); + module.exports = keysLogic.ValuesAnd = ValuesAnd; +}); +/*can-query-logic@1.2.2#src/types/keys-and*/ +define('can-query-logic@1.2.2#src/types/keys-and', [ + 'require', + 'exports', + 'module', + '../set', + 'can-assign', + '../array-union-intersection-difference', + 'can-reflect', + 'can-key/get/get', + 'can-symbol', + 'can-reflect', + './types' +], function (require, exports, module) { + var set = require('../set'); + var assign = require('can-assign'); + var arrayUnionIntersectionDifference = require('../array-union-intersection-difference'); + var canReflect = require('can-reflect'); + var canGet = require('can-key/get/get'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var keysLogic = require('./types'); + function KeysAnd(values) { + var vals = this.values = {}; + canReflect.eachKey(values, function (value, key) { + if (canReflect.isPlainObject(value) && !set.isSpecial(value)) { + vals[key] = new KeysAnd(value); + } else { + vals[key] = value; + } + }); + } + var isMemberSymbol = canSymbol.for('can.isMember'); + KeysAnd.prototype.isMember = function (props, root, rootKey) { + var equal = true; + var preKey = rootKey ? rootKey + '.' : ''; + canReflect.eachKey(this.values, function (value, key) { + var isMember = value && (value[isMemberSymbol] || value.isMember); + if (isMember) { + if (!isMember.call(value, canGet(props, key), root || props, preKey + key)) { + equal = false; + } + } else { + if (value !== canGet(props, key)) { + equal = false; + } + } + }); + return equal; + }; + function checkIfUniversalAndReturnUniversal(setA) { + return set.isEqual(setA, set.UNIVERSAL) ? set.UNIVERSAL : setA; + } + var MISSING = {}; + function eachInUnique(a, acb, b, bcb, defaultReturn) { + var bCopy = assign({}, b), res; + for (var prop in a) { + res = acb(prop, a[prop], prop in b ? b[prop] : MISSING, a, b); + if (res !== undefined) { + return res; + } + delete bCopy[prop]; + } + for (prop in bCopy) { + res = bcb(prop, MISSING, b[prop], a, b); + if (res !== undefined) { + return res; + } + } + return defaultReturn; + } + function keyDiff(valuesA, valuesB) { + var keyResults = arrayUnionIntersectionDifference(Object.keys(valuesA), Object.keys(valuesB)); + return { + aOnlyKeys: keyResults.difference, + aAndBKeys: keyResults.intersection, + bOnlyKeys: arrayUnionIntersectionDifference(Object.keys(valuesB), Object.keys(valuesA)).difference + }; + } + function notEmpty(value) { + return value !== set.EMPTY; + } + function difference(objA, objB) { + var valuesA = objA.values, valuesB = objB.values, diff = keyDiff(valuesA, valuesB), aOnlyKeys = diff.aOnlyKeys, aAndBKeys = diff.aAndBKeys, bOnlyKeys = diff.bOnlyKeys; + var sharedKeysAndValues = {}, productAbleKeysAndData = {}, disjointKeysAndValues = {}; + aAndBKeys.forEach(function (key) { + var difference = set.difference(valuesA[key], valuesB[key]); + if (difference === set.EMPTY) { + sharedKeysAndValues[key] = valuesA[key]; + } else { + var intersection = set.intersection(valuesA[key], valuesB[key]); + var isProductable = intersection !== set.EMPTY; + if (isProductable) { + productAbleKeysAndData[key] = { + difference: difference, + intersection: intersection + }; + } else { + disjointKeysAndValues[key] = valuesA[key]; + } + } + }); + var productAbleKeys = Object.keys(productAbleKeysAndData); + var singleProductKeyAndValue; + if (productAbleKeys.length === 1) { + singleProductKeyAndValue = {}; + singleProductKeyAndValue[productAbleKeys[0]] = productAbleKeysAndData[productAbleKeys[0]].difference; + } + if (Object.keys(disjointKeysAndValues).length) { + return objA; + } + if (aOnlyKeys.length === 0 && bOnlyKeys.length === 0) { + if (productAbleKeys.length > 1) { + return set.UNDEFINABLE; + } else if (productAbleKeys.length === 1) { + assign(sharedKeysAndValues, singleProductKeyAndValue); + return new KeysAnd(sharedKeysAndValues); + } else { + return set.EMPTY; + } + } + if (aOnlyKeys.length > 0 && bOnlyKeys.length === 0) { + if (productAbleKeys.length > 1) { + return set.UNDEFINABLE; + } else if (productAbleKeys.length === 1) { + assign(sharedKeysAndValues, singleProductKeyAndValue); + aOnlyKeys.forEach(function (key) { + sharedKeysAndValues[key] = valuesA[key]; + }); + return new KeysAnd(sharedKeysAndValues); + } else { + return set.EMPTY; + } + } + if (aOnlyKeys.length === 0 && bOnlyKeys.length > 0) { + if (productAbleKeys.length > 1) { + return set.UNDEFINABLE; + } + var productAbleOr; + if (productAbleKeys.length === 1) { + var productableKey = productAbleKeys[0]; + productAbleOr = assign({}, sharedKeysAndValues); + productAbleOr[productableKey] = productAbleKeysAndData[productableKey].difference; + sharedKeysAndValues[productableKey] = productAbleKeysAndData[productableKey].intersection; + } + var ands = bOnlyKeys.map(function (key) { + var shared = assign({}, sharedKeysAndValues); + var result = shared[key] = set.difference(set.UNIVERSAL, valuesB[key]); + return result === set.EMPTY ? result : new KeysAnd(shared); + }).filter(notEmpty); + if (productAbleOr) { + ands.push(new KeysAnd(productAbleOr)); + } + if (ands.length > 1) { + return new keysLogic.ValuesOr(ands); + } else if (ands.length === 1) { + return ands[0]; + } else { + return set.EMPTY; + } + } + if (aOnlyKeys.length > 0 && bOnlyKeys.length > 0) { + if (productAbleKeys.length) { + throw new Error('Can\'t handle any productable keys right now'); + } + aOnlyKeys.forEach(function (key) { + sharedKeysAndValues[key] = valuesA[key]; + }); + if (bOnlyKeys.length === 1) { + var key = bOnlyKeys[0]; + var shared = assign({}, sharedKeysAndValues); + shared[key] = set.difference(set.UNIVERSAL, valuesB[key]); + return new KeysAnd(shared); + } else { + return set.UNDEFINABLE; + } + } + } + set.defineComparison(KeysAnd, KeysAnd, { + union: function (objA, objB) { + var diff = keyDiff(objA.values, objB.values); + var aAndBKeysThatAreNotEqual = [], sameKeys = {}; + diff.aAndBKeys.forEach(function (key) { + if (!set.isEqual(objA.values[key], objB.values[key])) { + aAndBKeysThatAreNotEqual.push(key); + } else { + sameKeys[key] = objA.values[key]; + } + }); + var aUnequal = {}, bUnequal = {}; + aAndBKeysThatAreNotEqual.forEach(function (key) { + aUnequal[key] = objA.values[key]; + bUnequal[key] = objB.values[key]; + }); + if (!diff.aOnlyKeys.length && !diff.bOnlyKeys.length) { + if (aAndBKeysThatAreNotEqual.length === 1) { + var keyValue = aAndBKeysThatAreNotEqual[0]; + var result = sameKeys[keyValue] = set.union(objA.values[keyValue], objB.values[keyValue]); + return canReflect.size(sameKeys) === 1 && set.isEqual(result, set.UNIVERSAL) ? set.UNIVERSAL : new KeysAnd(sameKeys); + } else if (aAndBKeysThatAreNotEqual.length === 0) { + return objA; + } + } + if (aAndBKeysThatAreNotEqual.length === 0) { + if (diff.aOnlyKeys.length > 0 && diff.bOnlyKeys.length === 0) { + return checkIfUniversalAndReturnUniversal(objB); + } else if (diff.aOnlyKeys.length === 0 && diff.bOnlyKeys.length > 0) { + return checkIfUniversalAndReturnUniversal(objA); + } + } + if (diff.aOnlyKeys.length > 0 && diff.bOnlyKeys.length === 0) { + if (set.isSubset(new KeysAnd(aUnequal), new KeysAnd(bUnequal))) { + return objB; + } + } + if (diff.bOnlyKeys.length > 0 && diff.aOnlyKeys.length === 0) { + if (set.isSubset(new KeysAnd(bUnequal), new KeysAnd(aUnequal))) { + return objA; + } + } + return new keysLogic.ValuesOr([ + objA, + objB + ]); + }, + intersection: function (objA, objB) { + var valuesA = objA.values, valuesB = objB.values, foundEmpty = false; + var resultValues = {}; + eachInUnique(valuesA, function (prop, aVal, bVal) { + resultValues[prop] = bVal === MISSING ? aVal : set.intersection(aVal, bVal); + if (resultValues[prop] === set.EMPTY) { + foundEmpty = true; + } + }, valuesB, function (prop, aVal, bVal) { + resultValues[prop] = bVal; + if (resultValues[prop] === set.EMPTY) { + foundEmpty = true; + } + }); + if (foundEmpty) { + return set.EMPTY; + } else { + return new KeysAnd(resultValues); + } + }, + difference: difference + }); + set.defineComparison(set.UNIVERSAL, KeysAnd, { + difference: function (universe, and) { + return difference({ values: {} }, and); + } + }); + module.exports = keysLogic.KeysAnd = KeysAnd; +}); +/*can-query-logic@1.2.2#src/types/and-or-not*/ +define('can-query-logic@1.2.2#src/types/and-or-not', [ + 'require', + 'exports', + 'module', + './values-or', + './values-not', + './values-and', + './keys-and' +], function (require, exports, module) { + var ValuesOr = require('./values-or'); + var ValuesNot = require('./values-not'); + var ValuesAnd = require('./values-and'); + var KeysAnd = require('./keys-and'); + module.exports = { + KeysAnd: KeysAnd, + ValuesOr: ValuesOr, + ValuesNot: ValuesNot, + ValuesAnd: ValuesAnd + }; +}); +/*can-query-logic@1.2.2#src/helpers*/ +define('can-query-logic@1.2.2#src/helpers', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var typeNumber = { + 'undefined': 0, + 'null': 1, + 'number': 3, + 'string': 4, + 'object': 5, + 'boolean': 6 + }; + var getTypeNumber = function (obj) { + var type = typeof obj; + if (obj === null) { + type = 'null'; + } + return typeNumber[type]; + }; + var typeCompare = { + $gt: function (valueA, valueB) { + return getTypeNumber(valueA) > getTypeNumber(valueB); + }, + $lt: function (valueA, valueB) { + return getTypeNumber(valueA) < getTypeNumber(valueB); + } + }; + var defaultCompare = { + $gt: function (valueA, valueB) { + if (valueA == null || valueB == null) { + return typeCompare.$gt(valueA, valueB); + } + return valueA > valueB; + }, + $lt: function (valueA, valueB) { + if (valueA == null || valueB == null) { + return typeCompare.$gt(valueA, valueB); + } + return valueA < valueB; + } + }; + var helpers = { + uniqueConcat: function (itemsA, itemsB, getId) { + var ids = new Set(); + return itemsA.concat(itemsB).filter(function (item) { + var id = getId(item); + if (!ids.has(id)) { + ids.add(id); + return true; + } else { + return false; + } + }); + }, + getIdentityIndex: function (compare, items, props, startIndex, schema) { + var identity = canReflect.getIdentity(props, schema), starterItem = items[startIndex]; + if (compare(props, starterItem) === 0) { + if (identity === canReflect.getIdentity(starterItem, schema)) { + return startIndex; + } + } + var rightResult = this.getIdentityIndexByDirection(compare, items, props, startIndex + 1, 1, schema), leftResult; + if (rightResult.index) { + return rightResult.index; + } else { + leftResult = this.getIdentityIndexByDirection(compare, items, props, startIndex - 1, -1, schema); + } + if (leftResult.index !== undefined) { + return leftResult.index; + } + return rightResult.lastIndex; + }, + getIdentityIndexByDirection: function (compare, items, props, startIndex, direction, schema) { + var currentIndex = startIndex; + var identity = canReflect.getIdentity(props, schema); + while (currentIndex >= 0 && currentIndex < items.length) { + var currentItem = items[currentIndex]; + var computed = compare(props, currentItem); + if (computed === 0) { + if (identity === canReflect.getIdentity(currentItem, schema)) { + return { index: currentIndex }; + } + } else { + return { lastIndex: currentIndex - direction }; + } + currentIndex = currentIndex + direction; + } + return { lastIndex: currentIndex - direction }; + }, + getIndex: function (compare, items, props, schema) { + if (!items || !items.length) { + return undefined; + } + if (compare(props, items[0]) === -1) { + return 0; + } else if (compare(props, items[items.length - 1]) === 1) { + return items.length; + } + var low = 0, high = items.length; + while (low < high) { + var mid = low + high >>> 1, item = items[mid], computed = compare(props, item); + if (computed === 0) { + return this.getIdentityIndex(compare, items, props, mid, schema); + } else if (computed === -1) { + high = mid; + } else { + low = mid + 1; + } + } + return high; + }, + sortData: function (sortPropValue) { + if (sortPropValue[0] === '-') { + return { + prop: sortPropValue.slice(1), + desc: true + }; + } else { + return { + prop: sortPropValue, + desc: false + }; + } + }, + defaultCompare: defaultCompare, + typeCompare: typeCompare, + sorter: function (sortPropValue, sorters) { + var data = helpers.sortData(sortPropValue); + var compare; + if (sorters && sorters[data.prop]) { + compare = sorters[data.prop]; + } else { + compare = defaultCompare; + } + return function (item1, item2) { + var item1Value = canReflect.getKeyValue(item1, data.prop); + var item2Value = canReflect.getKeyValue(item2, data.prop); + var temp; + if (data.desc) { + temp = item1Value; + item1Value = item2Value; + item2Value = temp; + } + if (compare.$lt(item1Value, item2Value)) { + return -1; + } + if (compare.$gt(item1Value, item2Value)) { + return 1; + } + return 0; + }; + }, + valueHydrator: function (value) { + if (canReflect.isBuiltIn(value)) { + return value; + } else { + throw new Error('can-query-logic doesn\'t support comparison operator: ' + JSON.stringify(value)); + } + } + }; + module.exports = helpers; +}); +/*can-query-logic@1.2.2#src/types/basic-query*/ +define('can-query-logic@1.2.2#src/types/basic-query', [ + 'require', + 'exports', + 'module', + '../set', + './make-real-number-range-inclusive', + 'can-assign', + 'can-reflect', + './and-or-not', + '../helpers', + 'can-define-lazy-value' +], function (require, exports, module) { + var set = require('../set'); + var makeRealNumberRangeInclusive = require('./make-real-number-range-inclusive'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var andOrNot = require('./and-or-not'); + var helpers = require('../helpers'); + var defineLazyValue = require('can-define-lazy-value'); + var KeysAnd = andOrNot.KeysAnd, Or = andOrNot.ValuesOr, Not = andOrNot.ValuesNot, And = andOrNot.ValuesAnd; + var RecordRange = makeRealNumberRangeInclusive(0, Infinity); + function makeSort(schema, hydrateAndValue) { + var schemaKeys = schema.keys; + var sorters = {}; + canReflect.eachKey(schemaKeys, function (schemaProp, key) { + sorters[key] = { + $gt: function (valueA, valueB) { + if (valueA == null || valueB == null) { + return helpers.typeCompare.$gt(valueA, valueB); + } + var $gt = hydrateAndValue({ $gt: valueB }, key, schemaProp, helpers.valueHydrator); + var $eq = hydrateAndValue({ $eq: valueA }, key, schemaProp, helpers.valueHydrator); + return set.isEqual(set.union($gt, $eq), $gt); + }, + $lt: function (valueA, valueB) { + if (valueA == null || valueB == null) { + return helpers.typeCompare.$lt(valueA, valueB); + } + var $lt = hydrateAndValue({ $lt: valueB }, key, schemaProp, helpers.valueHydrator); + var $eq = hydrateAndValue({ $eq: valueA }, key, schemaProp, helpers.valueHydrator); + return set.isEqual(set.union($lt, $eq), $lt); + } + }; + }); + function Sort(key) { + this.key = key; + this.schema = schema; + this.compare = helpers.sorter(key, sorters); + } + function identityIntersection(v1, v2) { + return v1.key === v2.key ? v1 : set.EMPTY; + } + function identityDifference(v1, v2) { + return v1.key === v2.key ? set.EMPTY : v1; + } + function identityUnion(v1, v2) { + return v1.key === v2.key ? v1 : set.UNDEFINABLE; + } + set.defineComparison(Sort, Sort, { + intersection: identityIntersection, + difference: identityDifference, + union: identityUnion + }); + return Sort; + } + var DefaultSort = makeSort({ + keys: {}, + identity: ['id'] + }); + function BasicQuery(query) { + assign(this, query); + if (!this.filter) { + this.filter = set.UNIVERSAL; + } + if (!this.page) { + this.page = new RecordRange(); + } + if (!this.sort) { + this.sort = 'id'; + } + if (typeof this.sort === 'string') { + this.sort = new DefaultSort(this.sort); + } + } + BasicQuery.KeysAnd = KeysAnd; + BasicQuery.Or = Or; + BasicQuery.Not = Not; + BasicQuery.And = And; + BasicQuery.RecordRange = RecordRange; + BasicQuery.makeSort = makeSort; + canReflect.assignMap(BasicQuery.prototype, { + count: function () { + return this.page.end - this.page.start + 1; + }, + sortData: function (data) { + return data.slice(0).sort(this.sort.compare); + }, + filterMembersAndGetCount: function (bData, parentQuery) { + var parentIsUniversal; + if (parentQuery) { + parentIsUniversal = set.isEqual(parentQuery.page, set.UNIVERSAL); + if (parentIsUniversal && !set.isEqual(parentQuery.filter, set.UNIVERSAL) && !set.isSubset(this, parentQuery)) { + throw new Error('can-query-logic: Unable to get members from a set that is not a superset of the current set.'); + } + } else { + parentQuery = new BasicQuery(); + } + var aData = bData.filter(function (data) { + return this.filter.isMember(data); + }, this); + var count = aData.length; + if (count && this.sort.key !== parentQuery.sort.key) { + aData = this.sortData(aData); + } + var thisIsUniversal = set.isEqual(this.page, set.UNIVERSAL); + if (parentIsUniversal == null) { + parentIsUniversal = set.isEqual(parentQuery.page, set.UNIVERSAL); + } + if (parentIsUniversal) { + if (thisIsUniversal) { + return { + data: aData, + count: count + }; + } else { + return { + data: aData.slice(this.page.start, this.page.end + 1), + count: count + }; + } + } else if (this.sort.key === parentQuery.sort.key && set.isEqual(parentQuery.filter, this.filter)) { + return { + data: aData.slice(this.page.start - parentQuery.page.start, this.page.end - parentQuery.page.start + 1), + count: count + }; + } else { + throw new Error('can-query-logic: Unable to get members from the parent set for this subset.'); + } + }, + filterFrom: function (bData, parentQuery) { + return this.filterMembersAndGetCount(bData, parentQuery).data; + }, + merge: function (b, aItems, bItems, getId) { + var union = set.union(this, b); + if (union === set.UNDEFINABLE) { + return undefined; + } else { + var combined = helpers.uniqueConcat(aItems, bItems, getId); + return union.sortData(combined); + } + }, + index: function (props, items) { + var data = helpers.sortData(this.sort.key); + if (!canReflect.hasOwnKey(props, data.prop)) { + return undefined; + } + return helpers.getIndex(this.sort.compare, items, props, this.sort.schema); + }, + isMember: function (props) { + return this.filter.isMember(props); + }, + removePagination: function () { + this.page = new RecordRange(); + } + }); + var CLAUSE_TYPES = [ + 'filter', + 'page', + 'sort' + ]; + function getDifferentClauseTypes(queryA, queryB) { + var differentTypes = []; + CLAUSE_TYPES.forEach(function (clause) { + if (!set.isEqual(queryA[clause], queryB[clause])) { + differentTypes.push(clause); + } + }); + return differentTypes; + } + function isSubset(subLetter, superLetter, meta) { + if (meta[subLetter + 'FilterIsSubset']) { + if (meta[superLetter + 'PageIsUniversal']) { + return true; + } else { + return meta[subLetter + 'PageIsSubset'] && meta.sortIsEqual; + } + } else { + return false; + } + } + function MetaInformation(queryA, queryB) { + this.queryA = queryA; + this.queryB = queryB; + } + canReflect.eachKey({ + 'pageIsEqual': function () { + return set.isEqual(this.queryA.page, this.queryB.page); + }, + 'aPageIsUniversal': function () { + return set.isEqual(this.queryA.page, set.UNIVERSAL); + }, + 'bPageIsUniversal': function () { + return set.isEqual(this.queryB.page, set.UNIVERSAL); + }, + 'pagesAreUniversal': function () { + return this.pageIsEqual && this.aPageIsUniversal; + }, + 'sortIsEqual': function () { + return this.queryA.sort.key === this.queryB.sort.key; + }, + 'aFilterIsSubset': function () { + return set.isSubset(this.queryA.filter, this.queryB.filter); + }, + 'bFilterIsSubset': function () { + return set.isSubset(this.queryB.filter, this.queryA.filter); + }, + 'aPageIsSubset': function () { + return set.isSubset(this.queryA.page, this.queryB.page); + }, + 'bPageIsSubset': function () { + return set.isSubset(this.queryB.page, this.queryA.page); + }, + 'filterIsEqual': function () { + return set.isEqual(this.queryA.filter, this.queryB.filter); + }, + 'aIsSubset': function () { + return isSubset('a', 'b', this); + }, + 'bIsSubset': function () { + return isSubset('b', 'a', this); + } + }, function (def, prop) { + defineLazyValue(MetaInformation.prototype, prop, def); + }); + function metaInformation(queryA, queryB) { + var meta = new MetaInformation(queryA, queryB); + return meta; + } + set.defineComparison(BasicQuery, BasicQuery, { + union: function (queryA, queryB) { + var meta = metaInformation(queryA, queryB); + var filterUnion = set.union(queryA.filter, queryB.filter); + if (meta.pagesAreUniversal) { + return new BasicQuery({ + filter: filterUnion, + sort: meta.sortIsEqual ? queryA.sort.key : undefined + }); + } + if (meta.filterIsEqual) { + if (meta.sortIsEqual) { + return new BasicQuery({ + filter: queryA.filter, + sort: queryA.sort.key, + page: set.union(queryA.page, queryB.page) + }); + } else { + if (meta.aIsSubset) { + return queryB; + } else if (meta.bIsSubset) { + return queryA; + } + return set.UNDEFINABLE; + } + } else { + throw new Error('different filters, non-universal pages'); + } + }, + intersection: function (queryA, queryB) { + var meta = metaInformation(queryA, queryB); + if (meta.pagesAreUniversal) { + var filterResult = set.intersection(queryA.filter, queryB.filter); + if (set.isDefinedAndHasMembers(filterResult)) { + return new BasicQuery({ + filter: filterResult, + sort: meta.sortIsEqual ? queryA.sort.key : undefined + }); + } else { + return filterResult; + } + } + if (set.intersection(queryA.filter, queryB.filter) === set.EMPTY) { + return set.EMPTY; + } + if (meta.filterIsEqual) { + if (meta.sortIsEqual) { + return new BasicQuery({ + filter: queryA.filter, + sort: queryA.sort.key, + page: set.intersection(queryA.page, queryB.page) + }); + } else { + if (meta.aIsSubset) { + return queryA; + } else if (meta.bIsSubset) { + return queryB; + } + return set.UNKNOWABLE; + } + } else { + if (meta.aIsSubset) { + return queryA; + } else if (meta.bIsSubset) { + return queryB; + } else { + return set.UNDEFINABLE; + } + } + }, + difference: function (queryA, queryB) { + var differentClauses = getDifferentClauseTypes(queryA, queryB); + var meta = metaInformation(queryA, queryB); + var clause; + if (differentClauses.length > 1) { + if (meta.aIsSubset) { + return set.EMPTY; + } + if (meta.pagesAreUniversal) { + return new BasicQuery({ + filter: set.difference(queryA.filter, queryB.filter), + sort: queryA.sort.key + }); + } + return set.UNDEFINABLE; + } else { + switch (clause = differentClauses[0]) { + case undefined: { + return set.EMPTY; + } + case 'sort': { + if (meta.pagesAreUniversal) { + return set.EMPTY; + } else { + return set.UNKNOWABLE; + } + } + break; + case 'page': + case 'filter': { + var result = set.difference(queryA[clause], queryB[clause]); + if (set.isSpecial(result)) { + return result; + } else { + var query = { + filter: queryA.filter, + page: queryA.page, + sort: queryA.sort.key + }; + query[clause] = result; + return new BasicQuery(query); + } + } + } + } + } + }); + module.exports = BasicQuery; +}); +/*can-query-logic@1.2.2#src/serializer*/ +define('can-query-logic@1.2.2#src/serializer', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var Serializer = function (entries) { + var serializers = this.serializers = new Map(); + if (entries) { + entries.forEach(function (entry) { + var key = entry[0], value = entry[1]; + serializers.set(key, value); + }); + } + this.serialize = this.serialize.bind(this); + }; + Serializer.prototype.add = function (serializers) { + canReflect.assign(this.serializers, serializers instanceof Serializer ? serializers.serializers : serializers); + }; + Serializer.prototype.serialize = function (item) { + if (!item) { + return item; + } + var Type = item.constructor; + var serializer = this.serializers.get(Type); + if (!serializer) { + return canReflect.serialize(item); + } else { + return serializer(item, this.serialize); + } + }; + module.exports = Serializer; +}); +/*can-query-logic@1.2.2#src/serializers/comparisons*/ +define('can-query-logic@1.2.2#src/serializers/comparisons', [ + 'require', + 'exports', + 'module', + '../types/comparisons', + '../serializer', + 'can-reflect', + '../types/values-not' +], function (require, exports, module) { + var is = require('../types/comparisons'); + var Serializer = require('../serializer'); + var canReflect = require('can-reflect'); + var ValuesNot = require('../types/values-not'); + function makeNew(Constructor) { + return function (value) { + return new Constructor(value); + }; + } + var hydrateMap = {}; + function addHydrateFrom(key, hydrate) { + hydrateMap[key] = function (value, unknownHydrator) { + return hydrate(unknownHydrator ? unknownHydrator(value[key]) : value[key]); + }; + Object.defineProperty(hydrateMap[key], 'name', { + value: 'hydrate ' + key, + writable: true + }); + } + function addHydrateFromValues(key, hydrate) { + hydrateMap[key] = function (value, unknownHydrator) { + var clones = value[key]; + if (unknownHydrator) { + clones = clones.map(function (value) { + return unknownHydrator(value); + }); + } + return hydrate(clones); + }; + Object.defineProperty(hydrateMap[key], 'name', { + value: 'hydrate ' + key, + writable: true + }); + } + addHydrateFrom('$eq', function (value) { + return new is.In([value]); + }); + addHydrateFrom('$ne', function (value) { + return new is.NotIn([value]); + }); + addHydrateFrom('$gt', makeNew(is.GreaterThan)); + addHydrateFrom('$gte', makeNew(is.GreaterThanEqual)); + addHydrateFromValues('$in', makeNew(is.In)); + addHydrateFrom('$lt', makeNew(is.LessThan)); + addHydrateFrom('$lte', makeNew(is.LessThanEqual)); + addHydrateFromValues('$all', makeNew(is.All)); + var oppositeTypeMap = { + LessThan: { + Type: is.GreaterThanEqual, + prop: 'value' + }, + LessThanEqual: { + Type: is.GreaterThan, + prop: 'value' + }, + GreaterThan: { + Type: is.LessThanEqual, + prop: 'value' + }, + GreaterThanEqual: { + Type: is.LessThan, + prop: 'value' + }, + In: { + Type: is.NotIn, + prop: 'values' + }, + NotIn: { + Type: is.In, + prop: 'values' + } + }; + hydrateMap.$not = function (value, unknownHydrator) { + var hydratedValue = hydrateValue(value.$not, unknownHydrator); + var typeName = hydratedValue.constructor.name || hydratedValue.constructor.toString().match(/^\s*function\s*(\S*)\s*\(/)[1]; + if (oppositeTypeMap[typeName]) { + var options = oppositeTypeMap[typeName]; + var OppositeConstructor = options.Type; + var prop = options.prop; + return new OppositeConstructor(hydratedValue[prop]); + } + return new ValuesNot(hydratedValue); + }; + addHydrateFromValues('$nin', makeNew(is.NotIn)); + var serializer = new Serializer([ + [ + is.In, + function (isIn, serialize) { + return isIn.values.length === 1 ? serialize(isIn.values[0]) : { $in: isIn.values.map(serialize) }; + } + ], + [ + is.NotIn, + function (notIn, serialize) { + return notIn.values.length === 1 ? { $ne: serialize(notIn.values[0]) } : { $nin: notIn.values.map(serialize) }; + } + ], + [ + is.GreaterThan, + function (gt, serialize) { + return { $gt: serialize(gt.value) }; + } + ], + [ + is.GreaterThanEqual, + function (gte, serialize) { + return { $gte: serialize(gte.value) }; + } + ], + [ + is.LessThan, + function (lt, serialize) { + return { $lt: serialize(lt.value) }; + } + ], + [ + is.LessThanEqual, + function (lt, serialize) { + return { $lte: serialize(lt.value) }; + } + ], + [ + is.And, + function (and, serialize) { + var obj = {}; + and.values.forEach(function (clause) { + canReflect.assignMap(obj, serialize(clause)); + }); + return obj; + } + ], + [ + is.All, + function (all, serialize) { + return { $all: serialize(all.values) }; + } + ] + ]); + function hydrateValue(value, hydrateUnknown) { + if (!hydrateUnknown) { + hydrateUnknown = function () { + throw new Error('can-query-logic doesn\'t recognize operator: ' + JSON.stringify(value)); + }; + } + if (Array.isArray(value)) { + return new is.In(value.map(function (value) { + return hydrateUnknown(value); + })); + } else if (value && typeof value === 'object') { + var keys = Object.keys(value); + var allKeysAreComparisons = keys.every(function (key) { + return hydrateMap[key]; + }); + if (allKeysAreComparisons) { + var andClauses = keys.map(function (key) { + var part = {}; + part[key] = value[key]; + var hydrator = hydrateMap[key]; + return hydrator(part, hydrateUnknown); + }); + if (andClauses.length > 1) { + return new is.And(andClauses); + } else { + return andClauses[0]; + } + } else { + return hydrateUnknown(value); + } + } else { + return new is.In([hydrateUnknown(value)]); + } + } + module.exports = { + hydrate: hydrateValue, + serializer: serializer + }; +}); +/*can-query-logic@1.2.2#src/schema-helpers*/ +define('can-query-logic@1.2.2#src/schema-helpers', [ + 'require', + 'exports', + 'module', + 'can-reflect', + './set', + 'can-symbol' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var set = require('./set'); + var canSymbol = require('can-symbol'); + var schemaHelpers; + module.exports = schemaHelpers = { + isRangedType: function (Type) { + return Type && canReflect.isConstructorLike(Type) && !set.hasComparisons(Type) && !Type[canSymbol.for('can.SetType')] && Type.prototype.valueOf && Type.prototype.valueOf !== Object.prototype.valueOf; + }, + categorizeOrValues: function categorizeOrValues(values) { + var categories = { + primitives: [], + valueOfTypes: [], + others: [] + }; + values.forEach(function (value) { + if (canReflect.isPrimitive(value)) { + categories.primitives.push(value); + } else if (schemaHelpers.isRangedType(value)) { + categories.valueOfTypes.push(value); + } else { + categories.others.push(value); + } + }); + return categories; + } + }; +}); +/*can-query-logic@1.2.2#src/types/make-maybe*/ +define('can-query-logic@1.2.2#src/types/make-maybe', [ + 'require', + 'exports', + 'module', + '../set', + './comparisons', + 'can-reflect', + '../schema-helpers', + 'can-symbol' +], function (require, exports, module) { + var set = require('../set'); + var is = require('./comparisons'); + var canReflect = require('can-reflect'); + var schemaHelpers = require('../schema-helpers'); + var canSymbol = require('can-symbol'); + var comparisonSetTypeSymbol = canSymbol.for('can.ComparisonSetType'); + var isMemberSymbol = canSymbol.for('can.isMember'); + function splitByRangeAndEnum(maybeUniverse, rangeToBeSplit) { + var enumSet; + if (rangeToBeSplit instanceof is.And) { + var sets = rangeToBeSplit.values.map(function (setInAnd) { + return splitByRangeAndEnum(maybeUniverse, setInAnd); + }); + return sets.reduce(function (last, maybe) { + return { + range: set.intersection(last.range, maybe.range), + enum: set.intersection(last.enum, maybe.enum) + }; + }, { + range: set.UNIVERSAL, + enum: maybeUniverse + }); + } else if (rangeToBeSplit instanceof is.In) { + var shouldBeInValues = rangeToBeSplit.values.filter(function (value) { + return maybeUniverse.isMember(value); + }); + if (shouldBeInValues.length) { + var valuesCopy = rangeToBeSplit.values.slice(0); + canReflect.removeValues(valuesCopy, shouldBeInValues); + return { + enum: new is.In(shouldBeInValues), + range: valuesCopy.length ? new is.In(valuesCopy) : set.EMPTY + }; + } else { + return { + enum: set.EMPTY, + range: rangeToBeSplit + }; + } + } else if (rangeToBeSplit instanceof is.NotIn) { + enumSet = set.intersection(maybeUniverse, rangeToBeSplit); + var rangeValues = rangeToBeSplit.values.filter(function (value) { + return !maybeUniverse.isMember(value); + }); + return { + range: rangeValues.length ? new is.NotIn(rangeValues) : set.UNIVERSAL, + enum: enumSet + }; + } else { + return { + enum: set.EMPTY, + range: rangeToBeSplit + }; + } + } + function makeMaybe(inValues, makeChildType) { + var maybeUniverse = new is.In(inValues); + function Maybe(values) { + var result = splitByRangeAndEnum(maybeUniverse, values.range); + this.range = result.range || set.EMPTY; + if (values.enum) { + if (result.enum !== set.EMPTY) { + this.enum = set.union(result.enum, values.enum); + } else { + this.enum = values.enum; + } + } else { + this.enum = result.enum; + } + if (this.enum === set.EMPTY && this.range === set.EMPTY) { + return set.EMPTY; + } + } + Maybe.prototype.orValues = function () { + var values = []; + if (this.range !== set.EMPTY) { + values.push(this.range); + } + if (this.enum !== set.EMPTY) { + values.push(this.enum); + } + return values; + }; + Maybe.prototype[isMemberSymbol] = function isMember() { + var rangeIsMember = this.range[isMemberSymbol] || this.range.isMember, enumIsMember = this.enum[isMemberSymbol] || this.enum.isMember; + return rangeIsMember.apply(this.range, arguments) || enumIsMember.apply(this.enum, arguments); + }; + set.defineComparison(Maybe, Maybe, { + union: function (maybeA, maybeB) { + var enumSet = set.union(maybeA.enum, maybeB.enum); + var range = set.union(maybeA.range, maybeB.range); + return new Maybe({ + enum: enumSet, + range: range + }); + }, + difference: function (maybeA, maybeB) { + var enumSet = set.difference(maybeA.enum, maybeB.enum); + var range = set.difference(maybeA.range, maybeB.range); + return new Maybe({ + enum: enumSet, + range: range + }); + }, + intersection: function (maybeA, maybeB) { + var enumSet = set.intersection(maybeA.enum, maybeB.enum); + var range = set.intersection(maybeA.range, maybeB.range); + return new Maybe({ + enum: enumSet, + range: range + }); + } + }); + Maybe.inValues = inValues; + set.defineComparison(set.UNIVERSAL, Maybe, { + difference: function (universe, maybe) { + var primary, secondary; + if (maybe.range === set.UNIVERSAL) { + return new Maybe({ + range: maybe.range, + enum: set.difference(maybeUniverse, maybe.enum) + }); + } + if (maybe.enum === set.EMPTY) { + var rangeSet = set.difference(set.UNIVERSAL, maybe.range); + var notPresent = set.difference(maybeUniverse, maybe.range); + var enumSet = set.difference(notPresent, rangeSet); + return new Maybe({ + range: rangeSet, + enum: enumSet + }); + } else { + primary = set.difference(universe, maybe.range); + secondary = set.difference(maybeUniverse, maybe.enum); + } + return new Maybe({ + enum: secondary, + range: primary + }); + } + }); + makeChildType = makeChildType || function (v) { + return v; + }; + Maybe.hydrate = function (value, childHydrate) { + return new Maybe({ range: childHydrate(value, makeChildType) }); + }; + return Maybe; + } + makeMaybe.canMakeMaybeSetType = function (Type) { + var schema = canReflect.getSchema(Type); + if (schema && schema.type === 'Or') { + var categories = schemaHelpers.categorizeOrValues(schema.values); + return categories.valueOfTypes.length === 1 && categories.valueOfTypes.length + categories.primitives.length === schema.values.length; + } + return false; + }; + makeMaybe.makeMaybeSetTypes = function (Type) { + var schema = canReflect.getSchema(Type); + var categories = schemaHelpers.categorizeOrValues(schema.values); + var ComparisonSetType; + if (Type[comparisonSetTypeSymbol]) { + ComparisonSetType = Type[comparisonSetTypeSymbol]; + } else { + ComparisonSetType = function (value) { + this.value = canReflect.new(Type, value); + }; + ComparisonSetType.prototype.valueOf = function () { + return this.value; + }; + canReflect.assignSymbols(ComparisonSetType.prototype, { + 'can.serialize': function () { + return this.value; + } + }); + } + return { + Maybe: makeMaybe(categories.primitives, function hydrateMaybesValueType(value) { + return new ComparisonSetType(value); + }), + ComparisonSetType: ComparisonSetType + }; + }; + module.exports = makeMaybe; +}); +/*can-query-logic@1.2.2#src/types/make-enum*/ +define('can-query-logic@1.2.2#src/types/make-enum', [ + 'require', + 'exports', + 'module', + '../set', + '../array-union-intersection-difference', + '../schema-helpers', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + var set = require('../set'); + var arrayUnionIntersectionDifference = require('../array-union-intersection-difference'); + var schemaHelpers = require('../schema-helpers'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var setTypeSymbol = canSymbol.for('can.SetType'), isMemberSymbol = canSymbol.for('can.isMember'), newSymbol = canSymbol.for('can.new'); + function makeEnumSetType(allValues, hydrate) { + function Enum(values) { + var arr = Array.isArray(values) ? values : [values]; + this.values = hydrate ? arr.map(hydrate) : arr; + } + canReflect.assignSymbols(Enum.prototype, { + 'can.serialize': function () { + return this.values.length === 1 ? this.values[0] : this.values; + } + }); + Enum.prototype[isMemberSymbol] = function (value) { + return this.values.some(function (val) { + return set.isEqual(val, value); + }); + }; + Enum.UNIVERSAL = new Enum(allValues); + var difference = function (enum1, enum2) { + var result = arrayUnionIntersectionDifference(enum1.values, enum2.values); + if (result.difference.length) { + return new Enum(result.difference); + } else { + return set.EMPTY; + } + }; + set.defineComparison(Enum, Enum, { + union: function (enum1, enum2) { + var result = arrayUnionIntersectionDifference(enum1.values, enum2.values); + if (result.union.length) { + return new Enum(result.union); + } else { + return set.EMPTY; + } + }, + intersection: function (enum1, enum2) { + var result = arrayUnionIntersectionDifference(enum1.values, enum2.values); + if (result.intersection.length) { + return new Enum(result.intersection); + } else { + return set.EMPTY; + } + }, + difference: difference + }); + set.defineComparison(Enum, set.UNIVERSAL, { + difference: function (enumA) { + return difference(enumA, { values: allValues.slice(0) }); + } + }); + set.defineComparison(set.UNIVERSAL, Enum, { + difference: function (universe, enumB) { + return difference({ values: allValues.slice(0) }, enumB); + } + }); + return Enum; + } + function makeEnum(Type, allValues, hydrate) { + var Enum = makeEnumSetType(allValues, hydrate); + Type[setTypeSymbol] = Enum; + Type[isMemberSymbol] = function (value) { + return allValues.some(function (val) { + return set.isEqual(val, value); + }); + }; + return Enum; + } + makeEnum.canMakeEnumSetType = function (Type) { + var schema = canReflect.getSchema(Type); + if (schema && schema.type === 'Or') { + var categories = schemaHelpers.categorizeOrValues(schema.values); + return categories.primitives.length === schema.values.length; + } + return false; + }; + makeEnum.makeEnumSetType = function (Type) { + var schema = canReflect.getSchema(Type); + var categories = schemaHelpers.categorizeOrValues(schema.values); + var hydrate = Type[newSymbol] ? Type[newSymbol].bind(Type) : undefined; + return makeEnumSetType(categories.primitives, hydrate); + }; + module.exports = makeEnum; +}); +/*can-query-logic@1.2.2#src/serializers/basic-query*/ +define('can-query-logic@1.2.2#src/serializers/basic-query', [ + 'require', + 'exports', + 'module', + 'can-symbol', + 'can-reflect', + '../types/basic-query', + '../set', + '../serializers/comparisons', + '../serializer', + '../types/comparisons', + '../types/make-maybe', + '../types/make-enum', + 'can-log/dev/dev', + '../helpers' +], function (require, exports, module) { + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var BasicQuery = require('../types/basic-query'); + var set = require('../set'); + var comparisonsConverter = require('../serializers/comparisons'); + var Serializer = require('../serializer'); + var is = require('../types/comparisons'); + var makeMaybe = require('../types/make-maybe'); + var makeEnum = require('../types/make-enum'); + var logDev = require('can-log/dev/dev'); + var helpers = require('../helpers'); + var setTypeSymbol = canSymbol.for('can.SetType'); + var schemaSymbol = canSymbol.for('can.getSchema'); + var defaultQuery = new BasicQuery({}); + function getSchemaProperties(value) { + var constructor = value.constructor; + if (constructor && constructor[schemaSymbol]) { + var schema = constructor[schemaSymbol](); + return schema.keys || {}; + } else { + return {}; + } + } + function hydrateFilter(values, schemaProperties, hydrateUnknown) { + var valuesIsObject = values && typeof values === 'object'; + if (valuesIsObject && '$or' in values) { + return hydrateOrs(values.$or, schemaProperties, hydrateUnknown); + } else if (valuesIsObject && '$and' in values) { + return hydrateAnds(values.$and, schemaProperties, hydrateUnknown); + } else { + return hydrateAndValues(values, schemaProperties, hydrateUnknown); + } + } + var setTypeMap = new WeakMap(); + function hydrateAndValue(value, prop, SchemaType, hydrateChild) { + if (SchemaType) { + var SetType = SchemaType[setTypeSymbol]; + if (SetType) { + if (SetType.hydrate) { + return SetType.hydrate(value, comparisonsConverter.hydrate); + } else if (set.hasComparisons(SetType)) { + return new SetType(value); + } else { + return comparisonsConverter.hydrate(value, function (value) { + return new SetType(value); + }); + } + } else { + if (makeEnum.canMakeEnumSetType(SchemaType)) { + if (!setTypeMap.has(SchemaType)) { + setTypeMap.set(SchemaType, makeEnum.makeEnumSetType(SchemaType)); + } + SetType = setTypeMap.get(SchemaType); + return new SetType(value); + } else if (makeMaybe.canMakeMaybeSetType(SchemaType)) { + if (!setTypeMap.has(SchemaType)) { + setTypeMap.set(SchemaType, makeMaybe.makeMaybeSetTypes(SchemaType)); + } + SetType = setTypeMap.get(SchemaType).Maybe; + return SetType.hydrate(value, comparisonsConverter.hydrate); + } else { + return comparisonsConverter.hydrate(value, hydrateChild); + } + } + } else { + return comparisonsConverter.hydrate(value, hydrateChild); + } + } + function hydrateAndValues(values, schemaProperties, hydrateUnknown) { + schemaProperties = schemaProperties || {}; + function hydrateChild(value) { + if (value) { + if (Array.isArray(value)) { + return value.map(hydrateUnknown); + } else if (canReflect.isPlainObject(value)) { + return hydrateAndValues(value, getSchemaProperties(value)); + } + } + if (hydrateUnknown) { + return hydrateUnknown(value); + } else { + return value; + } + } + var clone = {}; + canReflect.eachKey(values, function (value, prop) { + clone[prop] = hydrateAndValue(value, prop, schemaProperties[prop], hydrateChild); + }); + return new BasicQuery.KeysAnd(clone); + } + function combineAnds(ands) { + var firstKeys = Object.keys(ands[0].values); + var keys = {}; + var keysCompare = new is.In(firstKeys); + firstKeys.map(function (key) { + keys[key] = []; + }); + var sameKeys = ands.every(function (and) { + if (!set.isEqual(keysCompare, new is.In(Object.keys(and.values)))) { + return false; + } + canReflect.eachKey(and.values, function (value, key) { + keys[key].push(value); + }); + return true; + }); + if (!sameKeys) { + return; + } + var unequalKeys = []; + firstKeys.forEach(function (key) { + var isEqual = keys[key].reduce(function (newSet, lastSetOrFalse) { + if (lastSetOrFalse === false) { + return false; + } + if (lastSetOrFalse === undefined) { + return newSet; + } + var res = set.isEqual(newSet, lastSetOrFalse); + return res ? newSet : false; + }); + if (!isEqual) { + unequalKeys.push(key); + } + }); + if (unequalKeys.length !== 1) { + return; + } + var unionKey = unequalKeys[0]; + var unioned = keys[unionKey].reduce(function (cur, last) { + return set.union(cur, last); + }, set.EMPTY); + var result = {}; + firstKeys.map(function (key) { + result[key] = keys[key][0]; + }); + result[unionKey] = unioned; + return new BasicQuery.KeysAnd(result); + } + function hydrateOrs(values, schemaProperties, hydrateUnknown) { + var comparisons = values.map(function (value) { + return hydrateAndValues(value, schemaProperties, hydrateUnknown); + }); + var combined = combineAnds(comparisons); + if (combined) { + return combined; + } + return new BasicQuery.Or(comparisons); + } + function hydrateAnds(values, schemaProperties, hydrateUnknown) { + var comparisons = values.map(function (value) { + return hydrateAndValues(value, schemaProperties, hydrateUnknown); + }); + return new BasicQuery.And(comparisons); + } + function recursivelyAddOrs(ors, value, serializer, key) { + value.orValues().forEach(function (orValue) { + if (typeof orValue.orValues === 'function') { + recursivelyAddOrs(ors, orValue, serializer, key); + } else { + var result = {}; + result[key] = serializer(orValue); + ors.push(result); + } + }); + } + module.exports = function (schema) { + var id = schema.identity && schema.identity[0]; + var keys = schema.keys; + var serializeMap = [ + [ + BasicQuery.Or, + function (or, serializer) { + return or.values.map(function (value) { + return serializer(value); + }); + } + ], + [ + BasicQuery.And, + function (and, serializer) { + return { + $and: and.values.map(function (value) { + return serializer(value); + }) + }; + } + ], + [ + BasicQuery.Not, + function (nots, serializer) { + return { $not: serializer(nots.value) }; + } + ], + [ + BasicQuery.KeysAnd, + function (and, serializer) { + var ors = []; + var result = {}; + canReflect.eachKey(and.values, function (value, key) { + if (typeof value.orValues === 'function') { + recursivelyAddOrs(ors, value, serializer, key); + } else { + result[key] = serializer(value); + } + }); + if (ors.length) { + if (ors.length === 1) { + return ors[0]; + } else { + return { + $or: ors.map(function (orPart) { + return canReflect.assign(canReflect.serialize(result), orPart); + }) + }; + } + } else { + return result; + } + } + ], + [ + BasicQuery.RecordRange, + function (range) { + return { + start: range.start, + end: range.end + }; + } + ], + [ + BasicQuery, + function (basicQuery, childSerializer) { + var filter = set.isEqual(basicQuery.filter, set.UNIVERSAL) ? {} : childSerializer(basicQuery.filter); + var res = {}; + if (canReflect.size(filter) !== 0) { + res.filter = filter; + } + if (!set.isEqual(basicQuery.page, defaultQuery.page)) { + res.page = { start: basicQuery.page.start }; + if (basicQuery.page.end !== defaultQuery.page.end) { + res.page.end = basicQuery.page.end; + } + } + if (basicQuery.sort.key !== id) { + res.sort = basicQuery.sort.key; + } + return res; + } + ] + ]; + var Sort = BasicQuery.makeSort(schema, hydrateAndValue); + var serializer = new Serializer(serializeMap); + serializer.add(comparisonsConverter.serializer); + return { + hydrate: function (data) { + var filter = canReflect.serialize(data.filter); + var filterAnd = hydrateFilter(filter, keys, helpers.valueHydrator); + var query = { filter: filterAnd }; + if (data.page) { + query.page = new BasicQuery.RecordRange(data.page.start, data.page.end); + } + if (data.sort) { + query.sort = new Sort(data.sort); + } else { + query.sort = new Sort(id); + } + return new BasicQuery(query); + }, + serializer: serializer + }; + }; +}); +/*can-query-logic@1.2.2#can-query-logic*/ +define('can-query-logic@1.2.2#can-query-logic', [ + 'require', + 'exports', + 'module', + './src/set', + 'can-symbol', + 'can-reflect', + './src/serializers/basic-query', + './src/types/basic-query', + './src/types/comparisons', + './src/types/make-enum' +], function (require, exports, module) { + var set = require('./src/set'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var makeBasicQueryConvert = require('./src/serializers/basic-query'); + var BasicQuery = require('./src/types/basic-query'); + var valueComparisons = require('./src/types/comparisons'); + var schemaSymbol = canSymbol.for('can.getSchema'); + var newSymbol = canSymbol.for('can.new'); + var makeEnum = require('./src/types/make-enum'); + function QueryLogic(Type, options) { + Type = Type || {}; + var passedHydrator = options && options.toQuery; + var passedSerializer = options && options.toParams; + var schema; + if (Type[schemaSymbol]) { + schema = Type[schemaSymbol](); + } else { + schema = Type; + } + var id = schema.identity && schema.identity[0]; + if (!id) { + schema.identity = ['id']; + } + var converter = makeBasicQueryConvert(schema), hydrate, serialize; + if (passedHydrator) { + hydrate = function (query) { + return converter.hydrate(passedHydrator(query)); + }; + } else { + hydrate = converter.hydrate; + } + if (passedSerializer) { + serialize = function (query) { + return passedSerializer(converter.serializer.serialize(query)); + }; + } else { + serialize = converter.serializer.serialize; + } + this.hydrate = hydrate; + this.serialize = serialize; + this.schema = schema; + } + function makeNewSet(prop) { + return function (qA, qB) { + var queryA = this.hydrate(qA), queryB = this.hydrate(qB); + var unionQuery = set[prop](queryA, queryB); + return this.serialize(unionQuery); + }; + } + function makeReturnValue(prop) { + return function (qA, qB) { + var queryA = this.hydrate(qA), queryB = this.hydrate(qB); + return set[prop](queryA, queryB); + }; + } + canReflect.assignSymbols(QueryLogic.prototype, { + 'can.getSchema': function () { + return this.schema; + } + }); + canReflect.assign(QueryLogic.prototype, { + union: makeNewSet('union'), + difference: makeNewSet('difference'), + intersection: makeNewSet('intersection'), + isEqual: makeReturnValue('isEqual'), + isProperSubset: makeReturnValue('isProperSubset'), + isSubset: makeReturnValue('isSubset'), + isSpecial: set.isSpecial, + isDefinedAndHasMembers: set.isDefinedAndHasMembers, + count: function (a) { + var queryA = this.hydrate(a); + return queryA.page.end - queryA.page.start + 1; + }, + identityKeys: function () { + return this.schema.identity; + }, + filterMembers: function (a, b, bData) { + var queryA = this.hydrate(a); + if (arguments.length >= 3) { + var queryB = this.hydrate(b); + return queryA.filterFrom(bData, queryB); + } else { + return queryA.filterFrom(b); + } + }, + filterMembersAndGetCount: function (a, b, bData) { + var queryA = this.hydrate(a), queryB = this.hydrate(b); + return queryA.filterMembersAndGetCount(bData, queryB); + }, + unionMembers: function (a, b, aData, bData) { + var queryA = this.hydrate(a), queryB = this.hydrate(b); + var schema = this.schema; + return queryA.merge(queryB, aData, bData, function (obj) { + return canReflect.getIdentity(obj, schema); + }); + }, + isMember: function (query, props) { + return this.hydrate(query).isMember(props); + }, + memberIdentity: function (props) { + return canReflect.getIdentity(props, this.schema); + }, + index: function (query, items, props) { + return this.hydrate(query).index(props, items); + }, + insert: function (query, items, item) { + var index = this.index(query, items, item); + if (index === undefined) { + index = items.length; + } + var copy = items.slice(0); + copy.splice(index, 0, item); + return copy; + }, + isPaginated: function (query) { + var basicQuery = this.hydrate(query); + return !set.isEqual(basicQuery.page, set.UNIVERSAL); + }, + removePagination: function (query) { + var basicQuery = this.hydrate(query); + basicQuery.removePagination(); + return this.serialize(basicQuery); + } + }); + for (var prop in set) { + if (QueryLogic[prop] === undefined) { + QueryLogic[prop] = set[prop]; + } + } + QueryLogic.makeEnum = function (values) { + var Type = function () { + }; + Type[newSymbol] = function (val) { + return val; + }; + makeEnum(Type, values); + return Type; + }; + QueryLogic.KeysAnd = BasicQuery.KeysAnd; + QueryLogic.ValuesOr = BasicQuery.Or; + QueryLogic.In = valueComparisons.In; + QueryLogic.NotIn = valueComparisons.NotIn; + QueryLogic.GreaterThan = valueComparisons.GreaterThan; + QueryLogic.GreaterThanEqual = valueComparisons.GreaterThanEqual; + QueryLogic.LessThan = valueComparisons.LessThan; + QueryLogic.LessThanEqual = valueComparisons.LessThanEqual; + QueryLogic.ValueAnd = valueComparisons.And; + QueryLogic.ValueOr = valueComparisons.Or; + module.exports = QueryLogic; +}); +/*can-type@1.1.5#test/type-methods-test*/ +define('can-type@1.1.5#test/type-methods-test', [ + 'require', + 'exports', + 'module', + 'can-symbol', + 'can-reflect', + '../can-type', + 'steal-qunit', + 'can-test-helpers', + 'can-query-logic' +], function (require, exports, module) { + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var type = require('../can-type'); + var QUnit = require('steal-qunit'); + var dev = require('can-test-helpers').dev; + var QueryLogic = require('can-query-logic'); + var newSymbol = canSymbol.for('can.new'); + var isMemberSymbol = canSymbol.for('can.isMember'); + var getSchemaSymbol = canSymbol.for('can.getSchema'); + QUnit.module('can-type - Type methods'); + function equal(assert, result, expected) { + assert.equal(result, expected, 'Result matches expected'); + } + function strictEqual(assert, result, expected) { + assert.strictEqual(result, expected, 'Result matches expected strictly'); + } + function isNaN(assert, result) { + assert.ok(result !== result, 'Is NaN value'); + } + function ok(assert, reason) { + assert.ok(true, reason || 'Expected to throw'); + } + function notOk(assert, reason) { + assert.ok(false, reason || 'Expected to throw'); + } + function throwsBecauseOfWrongType(assert) { + ok(assert, 'Throws when the wrong type is provided'); + } + function shouldHaveThrownBecauseOfWrongType(assert) { + notOk(assert, 'Should have thrown because the wrong type was provided'); + } + var checkIsNaN = { check: isNaN }; + var checkDateMatchesNumber = { + check: function (assert, date, num) { + assert.strictEqual(date.getTime(), num, 'Converted number to date'); + } + }; + var checkValue = function (comparison) { + return { + check: function (assert, result) { + assert.strictEqual(result, comparison, 'value has been correctly converted'); + } + }; + }; + var checkBoolean = function (comparison) { + return { + check: function (assert, result) { + assert.strictEqual(result, comparison, 'Boolean has been correctly converted'); + } + }; + }; + var checkNumber = function (comparison) { + return { + check: function (assert, result) { + assert.strictEqual(result, comparison, 'Number has been correctly converted'); + } + }; + }; + var matrix = { + convert: { check: equal }, + maybeConvert: { check: equal } + }; + if ("production" !== 'production') { + canReflect.assignMap(matrix, { + check: { + check: strictEqual, + throws: throwsBecauseOfWrongType + }, + maybe: { + check: strictEqual, + throws: throwsBecauseOfWrongType + } + }); + } + var dateAsNumber = new Date(1815, 11, 10).getTime(); + var Integer = {}; + Integer[newSymbol] = function (val) { + return parseInt(val); + }; + Integer[isMemberSymbol] = function (value) { + return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; + }; + canReflect.setName(Integer, 'CustomInteger'); + var testCases = [ + { + Type: Boolean, + value: true + }, + { + Type: Boolean, + value: false + }, + { + Type: Boolean, + value: 'true', + maybeConvert: checkBoolean(true), + convert: checkBoolean(true) + }, + { + Type: Boolean, + value: 'false', + maybeConvert: checkBoolean(false), + convert: checkBoolean(false), + maybe: checkBoolean(false), + check: checkBoolean(false) + }, + { + Type: Number, + value: 23 + }, + { + Type: String, + value: 'foo' + }, + { + Type: Date, + value: dateAsNumber, + convert: checkDateMatchesNumber, + maybeConvert: checkDateMatchesNumber + }, + { + Type: Number, + value: '33' + }, + { + Type: Number, + value: 'foo', + convert: checkIsNaN, + maybeConvert: checkIsNaN + }, + { + Type: Integer, + value: 44 + }, + { + Type: Integer, + value: 44.4, + convert: checkNumber(44), + maybeConvert: checkNumber(44) + }, + { + Type: type.check(Number), + value: '44', + convert: checkNumber(44), + maybeConvert: checkNumber(44), + check: { + check: shouldHaveThrownBecauseOfWrongType, + throws: throwsBecauseOfWrongType + } + }, + { + Type: type.maybe(Number), + value: '44', + convert: checkNumber(44), + check: throwsBecauseOfWrongType, + maybe: throwsBecauseOfWrongType + }, + { + Type: type.maybe(Number), + value: null, + convert: checkValue(null), + check: checkValue(null) + }, + { + Type: type.convert(Number), + value: '33', + check: throwsBecauseOfWrongType, + maybe: throwsBecauseOfWrongType, + convert: checkNumber(33), + maybeConvert: checkNumber(33) + }, + { + Type: type.convert(Number), + value: null, + check: throwsBecauseOfWrongType, + maybe: throwsBecauseOfWrongType, + convert: checkNumber(0), + maybeConvert: checkValue(null) + }, + { + Type: type.check(Integer), + value: 44.4, + convert: checkNumber(44), + maybeConvert: checkNumber(44), + check: throwsBecauseOfWrongType, + maybe: throwsBecauseOfWrongType + }, + { + Type: type.Integer, + value: 33.3, + check: throwsBecauseOfWrongType, + convert: checkNumber(33), + maybeConvert: checkNumber(33), + maybe: throwsBecauseOfWrongType + } + ]; + testCases.forEach(function (testCase) { + var Type = testCase.Type; + var value = testCase.value; + canReflect.each(matrix, function (definition, methodName) { + var typeName = canReflect.getName(Type); + var valueName = typeof value === 'string' ? '"' + value + '"' : value; + var testName = typeName + ' - ' + methodName + ' - ' + valueName; + QUnit.test(testName, function (assert) { + var TypeDefinition = type[methodName](Type); + try { + var result = canReflect.convert(value, TypeDefinition); + if (testCase[methodName] && testCase[methodName].check) { + testCase[methodName].check(assert, result, value); + } else { + definition.check(assert, result, value); + } + } catch (err) { + if (definition.throws) { + definition.throws(assert); + } else { + throw err; + } + } + }); + }); + }); + QUnit.test('type.Any works as an identity', function (assert) { + var result = canReflect.convert(45, type.Any); + assert.equal(result, 45, 'Acts as a identity'); + }); + QUnit.test('type.late(fn) takes a function to define the type later', function (assert) { + var theType = type.late(function () { + return type.convert(Number); + }); + var result = canReflect.convert('45', theType); + assert.equal(result, 45, 'Defined late but then converted'); + }); + dev.devOnlyTest('type.late(fn) where the underlying type value is a builtin becomes a strict type', function (assert) { + var typeType = type.late(function () { + return Number; + }); + var result = canReflect.convert(45, typeType); + assert.equal(result, 45, 'works with numbers'); + try { + canReflect.convert('45', typeType); + assert.ok(false, 'Should not have thrown'); + } catch (err) { + assert.ok(err, 'Got an error because it is strict'); + } + }); + QUnit.test('type.isTypeObject determines if an object is a TypeObject', function (assert) { + assert.equal(type.isTypeObject({}), false, 'Plain objects are not'); + var myTypeObject = {}; + myTypeObject[canSymbol.for('can.new')] = function () { + }; + myTypeObject[canSymbol.for('can.isMember')] = function () { + }; + assert.equal(type.isTypeObject(myTypeObject), true, 'With the symbols it is'); + var myTypeFunction = function () { + }; + myTypeFunction[canSymbol.for('can.new')] = function () { + }; + myTypeFunction[canSymbol.for('can.isMember')] = function () { + }; + assert.equal(type.isTypeObject(myTypeFunction), true, 'functions with the symbols are too'); + assert.equal(type.isTypeObject(null), false, 'primitives are not'); + assert.equal(type.isTypeObject(undefined), false, 'undefined is not'); + assert.equal(type.isTypeObject(23), false, 'number primitives too'); + assert.equal(type.isTypeObject(String), false, 'builtin constructors are not'); + }); + QUnit.test('type.normalize takes a Type and returns a TypeObject', function (assert) { + [ + String, + type.check(String), + Date + ].forEach(function (Type) { + var typeObject = type.normalize(Type); + var name = canReflect.getName(Type); + assert.equal(type.isTypeObject(typeObject), true, 'Creates a typeobject for ' + name); + }); + [ + 12, + null, + 'foobar' + ].forEach(function (primitive) { + try { + type.normalize(primitive); + } catch (err) { + assert.ok(err, 'Unable to normalize primitives'); + } + }); + }); + QUnit.test('Should not be able to call new on a TypeObject', function (assert) { + var typeObject = type.convert(Number); + try { + new typeObject(); + assert.ok(false, 'Should not be able to call new'); + } catch (err) { + assert.ok(err, 'Got an error calling new'); + } + }); + QUnit.test('Type equality', function (assert) { + assert.strictEqual(type.convert(type.check(String)), type.convert(type.check(String))); + assert.strictEqual(type.maybe(String), type.maybe(String)); + }); + dev.devOnlyTest('TypeObjects do not need to throw themselves', function (assert) { + assert.expect(2); + function isABC(str) { + return 'ABC'.indexOf(str.toString()) !== -1; + } + var OnlyABC = {}; + OnlyABC[newSymbol] = function () { + return 'A'; + }; + OnlyABC[isMemberSymbol] = isABC; + var StrictABC = type.check(OnlyABC); + try { + canReflect.convert('D', StrictABC); + } catch (e) { + assert.ok(true, 'Throw because isMember failed'); + } + var NotStrictABC = type.convert(StrictABC); + var val = canReflect.convert('D', NotStrictABC); + assert.equal(val, 'A', 'converted'); + }); + QUnit.test('Maybe types should always return a schema with an or', function (assert) { + var schema = canReflect.getSchema(type.maybe(String)); + assert.deepEqual(schema.values, [ + String, + null, + undefined + ]); + schema = canReflect.getSchema(type.convert(type.maybe(String))); + assert.deepEqual(schema.values, [ + String, + null, + undefined + ]); + schema = canReflect.getSchema(type.maybe(Boolean)); + assert.deepEqual(schema.values, [ + true, + false, + null, + undefined + ]); + schema = canReflect.getSchema(type.check(Boolean)); + assert.deepEqual(schema.values, [ + true, + false + ]); + schema = canReflect.getSchema(type.convert(type.maybe(Boolean))); + assert.deepEqual(schema.values, [ + true, + false, + null, + undefined + ]); + schema = canReflect.getSchema(type.maybeConvert(Boolean)); + assert.deepEqual(schema.values, [ + true, + false, + null, + undefined + ]); + schema = canReflect.getSchema(type.maybe(type.convert(Boolean))); + assert.deepEqual(schema.values, [ + true, + false, + null, + undefined + ]); + }); + QUnit.test('type.all converts objects', function (assert) { + var Person = function (values) { + canReflect.assignMap(this, values); + }; + Person[newSymbol] = function (values) { + return new Person(values); + }; + Person[getSchemaSymbol] = function () { + return { + type: 'map', + identity: [], + keys: { + first: type.check(String), + last: type.check(String), + age: type.check(Number) + } + }; + }; + var ConvertingPerson = type.all(type.convert, Person); + var person = canReflect.new(ConvertingPerson, { + first: 'Wilbur', + last: 'Phillips', + age: '8' + }); + assert.equal(typeof person.age, 'number', 'it is a number'); + assert.equal(person.first, 'Wilbur'); + assert.equal(person.last, 'Phillips'); + assert.equal(person.age, 8); + }); + QUnit.test('type.convertAll is a convenience for type.all(type.convert, Type)', function (assert) { + var Person = function () { + }; + Person[newSymbol] = function (values) { + return canReflect.assignMap(new Person(), values); + }; + Person[isMemberSymbol] = function (value) { + return value instanceof Person; + }; + Person[getSchemaSymbol] = function () { + return { + type: 'map', + identity: [], + keys: { + first: type.check(String), + last: type.check(String), + age: type.check(Number) + } + }; + }; + var ConvertingPerson = type.convertAll(Person); + var person = canReflect.new(ConvertingPerson, { + first: 'Wilbur', + last: 'Phillips', + age: '8' + }); + assert.equal(typeof person.age, 'number', 'it is a number'); + assert.equal(person.first, 'Wilbur'); + assert.equal(person.last, 'Phillips'); + assert.equal(person.age, 8); + }); + QUnit.test('Subtypes convert correctly', function (assert) { + var Animal = function () { + }; + var Frog = function () { + Animal.call(this, arguments); + }; + Object.setPrototypeOf(Frog.prototype, Animal.prototype); + Object.setPrototypeOf(Frog, Animal); + type.convert(Animal); + var ConvertingFrog = type.convert(Frog); + var frog = canReflect.convert({}, ConvertingFrog); + assert.ok(frog instanceof Frog, 'a frog is a frog'); + }); + QUnit.test('Integer works with can-query-logic', function (assert) { + var schema = { + type: 'map', + identity: [], + keys: { int: type.Integer } + }; + var ql = new QueryLogic(schema); + var ism = ql.isMember({ filter: { int: { $gte: 5 } } }, { int: 5 }); + assert.equal(ism, true, 'numbers are integers'); + }); + QUnit.test('Integer able to convert non-numbers', function (assert) { + var res = canReflect.convert({}, type.Integer); + assert.equal(res, 0, 'converts to 0'); + res = canReflect.convert(33.3, type.Integer); + assert.equal(res, 33, 'converts numbers right still'); + res = canReflect.convert('33', type.Integer); + assert.equal(res, 33, 'converts strings'); + res = canReflect.convert(NaN, type.Integer); + assert.equal(res, 0, 'defaults to 0'); + }); +}); +/*can-type@1.1.5#test/type-errors-test*/ +define('can-type@1.1.5#test/type-errors-test', [ + 'require', + 'exports', + 'module', + 'can-reflect', + '../can-type', + 'steal-qunit', + 'can-test-helpers' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var type = require('../can-type'); + var QUnit = require('steal-qunit'); + var dev = require('can-test-helpers').dev; + QUnit.module('can-type - Type errors'); + var testCases = [ + { + expectedTypeName: 'Number', + value: '3', + ExpectedType: Number + }, + { + expectedTypeName: 'String', + value: 3, + ExpectedType: String + }, + { + expectedTypeName: 'Number', + value: false, + ExpectedType: Number + }, + { + expectedTypeName: 'Boolean', + value: '', + ExpectedType: Boolean + } + ]; + testCases.forEach(function (testCase) { + var typeName = typeof testCase.value; + var typeName = typeName.charAt(0).toUpperCase() + typeName.slice(1); + var expectedTypeName = testCase.expectedTypeName; + dev.devOnlyTest('Include the type ' + typeName + ' of the value', function (assert) { + var strictType = type.check(testCase.ExpectedType); + try { + canReflect.convert(testCase.value, strictType); + } catch (error) { + assert.equal(error.message, testCase.value + ' (' + typeName + ') is not of type ' + expectedTypeName + '.'); + } + }); + }); + dev.devOnlyTest('Throws Error with ".type" value to "can-type-error"', function (assert) { + var numberStrictType = type.check(Number); + try { + canReflect.convert('foo', numberStrictType); + } catch (error) { + assert.equal(error.type, 'can-type-error'); + } + }); +}); +/*can-type@1.1.5#can-type-test*/ +define('can-type@1.1.5#can-type-test', [ + 'require', + 'exports', + 'module', + './test/type-methods-test', + './test/type-errors-test' +], function (require, exports, module) { + require('./test/type-methods-test'); + require('./test/type-errors-test'); +}); +/*can-simple-dom@1.7.1#lib/document/compare-document-position*/ +define('can-simple-dom@1.7.1#lib/document/compare-document-position', [ + 'require', + 'exports', + 'module', + 'can-child-nodes' +], function (require, exports, module) { + var getChildNodes = require('can-child-nodes'); + module.exports = function (Node) { + Node.DOCUMENT_POSITION_DISCONNECTED = 1; + Node.DOCUMENT_POSITION_PRECEDING = 2; + Node.DOCUMENT_POSITION_FOLLOWING = 4; + Node.DOCUMENT_POSITION_CONTAINS = 8; + Node.DOCUMENT_POSITION_CONTAINED_BY = 16; + Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32; + Node.prototype.compareDocumentPosition = function (other) { + function getFirstNodeByOrder(nodes, nodeOne, nodeTwo) { + return nodes.reduce(function (result, node) { + if (result !== false) { + return result; + } else if (node === nodeOne) { + return nodeOne; + } else if (node === nodeTwo) { + return nodeTwo; + } else if (node.childNodes) { + return getFirstNodeByOrder(getChildNodes(node), nodeOne, nodeTwo); + } else { + return false; + } + }, false); + } + function isAncestor(source, target) { + while (target.parentNode) { + target = target.parentNode; + if (target === source) { + return true; + } + } + return false; + } + function eitherContains(left, right) { + return isAncestor(left, right) ? Node.DOCUMENT_POSITION_CONTAINED_BY + Node.DOCUMENT_POSITION_FOLLOWING : isAncestor(right, left) ? Node.DOCUMENT_POSITION_CONTAINS + Node.DOCUMENT_POSITION_PRECEDING : false; + } + function getRootNode(node) { + while (node.parentNode) { + node = node.parentNode; + } + return node; + } + if (this === other) { + return 0; + } + var referenceRoot = getRootNode(this); + var otherRoot = getRootNode(other); + if (referenceRoot !== otherRoot) { + return Node.DOCUMENT_POSITION_DISCONNECTED; + } + var result = eitherContains(this, other); + if (result) { + return result; + } + var first = getFirstNodeByOrder([referenceRoot], this, other); + return first === this ? Node.DOCUMENT_POSITION_FOLLOWING : first === other ? Node.DOCUMENT_POSITION_PRECEDING : Node.DOCUMENT_POSITION_DISCONNECTED; + }; + }; +}); +/*can-simple-dom@1.7.1#lib/document/node*/ +define('can-simple-dom@1.7.1#lib/document/node', [ + 'require', + 'exports', + 'module', + './compare-document-position' +], function (require, exports, module) { + var makeCompareDocumentPosition = require('./compare-document-position'); + function Node(nodeType, nodeName, nodeValue, ownerDocument) { + this.nodeType = nodeType; + this.nodeName = nodeName; + this.nodeValue = nodeValue; + this.ownerDocument = ownerDocument; + this.childNodes = new ChildNodes(this); + this.parentNode = null; + this.previousSibling = null; + this.nextSibling = null; + this.firstChild = null; + this.lastChild = null; + } + Node.prototype._cloneNode = function () { + return new Node(this.nodeType, this.nodeName, this.nodeValue, this.ownerDocument); + }; + Node.prototype.cloneNode = function (deep) { + var node = this._cloneNode(); + if (deep) { + var child = this.firstChild, nextChild = child; + while (nextChild) { + nextChild = child.nextSibling; + nodeAppendChild.call(node, child.cloneNode(true)); + child = nextChild; + } + } + return node; + }; + var nodeAppendChild = Node.prototype.appendChild = function (node) { + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + insertFragment(node, this, this.lastChild, null); + return node; + } + if (node.parentNode) { + nodeRemoveChild.call(node.parentNode, node); + } + node.parentNode = this; + var refNode = this.lastChild; + if (refNode === null) { + this.firstChild = node; + this.lastChild = node; + } else { + node.previousSibling = refNode; + refNode.nextSibling = node; + this.lastChild = node; + } + ensureOwnerDocument(this, node); + return node; + }; + function insertFragment(fragment, newParent, before, after) { + if (!fragment.firstChild) { + return; + } + var firstChild = fragment.firstChild; + var lastChild = firstChild; + var node = firstChild; + firstChild.previousSibling = before; + if (before) { + before.nextSibling = firstChild; + } else { + newParent.firstChild = firstChild; + } + while (node) { + node.parentNode = newParent; + ensureOwnerDocument(newParent, node); + lastChild = node; + node = node.nextSibling; + } + lastChild.nextSibling = after; + if (after) { + after.previousSibling = lastChild; + } else { + newParent.lastChild = lastChild; + } + fragment.firstChild = null; + fragment.lastChild = null; + } + function ensureOwnerDocument(parent, child) { + var ownerDocument = parent.nodeType === 9 ? parent : parent.ownerDocument; + if (parent.ownerDocument !== child.ownerDocument) { + var node = child; + while (node) { + node.ownerDocument = ownerDocument; + if (node.firstChild) { + ensureOwnerDocument(node, node.firstChild); + } + node = node.nextSibling; + } + } + } + var nodeInsertBefore = Node.prototype.insertBefore = function (node, refNode) { + if (refNode == null) { + return nodeAppendChild.call(this, node); + } + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + insertFragment(node, this, refNode ? refNode.previousSibling : null, refNode); + return node; + } + if (node.parentNode) { + nodeRemoveChild.call(node.parentNode, node); + } + node.parentNode = this; + var previousSibling = refNode.previousSibling; + if (previousSibling) { + previousSibling.nextSibling = node; + node.previousSibling = previousSibling; + } + refNode.previousSibling = node; + node.nextSibling = refNode; + if (this.firstChild === refNode) { + this.firstChild = node; + } + ensureOwnerDocument(this, node); + return node; + }; + var nodeRemoveChild = Node.prototype.removeChild = function (refNode) { + if (this.firstChild === refNode) { + this.firstChild = refNode.nextSibling; + } + if (this.lastChild === refNode) { + this.lastChild = refNode.previousSibling; + } + if (refNode.previousSibling) { + refNode.previousSibling.nextSibling = refNode.nextSibling; + } + if (refNode.nextSibling) { + refNode.nextSibling.previousSibling = refNode.previousSibling; + } + refNode.parentNode = null; + refNode.nextSibling = null; + refNode.previousSibling = null; + return refNode; + }; + Node.prototype.replaceChild = function (newChild, oldChild) { + nodeInsertBefore.call(this, newChild, oldChild); + nodeRemoveChild.call(this, oldChild); + return oldChild; + }; + Node.prototype.contains = function (child) { + while (child) { + if (child === this) { + return true; + } + child = child.parentNode; + } + return false; + }; + Node.prototype.addEventListener = function () { + }; + Node.prototype.removeEventListener = function () { + }; + makeCompareDocumentPosition(Node); + Node.ELEMENT_NODE = 1; + Node.ATTRIBUTE_NODE = 2; + Node.TEXT_NODE = 3; + Node.CDATA_SECTION_NODE = 4; + Node.ENTITY_REFERENCE_NODE = 5; + Node.ENTITY_NODE = 6; + Node.PROCESSING_INSTRUCTION_NODE = 7; + Node.COMMENT_NODE = 8; + Node.DOCUMENT_NODE = 9; + Node.DOCUMENT_TYPE_NODE = 10; + Node.DOCUMENT_FRAGMENT_NODE = 11; + Node.NOTATION_NODE = 12; + function ChildNodes(node) { + this.node = node; + } + ChildNodes.prototype.item = function (index) { + var child = this.node.firstChild; + for (var i = 0; child && index !== i; i++) { + child = child.nextSibling; + } + return child; + }; + exports.Node = Node; + exports.nodeRemoveChild = nodeRemoveChild; +}); +/*can-simple-dom@1.7.1#lib/document/style*/ +define('can-simple-dom@1.7.1#lib/document/style', function (require, exports, module) { + function CSSStyleDeclaration(node) { + this.__node = node; + } + CSSStyleDeclaration.prototype.getPropertyValue = function () { + }; + Object.defineProperty(CSSStyleDeclaration.prototype, 'cssText', { + enumerable: true, + configurable: true, + get: function () { + return this.__node.getAttribute('style') || ''; + }, + set: function (val) { + this.__node._setAttribute('style', val); + } + }); + module.exports = CSSStyleDeclaration; +}); +/*can-simple-dom@1.7.1#lib/document/element*/ +define('can-simple-dom@1.7.1#lib/document/element', [ + 'require', + 'exports', + 'module', + './node', + './style' +], function (require, exports, module) { + var _node = require('./node'); + var nodeRemoveChild = _node.nodeRemoveChild; + var Node = _node.Node; + var CSSStyleDeclaration = require('./style'); + let attrSpecial = { + 'class': function (element, value) { + element._className = value; + } + }; + function Element(tagName, ownerDocument) { + tagName = tagName.toUpperCase(); + this.nodeConstructor(1, tagName, null, ownerDocument); + this.style = new CSSStyleDeclaration(this); + this.attributes = []; + this.tagName = tagName; + } + Element.prototype = Object.create(Node.prototype); + Element.prototype.constructor = Element; + Element.prototype.nodeConstructor = Node; + Element.prototype._cloneNode = function () { + var node = this.ownerDocument.createElement(this.tagName); + node.attributes = this.attributes.map(function (attr) { + return { + name: attr.name, + value: attr.value, + specified: attr.specified + }; + }); + return node; + }; + Element.prototype.getAttribute = function (_name) { + var attributes = this.attributes; + var name = _name.toLowerCase(); + var attr; + for (var i = 0, l = attributes.length; i < l; i++) { + attr = attributes[i]; + if (attr.name === name) { + return attr.value; + } + } + return null; + }; + Element.prototype.setAttribute = function () { + return this._setAttribute.apply(this, arguments); + }; + Element.prototype._setAttribute = function (_name, value) { + value += ''; + var attributes = this.attributes; + var name = _name.toLowerCase(); + var attr; + for (var i = 0, l = attributes.length; i < l; i++) { + attr = attributes[i]; + if (attr.name === name) { + attr.value = value; + const special = attrSpecial[name]; + if (special) { + special(this, value); + } + return; + } + } + attributes.push({ + name: name, + value: value, + specified: true + }); + attributes[name] = value; + const special = attrSpecial[name]; + if (special) { + special(this, value); + } + }; + Element.prototype.setAttributeNS = function (namespaceURI, name, value) { + this._setAttribute(name, value); + var i = this.attributes.length; + do { + i--; + var attrNode = this.attributes[i]; + if (attrNode.name === name) { + attrNode.namespaceURI = namespaceURI; + break; + } + } while (i > 0); + }; + Element.prototype.hasAttribute = function (_name) { + var attributes = this.attributes; + var name = _name.toLowerCase(); + var attr; + for (var i = 0, len = attributes.length; i < len; i++) { + attr = attributes[i]; + if (attr.name === name) { + return true; + } + } + return false; + }; + Element.prototype.removeAttribute = function (name) { + var attributes = this.attributes; + for (var i = 0, l = attributes.length; i < l; i++) { + var attr = attributes[i]; + if (attr.name === name) { + attributes.splice(i, 1); + const special = attrSpecial[name]; + if (special) { + special(this, undefined); + } + delete attributes[name]; + return; + } + } + }; + Element.prototype.getElementsByTagName = function (name) { + name = name.toUpperCase(); + var elements = []; + var cur = this.firstChild; + while (cur) { + if (cur.nodeType === Node.ELEMENT_NODE) { + if (cur.nodeName === name || name === '*') { + elements.push(cur); + } + elements.push.apply(elements, cur.getElementsByTagName(name)); + } + cur = cur.nextSibling; + } + return elements; + }; + Element.prototype.getElementById = function (id) { + var cur = this.firstChild, child; + while (cur) { + if (cur.attributes && cur.attributes.length) { + var attr; + for (var i = 0, len = cur.attributes.length; i < len; i++) { + attr = cur.attributes[i]; + if (attr.name === 'id' && attr.value === id) { + return cur; + } + } + } + if (cur.getElementById) { + child = cur.getElementById(id); + if (child) { + return child; + } + } + cur = cur.nextSibling; + } + }; + function Style(node) { + this.__node = node; + } + if (Object.defineProperty) { + Object.defineProperty(Element.prototype, 'className', { + configurable: true, + enumerable: true, + get: function () { + return this._className || ''; + }, + set: function (val) { + this._setAttribute('class', val); + this._className = val; + } + }); + Object.defineProperty(Element.prototype, 'innerHTML', { + configurable: true, + enumerable: true, + get: function () { + var html = ''; + var cur = this.firstChild; + while (cur) { + html += this.ownerDocument.__serializer.serialize(cur); + cur = cur.nextSibling; + } + return html; + }, + set: function (html) { + this.lastChild = this.firstChild = null; + var fragment; + if (this.nodeName === 'SCRIPT' || this.nodeName === 'STYLE') { + fragment = this.ownerDocument.createTextNode(html); + } else { + fragment = this.ownerDocument.__parser.parse(html); + } + this.appendChild(fragment); + } + }); + Object.defineProperty(Element.prototype, 'outerHTML', { + get: function () { + return this.ownerDocument.__serializer.serialize(this); + }, + set: function (html) { + this.parentNode.replaceChild(this.ownerDocument.__parser.parse(html), this); + } + }); + Object.defineProperty(Element.prototype, 'textContent', { + get: function () { + var fc = this.firstChild; + return fc && fc.nodeValue || ''; + }, + set: function (val) { + while (this.firstChild) { + nodeRemoveChild.call(this, this.firstChild); + } + var tn = this.ownerDocument.createTextNode(val); + this.appendChild(tn); + } + }); + } + module.exports = Element; +}); +/*can-simple-dom@1.7.1#lib/document/text*/ +define('can-simple-dom@1.7.1#lib/document/text', [ + 'require', + 'exports', + 'module', + './node' +], function (require, exports, module) { + var Node = require('./node').Node; + function Text(text, ownerDocument) { + this.nodeConstructor(3, '#text', text, ownerDocument); + } + Text.prototype._cloneNode = function () { + return this.ownerDocument.createTextNode(this.nodeValue); + }; + Text.prototype = Object.create(Node.prototype); + Text.prototype.constructor = Text; + Text.prototype.nodeConstructor = Node; + module.exports = Text; +}); +/*can-simple-dom@1.7.1#lib/document/comment*/ +define('can-simple-dom@1.7.1#lib/document/comment', [ + 'require', + 'exports', + 'module', + './node' +], function (require, exports, module) { + var Node = require('./node').Node; + function Comment(text, ownerDocument) { + this.nodeConstructor(8, '#comment', text, ownerDocument); + } + Comment.prototype._cloneNode = function () { + return this.ownerDocument.createComment(this.nodeValue); + }; + Comment.prototype = Object.create(Node.prototype); + Comment.prototype.constructor = Comment; + Comment.prototype.nodeConstructor = Node; + module.exports = Comment; +}); +/*can-simple-dom@1.7.1#lib/document/document-fragment*/ +define('can-simple-dom@1.7.1#lib/document/document-fragment', [ + 'require', + 'exports', + 'module', + './node' +], function (require, exports, module) { + var Node = require('./node').Node; + function DocumentFragment(ownerDocument) { + this.nodeConstructor(11, '#document-fragment', null, ownerDocument); + } + DocumentFragment.prototype._cloneNode = function () { + return this.ownerDocument.createDocumentFragment(); + }; + DocumentFragment.prototype = Object.create(Node.prototype); + DocumentFragment.prototype.constructor = DocumentFragment; + DocumentFragment.prototype.nodeConstructor = Node; + module.exports = DocumentFragment; +}); +/*micro-location@0.1.5#lib/micro-location*/ +function Location() { + this.init.apply(this, arguments); +} +Location.prototype = { + init: function (protocol, host, hostname, port, pathname, search, hash) { + this.protocol = protocol; + this.host = host; + this.hostname = hostname; + this.port = port || ''; + this.pathname = pathname || ''; + this.search = search || ''; + this.hash = hash || ''; + if (protocol) { + with (this) + this.href = protocol + '//' + host + pathname + search + hash; + } else if (host) { + with (this) + this.href = '//' + host + pathname + search + hash; + } else { + with (this) + this.href = pathname + search + hash; + } + }, + params: function (name) { + if (!this._params) { + var params = {}; + var pairs = this.search.substring(1).split(/[;&]/); + for (var i = 0, len = pairs.length; i < len; i++) { + if (!pairs[i]) + continue; + var pair = pairs[i].split(/=/); + var key = decodeURIComponent(pair[0].replace(/\+/g, '%20')); + var val = decodeURIComponent(pair[1].replace(/\+/g, '%20')); + if (!params[key]) + params[key] = []; + params[key].push(val); + } + this._params = params; + } + switch (typeof name) { + case 'undefined': + return this._params; + case 'object': + return this.build(name); + } + return this._params[name] ? this._params[name][0] : null; + }, + build: function (params) { + if (!params) + params = this._params; + var ret = new Location(); + var _search = this.search; + if (params) { + var search = []; + for (var key in params) + if (params.hasOwnProperty(key)) { + var val = params[key]; + switch (typeof val) { + case 'object': + for (var i = 0, len = val.length; i < len; i++) { + search.push(encodeURIComponent(key) + '=' + encodeURIComponent(val[i])); + } + break; + default: + search.push(encodeURIComponent(key) + '=' + encodeURIComponent(val)); + } + } + _search = '?' + search.join('&'); + } + with (this) + ret.init.apply(ret, [ + protocol, + host, + hostname, + port, + pathname, + _search, + hash + ]); + return ret; + } +}; +Location.regexp = new RegExp('^(?:(https?:)//(([^:/]+)(:[^/]+)?))?([^#?]*)(\\?[^#]*)?(#.*)?$'); +Location.parse = function (string) { + var matched = String(string).match(this.regexp); + var ret = new Location(); + ret.init.apply(ret, matched.slice(1)); + return ret; +}; +(function (root, factory) { + if (typeof module === 'object' && module.exports) { + module.exports = { Location: factory() }; + } else if (typeof define === 'function' && define.amd) { + define('micro-location@0.1.5#lib/micro-location', [], function () { + return { Location: factory() }; + }); + } else { + root.Location = factory(); + } +}(this, function () { + return Location; +})); +/*can-simple-dom@1.7.1#lib/extend*/ +define('can-simple-dom@1.7.1#lib/extend', function (require, exports, module) { + module.exports = function (a, b) { + for (var p in b) { + a[p] = b[p]; + } + return a; + }; +}); +/*can-simple-dom@1.7.1#lib/document/anchor-element*/ +define('can-simple-dom@1.7.1#lib/document/anchor-element', [ + 'require', + 'exports', + 'module', + './element', + 'micro-location', + '../extend' +], function (require, exports, module) { + var Element = require('./element'); + var microLocation = require('micro-location'); + var extend = require('../extend'); + const Location = microLocation.Location || microLocation; + function AnchorElement(tagName, ownerDocument) { + this.elementConstructor(tagName, ownerDocument); + Object.defineProperty(this, '_href', { + enumerable: false, + configurable: true, + writable: true, + value: '' + }); + extend(this, Location.parse('')); + } + AnchorElement.prototype = Object.create(Element.prototype); + AnchorElement.prototype.constructor = AnchorElement; + AnchorElement.prototype.elementConstructor = Element; + AnchorElement.prototype.setAttribute = function (_name, value) { + Element.prototype.setAttribute.apply(this, arguments); + if (_name.toLowerCase() === 'href') { + extend(this, Location.parse(value)); + } + }; + Object.defineProperty(AnchorElement.prototype, 'href', { + get: function () { + return this._href; + }, + set: function (val) { + if (val !== this._href) { + this._href = val; + this.setAttribute('href', val); + } + } + }); + module.exports = AnchorElement; +}); +/*can-simple-dom@1.7.1#lib/document/utils*/ +define('can-simple-dom@1.7.1#lib/document/utils', function (require, exports, module) { + exports.propToAttr = function (Element, name) { + Object.defineProperty(Element.prototype, name, { + configurable: true, + enumerable: true, + get: function () { + return this.getAttribute(name); + }, + set: function (val) { + this.setAttribute(name, val); + } + }); + }; +}); +/*can-simple-dom@1.7.1#lib/document/input-element*/ +define('can-simple-dom@1.7.1#lib/document/input-element', [ + 'require', + 'exports', + 'module', + './element', + './utils' +], function (require, exports, module) { + var Element = require('./element'); + var propToAttr = require('./utils').propToAttr; + function InputElement(tagName, ownerDocument) { + this.elementConstructor(tagName, ownerDocument); + } + InputElement.prototype = Object.create(Element.prototype); + InputElement.prototype.constructor = InputElement; + InputElement.prototype.elementConstructor = Element; + propToAttr(InputElement, 'type'); + propToAttr(InputElement, 'value'); + Object.defineProperty(InputElement.prototype, 'checked', { + configurable: true, + enumerable: true, + get: function () { + return this.hasAttribute('checked'); + }, + set: function (value) { + if (value) { + this.setAttribute('checked', ''); + } else { + this.removeAttribute('checked'); + } + } + }); + module.exports = InputElement; +}); +/*can-simple-dom@1.7.1#lib/document/option-element*/ +define('can-simple-dom@1.7.1#lib/document/option-element', [ + 'require', + 'exports', + 'module', + './element', + './utils' +], function (require, exports, module) { + var Element = require('./element'); + var propToAttr = require('./utils').propToAttr; + function OptionElement(tagName, ownerDocument) { + this.elementConstructor(tagName, ownerDocument); + } + OptionElement.prototype = Object.create(Element.prototype); + OptionElement.prototype.constructor = OptionElement; + OptionElement.prototype.elementConstructor = Element; + propToAttr(OptionElement, 'value'); + Object.defineProperty(OptionElement.prototype, 'selected', { + enumerable: true, + configurable: true, + get: function () { + var val = this.value || ''; + var parent = this.parentNode; + return parent && parent.value == val; + }, + set: function (val) { + if (val) { + var parent = this.parentNode; + if (parent) { + parent.value = this.value; + } + } + } + }); + module.exports = OptionElement; +}); +/*can-simple-dom@1.7.1#lib/document/select-element*/ +define('can-simple-dom@1.7.1#lib/document/select-element', [ + 'require', + 'exports', + 'module', + './element', + './utils' +], function (require, exports, module) { + var Element = require('./element'); + var propToAttr = require('./utils').propToAttr; + function SelectElement(tagName, ownerDocument) { + this.elementConstructor(tagName, ownerDocument); + this.selectedIndex = 0; + } + SelectElement.prototype = Object.create(Element.prototype); + SelectElement.prototype.constructor = SelectElement; + SelectElement.prototype.elementConstructor = Element; + propToAttr(SelectElement, 'value'); + module.exports = SelectElement; +}); +/*can-simple-dom@1.7.1#lib/document*/ +define('can-simple-dom@1.7.1#lib/document', [ + 'require', + 'exports', + 'module', + './document/node', + './document/element', + './document/text', + './document/comment', + './document/document-fragment', + './document/anchor-element', + './document/input-element', + './document/option-element', + './document/select-element' +], function (require, exports, module) { + var Node = require('./document/node').Node; + var Element = require('./document/element'); + var Text = require('./document/text'); + var Comment = require('./document/comment'); + var DocumentFragment = require('./document/document-fragment'); + var AnchorElement = require('./document/anchor-element'); + var InputElement = require('./document/input-element'); + var OptionElement = require('./document/option-element'); + var SelectElement = require('./document/select-element'); + var noop = Function.prototype; + function Document() { + this.nodeConstructor(9, '#document', null, this); + var documentElement = new Element('html', this); + var body = new Element('body', this); + var head = new Element('head', this); + documentElement.appendChild(head); + documentElement.appendChild(body); + this.appendChild(documentElement); + var self = this; + this.implementation = { + createHTMLDocument: function (content) { + var document = new Document(); + var frag = self.__parser.parse(content); + var body = Element.prototype.getElementsByTagName.call(frag, 'body')[0]; + var head = Element.prototype.getElementsByTagName.call(frag, 'head')[0]; + if (!body && !head) { + document.body.appendChild(frag); + } else { + if (body) { + document.documentElement.replaceChild(body, document.body); + } + if (head) { + document.documentElement.replaceChild(head, document.head); + } + document.documentElement.appendChild(frag); + } + document.__addSerializerAndParser(self.__serializer, self.__parser); + return document; + } + }; + } + Document.prototype = Object.create(Node.prototype); + Document.prototype.constructor = Document; + Document.prototype.nodeConstructor = Node; + const specialElements = { + 'a': AnchorElement, + 'input': InputElement, + 'option': OptionElement, + 'select': SelectElement + }; + Document.prototype.createElement = function (tagName) { + var Special = specialElements[tagName.toLowerCase()]; + if (Special) { + return new Special(tagName, this); + } + return new Element(tagName, this); + }; + Document.prototype.createTextNode = function (text) { + return new Text(text, this); + }; + Document.prototype.createComment = function (text) { + return new Comment(text, this); + }; + Document.prototype.createDocumentFragment = function () { + return new DocumentFragment(this); + }; + Document.prototype.getElementsByTagName = function (name) { + name = name.toUpperCase(); + var elements = []; + var cur = this.firstChild; + while (cur) { + if (cur.nodeType === Node.ELEMENT_NODE) { + if (cur.nodeName === name || name === '*') { + elements.push(cur); + } + elements.push.apply(elements, cur.getElementsByTagName(name)); + } + cur = cur.nextSibling; + } + return elements; + }; + Document.prototype.getElementById = function (id) { + return Element.prototype.getElementById.apply(this.documentElement, arguments); + }; + Document.prototype.__addSerializerAndParser = function (serializer, parser) { + this.__parser = parser; + this.__serializer = serializer; + }; + if (Object.defineProperty) { + Object.defineProperty(Document.prototype, 'currentScript', { + get: function () { + var scripts = this.getElementsByTagName('script'); + var first = scripts[scripts.length - 1]; + if (!first) { + first = this.createElement('script'); + } + return first; + } + }); + Object.defineProperty(Document.prototype, 'documentElement', { + get: function () { + return this.firstChild; + }, + set: noop + }); + function firstOfKind(root, nodeName) { + if (root == null) + return null; + var node = root.firstChild; + while (node) { + if (node.nodeName === nodeName) { + return node; + } + node = node.nextSibling; + } + return null; + } + [ + 'head', + 'body' + ].forEach(function (localName) { + var nodeName = localName.toUpperCase(); + Object.defineProperty(Document.prototype, localName, { + get: function () { + return firstOfKind(this.documentElement, nodeName); + }, + set: noop + }); + }); + } + module.exports = Document; +}); +/*can-simple-dom@1.7.1#lib/event*/ +define('can-simple-dom@1.7.1#lib/event', [ + 'require', + 'exports', + 'module', + './document/node', + './document' +], function (require, exports, module) { + var Node = require('./document/node').Node; + var Document = require('./document'); + var Event = function () { + }; + Event.prototype.initEvent = function (type, bubbles, cancelable) { + this.type = type; + this.bubbles = !!bubbles; + this.cancelable = !!cancelable; + }; + Event.prototype.stopPropagation = function () { + this.isPropagationStopped = true; + }; + Event.prototype.preventDefault = function () { + this.isDefaultPrevented = true; + }; + Document.prototype.createEvent = function (type) { + return new Event(); + }; + Node.prototype.addEventListener = function (event, handler, capture) { + if (!this.__handlers) { + Object.defineProperty(this, '__handlers', { + value: {}, + enumerable: false + }); + } + var phase = capture ? 'capture' : 'bubble'; + var handlersByType = this.__handlers[event + ' ' + phase]; + if (!handlersByType) { + handlersByType = this.__handlers[event + ' ' + phase] = []; + } + if (handlersByType.indexOf(handler) === -1) { + handlersByType.push(handler); + } + }; + Node.prototype.removeEventListener = function (event, handler, capture) { + if (this.__handlers) { + var phase = capture ? 'capture' : 'bubble'; + var handlersByType = this.__handlers[event + ' ' + phase]; + if (handlersByType) { + var index = 0; + while (index < handlersByType.length) { + if (handlersByType[index] === handler) { + handlersByType.splice(index, 1); + } else { + index++; + } + } + } + } + }; + Node.prototype.dispatchEvent = function (event) { + event.target = this; + var cur = this; + var dispatchHandlers = []; + do { + var handlers = cur.__handlers && cur.__handlers[event.type + ' bubble']; + if (handlers) { + dispatchHandlers.push({ + node: cur, + handlers: handlers + }); + } + cur = cur.parentNode; + } while (event.bubbles && cur); + for (var i = 0; i < dispatchHandlers.length; i++) { + var dispatches = dispatchHandlers[i]; + event.currentTarget = dispatches.node; + for (var h = 0; h < dispatches.handlers.length; h++) { + var handler = dispatches.handlers[h]; + var res = handler.call(this, event); + if (res) { + event.stopPropagation(); + event.preventDefault(); + } + if (event.isImmediatePropagationStopped) { + return !event.isDefaultPrevented; + } + } + if (event.isPropagationStopped) { + return !event.isDefaultPrevented; + } + } + return !event.isDefaultPrevented; + }; + module.exports = Event; +}); +/*he@1.2.0#he*/ +; +(function (root) { + var freeExports = typeof exports == 'object' && exports; + var freeModule = typeof module == 'object' && module && module.exports == freeExports && module; + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; + var regexAsciiWhitelist = /[\x01-\x7F]/g; + var regexBmpWhitelist = /[\x01-\t\x0B\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g; + var regexEncodeNonAscii = /<\u20D2|=\u20E5|>\u20D2|\u205F\u200A|\u219D\u0338|\u2202\u0338|\u2220\u20D2|\u2229\uFE00|\u222A\uFE00|\u223C\u20D2|\u223D\u0331|\u223E\u0333|\u2242\u0338|\u224B\u0338|\u224D\u20D2|\u224E\u0338|\u224F\u0338|\u2250\u0338|\u2261\u20E5|\u2264\u20D2|\u2265\u20D2|\u2266\u0338|\u2267\u0338|\u2268\uFE00|\u2269\uFE00|\u226A\u0338|\u226A\u20D2|\u226B\u0338|\u226B\u20D2|\u227F\u0338|\u2282\u20D2|\u2283\u20D2|\u228A\uFE00|\u228B\uFE00|\u228F\u0338|\u2290\u0338|\u2293\uFE00|\u2294\uFE00|\u22B4\u20D2|\u22B5\u20D2|\u22D8\u0338|\u22D9\u0338|\u22DA\uFE00|\u22DB\uFE00|\u22F5\u0338|\u22F9\u0338|\u2933\u0338|\u29CF\u0338|\u29D0\u0338|\u2A6D\u0338|\u2A70\u0338|\u2A7D\u0338|\u2A7E\u0338|\u2AA1\u0338|\u2AA2\u0338|\u2AAC\uFE00|\u2AAD\uFE00|\u2AAF\u0338|\u2AB0\u0338|\u2AC5\u0338|\u2AC6\u0338|\u2ACB\uFE00|\u2ACC\uFE00|\u2AFD\u20E5|[\xA0-\u0113\u0116-\u0122\u0124-\u012B\u012E-\u014D\u0150-\u017E\u0192\u01B5\u01F5\u0237\u02C6\u02C7\u02D8-\u02DD\u0311\u0391-\u03A1\u03A3-\u03A9\u03B1-\u03C9\u03D1\u03D2\u03D5\u03D6\u03DC\u03DD\u03F0\u03F1\u03F5\u03F6\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E\u045F\u2002-\u2005\u2007-\u2010\u2013-\u2016\u2018-\u201A\u201C-\u201E\u2020-\u2022\u2025\u2026\u2030-\u2035\u2039\u203A\u203E\u2041\u2043\u2044\u204F\u2057\u205F-\u2063\u20AC\u20DB\u20DC\u2102\u2105\u210A-\u2113\u2115-\u211E\u2122\u2124\u2127-\u2129\u212C\u212D\u212F-\u2131\u2133-\u2138\u2145-\u2148\u2153-\u215E\u2190-\u219B\u219D-\u21A7\u21A9-\u21AE\u21B0-\u21B3\u21B5-\u21B7\u21BA-\u21DB\u21DD\u21E4\u21E5\u21F5\u21FD-\u2205\u2207-\u2209\u220B\u220C\u220F-\u2214\u2216-\u2218\u221A\u221D-\u2238\u223A-\u2257\u2259\u225A\u225C\u225F-\u2262\u2264-\u228B\u228D-\u229B\u229D-\u22A5\u22A7-\u22B0\u22B2-\u22BB\u22BD-\u22DB\u22DE-\u22E3\u22E6-\u22F7\u22F9-\u22FE\u2305\u2306\u2308-\u2310\u2312\u2313\u2315\u2316\u231C-\u231F\u2322\u2323\u232D\u232E\u2336\u233D\u233F\u237C\u23B0\u23B1\u23B4-\u23B6\u23DC-\u23DF\u23E2\u23E7\u2423\u24C8\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2550-\u256C\u2580\u2584\u2588\u2591-\u2593\u25A1\u25AA\u25AB\u25AD\u25AE\u25B1\u25B3-\u25B5\u25B8\u25B9\u25BD-\u25BF\u25C2\u25C3\u25CA\u25CB\u25EC\u25EF\u25F8-\u25FC\u2605\u2606\u260E\u2640\u2642\u2660\u2663\u2665\u2666\u266A\u266D-\u266F\u2713\u2717\u2720\u2736\u2758\u2772\u2773\u27C8\u27C9\u27E6-\u27ED\u27F5-\u27FA\u27FC\u27FF\u2902-\u2905\u290C-\u2913\u2916\u2919-\u2920\u2923-\u292A\u2933\u2935-\u2939\u293C\u293D\u2945\u2948-\u294B\u294E-\u2976\u2978\u2979\u297B-\u297F\u2985\u2986\u298B-\u2996\u299A\u299C\u299D\u29A4-\u29B7\u29B9\u29BB\u29BC\u29BE-\u29C5\u29C9\u29CD-\u29D0\u29DC-\u29DE\u29E3-\u29E5\u29EB\u29F4\u29F6\u2A00-\u2A02\u2A04\u2A06\u2A0C\u2A0D\u2A10-\u2A17\u2A22-\u2A27\u2A29\u2A2A\u2A2D-\u2A31\u2A33-\u2A3C\u2A3F\u2A40\u2A42-\u2A4D\u2A50\u2A53-\u2A58\u2A5A-\u2A5D\u2A5F\u2A66\u2A6A\u2A6D-\u2A75\u2A77-\u2A9A\u2A9D-\u2AA2\u2AA4-\u2AB0\u2AB3-\u2AC8\u2ACB\u2ACC\u2ACF-\u2ADB\u2AE4\u2AE6-\u2AE9\u2AEB-\u2AF3\u2AFD\uFB00-\uFB04]|\uD835[\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDD6B]/g; + var encodeMap = { + '\xAD': 'shy', + '‌': 'zwnj', + '‍': 'zwj', + '\u200E': 'lrm', + '\u2063': 'ic', + '\u2062': 'it', + '\u2061': 'af', + '\u200F': 'rlm', + '\u200B': 'ZeroWidthSpace', + '\u2060': 'NoBreak', + '̑': 'DownBreve', + '⃛': 'tdot', + '⃜': 'DotDot', + '\t': 'Tab', + '\n': 'NewLine', + '\u2008': 'puncsp', + '\u205F': 'MediumSpace', + '\u2009': 'thinsp', + '\u200A': 'hairsp', + '\u2004': 'emsp13', + '\u2002': 'ensp', + '\u2005': 'emsp14', + '\u2003': 'emsp', + '\u2007': 'numsp', + '\xA0': 'nbsp', + '\u205F\u200A': 'ThickSpace', + '\u203E': 'oline', + '_': 'lowbar', + '\u2010': 'dash', + '\u2013': 'ndash', + '\u2014': 'mdash', + '\u2015': 'horbar', + ',': 'comma', + ';': 'semi', + '\u204F': 'bsemi', + ':': 'colon', + '\u2A74': 'Colone', + '!': 'excl', + '\xA1': 'iexcl', + '?': 'quest', + '\xBF': 'iquest', + '.': 'period', + '\u2025': 'nldr', + '\u2026': 'mldr', + '\xB7': 'middot', + '\'': 'apos', + '\u2018': 'lsquo', + '\u2019': 'rsquo', + '\u201A': 'sbquo', + '\u2039': 'lsaquo', + '\u203A': 'rsaquo', + '"': 'quot', + '\u201C': 'ldquo', + '\u201D': 'rdquo', + '\u201E': 'bdquo', + '\xAB': 'laquo', + '\xBB': 'raquo', + '(': 'lpar', + ')': 'rpar', + '[': 'lsqb', + ']': 'rsqb', + '{': 'lcub', + '}': 'rcub', + '\u2308': 'lceil', + '\u2309': 'rceil', + '\u230A': 'lfloor', + '\u230B': 'rfloor', + '\u2985': 'lopar', + '\u2986': 'ropar', + '\u298B': 'lbrke', + '\u298C': 'rbrke', + '\u298D': 'lbrkslu', + '\u298E': 'rbrksld', + '\u298F': 'lbrksld', + '\u2990': 'rbrkslu', + '\u2991': 'langd', + '\u2992': 'rangd', + '\u2993': 'lparlt', + '\u2994': 'rpargt', + '\u2995': 'gtlPar', + '\u2996': 'ltrPar', + '\u27E6': 'lobrk', + '\u27E7': 'robrk', + '\u27E8': 'lang', + '\u27E9': 'rang', + '\u27EA': 'Lang', + '\u27EB': 'Rang', + '\u27EC': 'loang', + '\u27ED': 'roang', + '\u2772': 'lbbrk', + '\u2773': 'rbbrk', + '\u2016': 'Vert', + '\xA7': 'sect', + '\xB6': 'para', + '@': 'commat', + '*': 'ast', + '/': 'sol', + 'undefined': null, + '&': 'amp', + '#': 'num', + '%': 'percnt', + '\u2030': 'permil', + '\u2031': 'pertenk', + '\u2020': 'dagger', + '\u2021': 'Dagger', + '\u2022': 'bull', + '\u2043': 'hybull', + '\u2032': 'prime', + '\u2033': 'Prime', + '\u2034': 'tprime', + '\u2057': 'qprime', + '\u2035': 'bprime', + '\u2041': 'caret', + '`': 'grave', + '\xB4': 'acute', + '\u02DC': 'tilde', + '^': 'Hat', + '\xAF': 'macr', + '\u02D8': 'breve', + '\u02D9': 'dot', + '\xA8': 'die', + '\u02DA': 'ring', + '\u02DD': 'dblac', + '\xB8': 'cedil', + '\u02DB': 'ogon', + 'ˆ': 'circ', + 'ˇ': 'caron', + '\xB0': 'deg', + '\xA9': 'copy', + '\xAE': 'reg', + '\u2117': 'copysr', + '\u2118': 'wp', + '\u211E': 'rx', + '\u2127': 'mho', + '\u2129': 'iiota', + '\u2190': 'larr', + '\u219A': 'nlarr', + '\u2192': 'rarr', + '\u219B': 'nrarr', + '\u2191': 'uarr', + '\u2193': 'darr', + '\u2194': 'harr', + '\u21AE': 'nharr', + '\u2195': 'varr', + '\u2196': 'nwarr', + '\u2197': 'nearr', + '\u2198': 'searr', + '\u2199': 'swarr', + '\u219D': 'rarrw', + '\u219D̸': 'nrarrw', + '\u219E': 'Larr', + '\u219F': 'Uarr', + '\u21A0': 'Rarr', + '\u21A1': 'Darr', + '\u21A2': 'larrtl', + '\u21A3': 'rarrtl', + '\u21A4': 'mapstoleft', + '\u21A5': 'mapstoup', + '\u21A6': 'map', + '\u21A7': 'mapstodown', + '\u21A9': 'larrhk', + '\u21AA': 'rarrhk', + '\u21AB': 'larrlp', + '\u21AC': 'rarrlp', + '\u21AD': 'harrw', + '\u21B0': 'lsh', + '\u21B1': 'rsh', + '\u21B2': 'ldsh', + '\u21B3': 'rdsh', + '\u21B5': 'crarr', + '\u21B6': 'cularr', + '\u21B7': 'curarr', + '\u21BA': 'olarr', + '\u21BB': 'orarr', + '\u21BC': 'lharu', + '\u21BD': 'lhard', + '\u21BE': 'uharr', + '\u21BF': 'uharl', + '\u21C0': 'rharu', + '\u21C1': 'rhard', + '\u21C2': 'dharr', + '\u21C3': 'dharl', + '\u21C4': 'rlarr', + '\u21C5': 'udarr', + '\u21C6': 'lrarr', + '\u21C7': 'llarr', + '\u21C8': 'uuarr', + '\u21C9': 'rrarr', + '\u21CA': 'ddarr', + '\u21CB': 'lrhar', + '\u21CC': 'rlhar', + '\u21D0': 'lArr', + '\u21CD': 'nlArr', + '\u21D1': 'uArr', + '\u21D2': 'rArr', + '\u21CF': 'nrArr', + '\u21D3': 'dArr', + '\u21D4': 'iff', + '\u21CE': 'nhArr', + '\u21D5': 'vArr', + '\u21D6': 'nwArr', + '\u21D7': 'neArr', + '\u21D8': 'seArr', + '\u21D9': 'swArr', + '\u21DA': 'lAarr', + '\u21DB': 'rAarr', + '\u21DD': 'zigrarr', + '\u21E4': 'larrb', + '\u21E5': 'rarrb', + '\u21F5': 'duarr', + '\u21FD': 'loarr', + '\u21FE': 'roarr', + '\u21FF': 'hoarr', + '\u2200': 'forall', + '\u2201': 'comp', + '\u2202': 'part', + '\u2202̸': 'npart', + '\u2203': 'exist', + '\u2204': 'nexist', + '\u2205': 'empty', + '\u2207': 'Del', + '\u2208': 'in', + '\u2209': 'notin', + '\u220B': 'ni', + '\u220C': 'notni', + '\u03F6': 'bepsi', + '\u220F': 'prod', + '\u2210': 'coprod', + '\u2211': 'sum', + '+': 'plus', + '\xB1': 'pm', + '\xF7': 'div', + '\xD7': 'times', + '<': 'lt', + '\u226E': 'nlt', + '<⃒': 'nvlt', + '=': 'equals', + '\u2260': 'ne', + '=⃥': 'bne', + '\u2A75': 'Equal', + '>': 'gt', + '\u226F': 'ngt', + '>⃒': 'nvgt', + '\xAC': 'not', + '|': 'vert', + '\xA6': 'brvbar', + '\u2212': 'minus', + '\u2213': 'mp', + '\u2214': 'plusdo', + '\u2044': 'frasl', + '\u2216': 'setmn', + '\u2217': 'lowast', + '\u2218': 'compfn', + '\u221A': 'Sqrt', + '\u221D': 'prop', + '\u221E': 'infin', + '\u221F': 'angrt', + '\u2220': 'ang', + '\u2220⃒': 'nang', + '\u2221': 'angmsd', + '\u2222': 'angsph', + '\u2223': 'mid', + '\u2224': 'nmid', + '\u2225': 'par', + '\u2226': 'npar', + '\u2227': 'and', + '\u2228': 'or', + '\u2229': 'cap', + '\u2229︀': 'caps', + '\u222A': 'cup', + '\u222A︀': 'cups', + '\u222B': 'int', + '\u222C': 'Int', + '\u222D': 'tint', + '\u2A0C': 'qint', + '\u222E': 'oint', + '\u222F': 'Conint', + '\u2230': 'Cconint', + '\u2231': 'cwint', + '\u2232': 'cwconint', + '\u2233': 'awconint', + '\u2234': 'there4', + '\u2235': 'becaus', + '\u2236': 'ratio', + '\u2237': 'Colon', + '\u2238': 'minusd', + '\u223A': 'mDDot', + '\u223B': 'homtht', + '\u223C': 'sim', + '\u2241': 'nsim', + '\u223C⃒': 'nvsim', + '\u223D': 'bsim', + '\u223Ḏ': 'race', + '\u223E': 'ac', + '\u223E̳': 'acE', + '\u223F': 'acd', + '\u2240': 'wr', + '\u2242': 'esim', + '\u2242̸': 'nesim', + '\u2243': 'sime', + '\u2244': 'nsime', + '\u2245': 'cong', + '\u2247': 'ncong', + '\u2246': 'simne', + '\u2248': 'ap', + '\u2249': 'nap', + '\u224A': 'ape', + '\u224B': 'apid', + '\u224B̸': 'napid', + '\u224C': 'bcong', + '\u224D': 'CupCap', + '\u226D': 'NotCupCap', + '\u224D⃒': 'nvap', + '\u224E': 'bump', + '\u224E̸': 'nbump', + '\u224F': 'bumpe', + '\u224F̸': 'nbumpe', + '\u2250': 'doteq', + '\u2250̸': 'nedot', + '\u2251': 'eDot', + '\u2252': 'efDot', + '\u2253': 'erDot', + '\u2254': 'colone', + '\u2255': 'ecolon', + '\u2256': 'ecir', + '\u2257': 'cire', + '\u2259': 'wedgeq', + '\u225A': 'veeeq', + '\u225C': 'trie', + '\u225F': 'equest', + '\u2261': 'equiv', + '\u2262': 'nequiv', + '\u2261⃥': 'bnequiv', + '\u2264': 'le', + '\u2270': 'nle', + '\u2264⃒': 'nvle', + '\u2265': 'ge', + '\u2271': 'nge', + '\u2265⃒': 'nvge', + '\u2266': 'lE', + '\u2266̸': 'nlE', + '\u2267': 'gE', + '\u2267̸': 'ngE', + '\u2268︀': 'lvnE', + '\u2268': 'lnE', + '\u2269': 'gnE', + '\u2269︀': 'gvnE', + '\u226A': 'll', + '\u226A̸': 'nLtv', + '\u226A⃒': 'nLt', + '\u226B': 'gg', + '\u226B̸': 'nGtv', + '\u226B⃒': 'nGt', + '\u226C': 'twixt', + '\u2272': 'lsim', + '\u2274': 'nlsim', + '\u2273': 'gsim', + '\u2275': 'ngsim', + '\u2276': 'lg', + '\u2278': 'ntlg', + '\u2277': 'gl', + '\u2279': 'ntgl', + '\u227A': 'pr', + '\u2280': 'npr', + '\u227B': 'sc', + '\u2281': 'nsc', + '\u227C': 'prcue', + '\u22E0': 'nprcue', + '\u227D': 'sccue', + '\u22E1': 'nsccue', + '\u227E': 'prsim', + '\u227F': 'scsim', + '\u227F̸': 'NotSucceedsTilde', + '\u2282': 'sub', + '\u2284': 'nsub', + '\u2282⃒': 'vnsub', + '\u2283': 'sup', + '\u2285': 'nsup', + '\u2283⃒': 'vnsup', + '\u2286': 'sube', + '\u2288': 'nsube', + '\u2287': 'supe', + '\u2289': 'nsupe', + '\u228A︀': 'vsubne', + '\u228A': 'subne', + '\u228B︀': 'vsupne', + '\u228B': 'supne', + '\u228D': 'cupdot', + '\u228E': 'uplus', + '\u228F': 'sqsub', + '\u228F̸': 'NotSquareSubset', + '\u2290': 'sqsup', + '\u2290̸': 'NotSquareSuperset', + '\u2291': 'sqsube', + '\u22E2': 'nsqsube', + '\u2292': 'sqsupe', + '\u22E3': 'nsqsupe', + '\u2293': 'sqcap', + '\u2293︀': 'sqcaps', + '\u2294': 'sqcup', + '\u2294︀': 'sqcups', + '\u2295': 'oplus', + '\u2296': 'ominus', + '\u2297': 'otimes', + '\u2298': 'osol', + '\u2299': 'odot', + '\u229A': 'ocir', + '\u229B': 'oast', + '\u229D': 'odash', + '\u229E': 'plusb', + '\u229F': 'minusb', + '\u22A0': 'timesb', + '\u22A1': 'sdotb', + '\u22A2': 'vdash', + '\u22AC': 'nvdash', + '\u22A3': 'dashv', + '\u22A4': 'top', + '\u22A5': 'bot', + '\u22A7': 'models', + '\u22A8': 'vDash', + '\u22AD': 'nvDash', + '\u22A9': 'Vdash', + '\u22AE': 'nVdash', + '\u22AA': 'Vvdash', + '\u22AB': 'VDash', + '\u22AF': 'nVDash', + '\u22B0': 'prurel', + '\u22B2': 'vltri', + '\u22EA': 'nltri', + '\u22B3': 'vrtri', + '\u22EB': 'nrtri', + '\u22B4': 'ltrie', + '\u22EC': 'nltrie', + '\u22B4⃒': 'nvltrie', + '\u22B5': 'rtrie', + '\u22ED': 'nrtrie', + '\u22B5⃒': 'nvrtrie', + '\u22B6': 'origof', + '\u22B7': 'imof', + '\u22B8': 'mumap', + '\u22B9': 'hercon', + '\u22BA': 'intcal', + '\u22BB': 'veebar', + '\u22BD': 'barvee', + '\u22BE': 'angrtvb', + '\u22BF': 'lrtri', + '\u22C0': 'Wedge', + '\u22C1': 'Vee', + '\u22C2': 'xcap', + '\u22C3': 'xcup', + '\u22C4': 'diam', + '\u22C5': 'sdot', + '\u22C6': 'Star', + '\u22C7': 'divonx', + '\u22C8': 'bowtie', + '\u22C9': 'ltimes', + '\u22CA': 'rtimes', + '\u22CB': 'lthree', + '\u22CC': 'rthree', + '\u22CD': 'bsime', + '\u22CE': 'cuvee', + '\u22CF': 'cuwed', + '\u22D0': 'Sub', + '\u22D1': 'Sup', + '\u22D2': 'Cap', + '\u22D3': 'Cup', + '\u22D4': 'fork', + '\u22D5': 'epar', + '\u22D6': 'ltdot', + '\u22D7': 'gtdot', + '\u22D8': 'Ll', + '\u22D8̸': 'nLl', + '\u22D9': 'Gg', + '\u22D9̸': 'nGg', + '\u22DA︀': 'lesg', + '\u22DA': 'leg', + '\u22DB': 'gel', + '\u22DB︀': 'gesl', + '\u22DE': 'cuepr', + '\u22DF': 'cuesc', + '\u22E6': 'lnsim', + '\u22E7': 'gnsim', + '\u22E8': 'prnsim', + '\u22E9': 'scnsim', + '\u22EE': 'vellip', + '\u22EF': 'ctdot', + '\u22F0': 'utdot', + '\u22F1': 'dtdot', + '\u22F2': 'disin', + '\u22F3': 'isinsv', + '\u22F4': 'isins', + '\u22F5': 'isindot', + '\u22F5̸': 'notindot', + '\u22F6': 'notinvc', + '\u22F7': 'notinvb', + '\u22F9': 'isinE', + '\u22F9̸': 'notinE', + '\u22FA': 'nisd', + '\u22FB': 'xnis', + '\u22FC': 'nis', + '\u22FD': 'notnivc', + '\u22FE': 'notnivb', + '\u2305': 'barwed', + '\u2306': 'Barwed', + '\u230C': 'drcrop', + '\u230D': 'dlcrop', + '\u230E': 'urcrop', + '\u230F': 'ulcrop', + '\u2310': 'bnot', + '\u2312': 'profline', + '\u2313': 'profsurf', + '\u2315': 'telrec', + '\u2316': 'target', + '\u231C': 'ulcorn', + '\u231D': 'urcorn', + '\u231E': 'dlcorn', + '\u231F': 'drcorn', + '\u2322': 'frown', + '\u2323': 'smile', + '\u232D': 'cylcty', + '\u232E': 'profalar', + '\u2336': 'topbot', + '\u233D': 'ovbar', + '\u233F': 'solbar', + '\u237C': 'angzarr', + '\u23B0': 'lmoust', + '\u23B1': 'rmoust', + '\u23B4': 'tbrk', + '\u23B5': 'bbrk', + '\u23B6': 'bbrktbrk', + '\u23DC': 'OverParenthesis', + '\u23DD': 'UnderParenthesis', + '\u23DE': 'OverBrace', + '\u23DF': 'UnderBrace', + '\u23E2': 'trpezium', + '\u23E7': 'elinters', + '\u2423': 'blank', + '\u2500': 'boxh', + '\u2502': 'boxv', + '\u250C': 'boxdr', + '\u2510': 'boxdl', + '\u2514': 'boxur', + '\u2518': 'boxul', + '\u251C': 'boxvr', + '\u2524': 'boxvl', + '\u252C': 'boxhd', + '\u2534': 'boxhu', + '\u253C': 'boxvh', + '\u2550': 'boxH', + '\u2551': 'boxV', + '\u2552': 'boxdR', + '\u2553': 'boxDr', + '\u2554': 'boxDR', + '\u2555': 'boxdL', + '\u2556': 'boxDl', + '\u2557': 'boxDL', + '\u2558': 'boxuR', + '\u2559': 'boxUr', + '\u255A': 'boxUR', + '\u255B': 'boxuL', + '\u255C': 'boxUl', + '\u255D': 'boxUL', + '\u255E': 'boxvR', + '\u255F': 'boxVr', + '\u2560': 'boxVR', + '\u2561': 'boxvL', + '\u2562': 'boxVl', + '\u2563': 'boxVL', + '\u2564': 'boxHd', + '\u2565': 'boxhD', + '\u2566': 'boxHD', + '\u2567': 'boxHu', + '\u2568': 'boxhU', + '\u2569': 'boxHU', + '\u256A': 'boxvH', + '\u256B': 'boxVh', + '\u256C': 'boxVH', + '\u2580': 'uhblk', + '\u2584': 'lhblk', + '\u2588': 'block', + '\u2591': 'blk14', + '\u2592': 'blk12', + '\u2593': 'blk34', + '\u25A1': 'squ', + '\u25AA': 'squf', + '\u25AB': 'EmptyVerySmallSquare', + '\u25AD': 'rect', + '\u25AE': 'marker', + '\u25B1': 'fltns', + '\u25B3': 'xutri', + '\u25B4': 'utrif', + '\u25B5': 'utri', + '\u25B8': 'rtrif', + '\u25B9': 'rtri', + '\u25BD': 'xdtri', + '\u25BE': 'dtrif', + '\u25BF': 'dtri', + '\u25C2': 'ltrif', + '\u25C3': 'ltri', + '\u25CA': 'loz', + '\u25CB': 'cir', + '\u25EC': 'tridot', + '\u25EF': 'xcirc', + '\u25F8': 'ultri', + '\u25F9': 'urtri', + '\u25FA': 'lltri', + '\u25FB': 'EmptySmallSquare', + '\u25FC': 'FilledSmallSquare', + '\u2605': 'starf', + '\u2606': 'star', + '\u260E': 'phone', + '\u2640': 'female', + '\u2642': 'male', + '\u2660': 'spades', + '\u2663': 'clubs', + '\u2665': 'hearts', + '\u2666': 'diams', + '\u266A': 'sung', + '\u2713': 'check', + '\u2717': 'cross', + '\u2720': 'malt', + '\u2736': 'sext', + '\u2758': 'VerticalSeparator', + '\u27C8': 'bsolhsub', + '\u27C9': 'suphsol', + '\u27F5': 'xlarr', + '\u27F6': 'xrarr', + '\u27F7': 'xharr', + '\u27F8': 'xlArr', + '\u27F9': 'xrArr', + '\u27FA': 'xhArr', + '\u27FC': 'xmap', + '\u27FF': 'dzigrarr', + '\u2902': 'nvlArr', + '\u2903': 'nvrArr', + '\u2904': 'nvHarr', + '\u2905': 'Map', + '\u290C': 'lbarr', + '\u290D': 'rbarr', + '\u290E': 'lBarr', + '\u290F': 'rBarr', + '\u2910': 'RBarr', + '\u2911': 'DDotrahd', + '\u2912': 'UpArrowBar', + '\u2913': 'DownArrowBar', + '\u2916': 'Rarrtl', + '\u2919': 'latail', + '\u291A': 'ratail', + '\u291B': 'lAtail', + '\u291C': 'rAtail', + '\u291D': 'larrfs', + '\u291E': 'rarrfs', + '\u291F': 'larrbfs', + '\u2920': 'rarrbfs', + '\u2923': 'nwarhk', + '\u2924': 'nearhk', + '\u2925': 'searhk', + '\u2926': 'swarhk', + '\u2927': 'nwnear', + '\u2928': 'toea', + '\u2929': 'tosa', + '\u292A': 'swnwar', + '\u2933': 'rarrc', + '\u2933̸': 'nrarrc', + '\u2935': 'cudarrr', + '\u2936': 'ldca', + '\u2937': 'rdca', + '\u2938': 'cudarrl', + '\u2939': 'larrpl', + '\u293C': 'curarrm', + '\u293D': 'cularrp', + '\u2945': 'rarrpl', + '\u2948': 'harrcir', + '\u2949': 'Uarrocir', + '\u294A': 'lurdshar', + '\u294B': 'ldrushar', + '\u294E': 'LeftRightVector', + '\u294F': 'RightUpDownVector', + '\u2950': 'DownLeftRightVector', + '\u2951': 'LeftUpDownVector', + '\u2952': 'LeftVectorBar', + '\u2953': 'RightVectorBar', + '\u2954': 'RightUpVectorBar', + '\u2955': 'RightDownVectorBar', + '\u2956': 'DownLeftVectorBar', + '\u2957': 'DownRightVectorBar', + '\u2958': 'LeftUpVectorBar', + '\u2959': 'LeftDownVectorBar', + '\u295A': 'LeftTeeVector', + '\u295B': 'RightTeeVector', + '\u295C': 'RightUpTeeVector', + '\u295D': 'RightDownTeeVector', + '\u295E': 'DownLeftTeeVector', + '\u295F': 'DownRightTeeVector', + '\u2960': 'LeftUpTeeVector', + '\u2961': 'LeftDownTeeVector', + '\u2962': 'lHar', + '\u2963': 'uHar', + '\u2964': 'rHar', + '\u2965': 'dHar', + '\u2966': 'luruhar', + '\u2967': 'ldrdhar', + '\u2968': 'ruluhar', + '\u2969': 'rdldhar', + '\u296A': 'lharul', + '\u296B': 'llhard', + '\u296C': 'rharul', + '\u296D': 'lrhard', + '\u296E': 'udhar', + '\u296F': 'duhar', + '\u2970': 'RoundImplies', + '\u2971': 'erarr', + '\u2972': 'simrarr', + '\u2973': 'larrsim', + '\u2974': 'rarrsim', + '\u2975': 'rarrap', + '\u2976': 'ltlarr', + '\u2978': 'gtrarr', + '\u2979': 'subrarr', + '\u297B': 'suplarr', + '\u297C': 'lfisht', + '\u297D': 'rfisht', + '\u297E': 'ufisht', + '\u297F': 'dfisht', + '\u299A': 'vzigzag', + '\u299C': 'vangrt', + '\u299D': 'angrtvbd', + '\u29A4': 'ange', + '\u29A5': 'range', + '\u29A6': 'dwangle', + '\u29A7': 'uwangle', + '\u29A8': 'angmsdaa', + '\u29A9': 'angmsdab', + '\u29AA': 'angmsdac', + '\u29AB': 'angmsdad', + '\u29AC': 'angmsdae', + '\u29AD': 'angmsdaf', + '\u29AE': 'angmsdag', + '\u29AF': 'angmsdah', + '\u29B0': 'bemptyv', + '\u29B1': 'demptyv', + '\u29B2': 'cemptyv', + '\u29B3': 'raemptyv', + '\u29B4': 'laemptyv', + '\u29B5': 'ohbar', + '\u29B6': 'omid', + '\u29B7': 'opar', + '\u29B9': 'operp', + '\u29BB': 'olcross', + '\u29BC': 'odsold', + '\u29BE': 'olcir', + '\u29BF': 'ofcir', + '\u29C0': 'olt', + '\u29C1': 'ogt', + '\u29C2': 'cirscir', + '\u29C3': 'cirE', + '\u29C4': 'solb', + '\u29C5': 'bsolb', + '\u29C9': 'boxbox', + '\u29CD': 'trisb', + '\u29CE': 'rtriltri', + '\u29CF': 'LeftTriangleBar', + '\u29CF̸': 'NotLeftTriangleBar', + '\u29D0': 'RightTriangleBar', + '\u29D0̸': 'NotRightTriangleBar', + '\u29DC': 'iinfin', + '\u29DD': 'infintie', + '\u29DE': 'nvinfin', + '\u29E3': 'eparsl', + '\u29E4': 'smeparsl', + '\u29E5': 'eqvparsl', + '\u29EB': 'lozf', + '\u29F4': 'RuleDelayed', + '\u29F6': 'dsol', + '\u2A00': 'xodot', + '\u2A01': 'xoplus', + '\u2A02': 'xotime', + '\u2A04': 'xuplus', + '\u2A06': 'xsqcup', + '\u2A0D': 'fpartint', + '\u2A10': 'cirfnint', + '\u2A11': 'awint', + '\u2A12': 'rppolint', + '\u2A13': 'scpolint', + '\u2A14': 'npolint', + '\u2A15': 'pointint', + '\u2A16': 'quatint', + '\u2A17': 'intlarhk', + '\u2A22': 'pluscir', + '\u2A23': 'plusacir', + '\u2A24': 'simplus', + '\u2A25': 'plusdu', + '\u2A26': 'plussim', + '\u2A27': 'plustwo', + '\u2A29': 'mcomma', + '\u2A2A': 'minusdu', + '\u2A2D': 'loplus', + '\u2A2E': 'roplus', + '\u2A2F': 'Cross', + '\u2A30': 'timesd', + '\u2A31': 'timesbar', + '\u2A33': 'smashp', + '\u2A34': 'lotimes', + '\u2A35': 'rotimes', + '\u2A36': 'otimesas', + '\u2A37': 'Otimes', + '\u2A38': 'odiv', + '\u2A39': 'triplus', + '\u2A3A': 'triminus', + '\u2A3B': 'tritime', + '\u2A3C': 'iprod', + '\u2A3F': 'amalg', + '\u2A40': 'capdot', + '\u2A42': 'ncup', + '\u2A43': 'ncap', + '\u2A44': 'capand', + '\u2A45': 'cupor', + '\u2A46': 'cupcap', + '\u2A47': 'capcup', + '\u2A48': 'cupbrcap', + '\u2A49': 'capbrcup', + '\u2A4A': 'cupcup', + '\u2A4B': 'capcap', + '\u2A4C': 'ccups', + '\u2A4D': 'ccaps', + '\u2A50': 'ccupssm', + '\u2A53': 'And', + '\u2A54': 'Or', + '\u2A55': 'andand', + '\u2A56': 'oror', + '\u2A57': 'orslope', + '\u2A58': 'andslope', + '\u2A5A': 'andv', + '\u2A5B': 'orv', + '\u2A5C': 'andd', + '\u2A5D': 'ord', + '\u2A5F': 'wedbar', + '\u2A66': 'sdote', + '\u2A6A': 'simdot', + '\u2A6D': 'congdot', + '\u2A6D̸': 'ncongdot', + '\u2A6E': 'easter', + '\u2A6F': 'apacir', + '\u2A70': 'apE', + '\u2A70̸': 'napE', + '\u2A71': 'eplus', + '\u2A72': 'pluse', + '\u2A73': 'Esim', + '\u2A77': 'eDDot', + '\u2A78': 'equivDD', + '\u2A79': 'ltcir', + '\u2A7A': 'gtcir', + '\u2A7B': 'ltquest', + '\u2A7C': 'gtquest', + '\u2A7D': 'les', + '\u2A7D̸': 'nles', + '\u2A7E': 'ges', + '\u2A7E̸': 'nges', + '\u2A7F': 'lesdot', + '\u2A80': 'gesdot', + '\u2A81': 'lesdoto', + '\u2A82': 'gesdoto', + '\u2A83': 'lesdotor', + '\u2A84': 'gesdotol', + '\u2A85': 'lap', + '\u2A86': 'gap', + '\u2A87': 'lne', + '\u2A88': 'gne', + '\u2A89': 'lnap', + '\u2A8A': 'gnap', + '\u2A8B': 'lEg', + '\u2A8C': 'gEl', + '\u2A8D': 'lsime', + '\u2A8E': 'gsime', + '\u2A8F': 'lsimg', + '\u2A90': 'gsiml', + '\u2A91': 'lgE', + '\u2A92': 'glE', + '\u2A93': 'lesges', + '\u2A94': 'gesles', + '\u2A95': 'els', + '\u2A96': 'egs', + '\u2A97': 'elsdot', + '\u2A98': 'egsdot', + '\u2A99': 'el', + '\u2A9A': 'eg', + '\u2A9D': 'siml', + '\u2A9E': 'simg', + '\u2A9F': 'simlE', + '\u2AA0': 'simgE', + '\u2AA1': 'LessLess', + '\u2AA1̸': 'NotNestedLessLess', + '\u2AA2': 'GreaterGreater', + '\u2AA2̸': 'NotNestedGreaterGreater', + '\u2AA4': 'glj', + '\u2AA5': 'gla', + '\u2AA6': 'ltcc', + '\u2AA7': 'gtcc', + '\u2AA8': 'lescc', + '\u2AA9': 'gescc', + '\u2AAA': 'smt', + '\u2AAB': 'lat', + '\u2AAC': 'smte', + '\u2AAC︀': 'smtes', + '\u2AAD': 'late', + '\u2AAD︀': 'lates', + '\u2AAE': 'bumpE', + '\u2AAF': 'pre', + '\u2AAF̸': 'npre', + '\u2AB0': 'sce', + '\u2AB0̸': 'nsce', + '\u2AB3': 'prE', + '\u2AB4': 'scE', + '\u2AB5': 'prnE', + '\u2AB6': 'scnE', + '\u2AB7': 'prap', + '\u2AB8': 'scap', + '\u2AB9': 'prnap', + '\u2ABA': 'scnap', + '\u2ABB': 'Pr', + '\u2ABC': 'Sc', + '\u2ABD': 'subdot', + '\u2ABE': 'supdot', + '\u2ABF': 'subplus', + '\u2AC0': 'supplus', + '\u2AC1': 'submult', + '\u2AC2': 'supmult', + '\u2AC3': 'subedot', + '\u2AC4': 'supedot', + '\u2AC5': 'subE', + '\u2AC5̸': 'nsubE', + '\u2AC6': 'supE', + '\u2AC6̸': 'nsupE', + '\u2AC7': 'subsim', + '\u2AC8': 'supsim', + '\u2ACB︀': 'vsubnE', + '\u2ACB': 'subnE', + '\u2ACC︀': 'vsupnE', + '\u2ACC': 'supnE', + '\u2ACF': 'csub', + '\u2AD0': 'csup', + '\u2AD1': 'csube', + '\u2AD2': 'csupe', + '\u2AD3': 'subsup', + '\u2AD4': 'supsub', + '\u2AD5': 'subsub', + '\u2AD6': 'supsup', + '\u2AD7': 'suphsub', + '\u2AD8': 'supdsub', + '\u2AD9': 'forkv', + '\u2ADA': 'topfork', + '\u2ADB': 'mlcp', + '\u2AE4': 'Dashv', + '\u2AE6': 'Vdashl', + '\u2AE7': 'Barv', + '\u2AE8': 'vBar', + '\u2AE9': 'vBarv', + '\u2AEB': 'Vbar', + '\u2AEC': 'Not', + '\u2AED': 'bNot', + '\u2AEE': 'rnmid', + '\u2AEF': 'cirmid', + '\u2AF0': 'midcir', + '\u2AF1': 'topcir', + '\u2AF2': 'nhpar', + '\u2AF3': 'parsim', + '\u2AFD': 'parsl', + '\u2AFD⃥': 'nparsl', + '\u266D': 'flat', + '\u266E': 'natur', + '\u266F': 'sharp', + '\xA4': 'curren', + '\xA2': 'cent', + '$': 'dollar', + '\xA3': 'pound', + '\xA5': 'yen', + '\u20AC': 'euro', + '\xB9': 'sup1', + '\xBD': 'half', + '\u2153': 'frac13', + '\xBC': 'frac14', + '\u2155': 'frac15', + '\u2159': 'frac16', + '\u215B': 'frac18', + '\xB2': 'sup2', + '\u2154': 'frac23', + '\u2156': 'frac25', + '\xB3': 'sup3', + '\xBE': 'frac34', + '\u2157': 'frac35', + '\u215C': 'frac38', + '\u2158': 'frac45', + '\u215A': 'frac56', + '\u215D': 'frac58', + '\u215E': 'frac78', + '\uD835\uDCB6': 'ascr', + '\uD835\uDD52': 'aopf', + '\uD835\uDD1E': 'afr', + '\uD835\uDD38': 'Aopf', + '\uD835\uDD04': 'Afr', + '\uD835\uDC9C': 'Ascr', + 'ª': 'ordf', + 'á': 'aacute', + 'Á': 'Aacute', + 'à': 'agrave', + 'À': 'Agrave', + 'ă': 'abreve', + 'Ă': 'Abreve', + 'â': 'acirc', + 'Â': 'Acirc', + 'å': 'aring', + 'Å': 'angst', + 'ä': 'auml', + 'Ä': 'Auml', + 'ã': 'atilde', + 'Ã': 'Atilde', + 'ą': 'aogon', + 'Ą': 'Aogon', + 'ā': 'amacr', + 'Ā': 'Amacr', + 'æ': 'aelig', + 'Æ': 'AElig', + '\uD835\uDCB7': 'bscr', + '\uD835\uDD53': 'bopf', + '\uD835\uDD1F': 'bfr', + '\uD835\uDD39': 'Bopf', + 'ℬ': 'Bscr', + '\uD835\uDD05': 'Bfr', + '\uD835\uDD20': 'cfr', + '\uD835\uDCB8': 'cscr', + '\uD835\uDD54': 'copf', + 'ℭ': 'Cfr', + '\uD835\uDC9E': 'Cscr', + 'ℂ': 'Copf', + 'ć': 'cacute', + 'Ć': 'Cacute', + 'ĉ': 'ccirc', + 'Ĉ': 'Ccirc', + 'č': 'ccaron', + 'Č': 'Ccaron', + 'ċ': 'cdot', + 'Ċ': 'Cdot', + 'ç': 'ccedil', + 'Ç': 'Ccedil', + '\u2105': 'incare', + '\uD835\uDD21': 'dfr', + 'ⅆ': 'dd', + '\uD835\uDD55': 'dopf', + '\uD835\uDCB9': 'dscr', + '\uD835\uDC9F': 'Dscr', + '\uD835\uDD07': 'Dfr', + 'ⅅ': 'DD', + '\uD835\uDD3B': 'Dopf', + 'ď': 'dcaron', + 'Ď': 'Dcaron', + 'đ': 'dstrok', + 'Đ': 'Dstrok', + 'ð': 'eth', + 'Ð': 'ETH', + 'ⅇ': 'ee', + 'ℯ': 'escr', + '\uD835\uDD22': 'efr', + '\uD835\uDD56': 'eopf', + 'ℰ': 'Escr', + '\uD835\uDD08': 'Efr', + '\uD835\uDD3C': 'Eopf', + 'é': 'eacute', + 'É': 'Eacute', + 'è': 'egrave', + 'È': 'Egrave', + 'ê': 'ecirc', + 'Ê': 'Ecirc', + 'ě': 'ecaron', + 'Ě': 'Ecaron', + 'ë': 'euml', + 'Ë': 'Euml', + 'ė': 'edot', + 'Ė': 'Edot', + 'ę': 'eogon', + 'Ę': 'Eogon', + 'ē': 'emacr', + 'Ē': 'Emacr', + '\uD835\uDD23': 'ffr', + '\uD835\uDD57': 'fopf', + '\uD835\uDCBB': 'fscr', + '\uD835\uDD09': 'Ffr', + '\uD835\uDD3D': 'Fopf', + 'ℱ': 'Fscr', + 'ff': 'fflig', + 'ffi': 'ffilig', + 'ffl': 'ffllig', + 'fi': 'filig', + 'fj': 'fjlig', + 'fl': 'fllig', + 'ƒ': 'fnof', + 'ℊ': 'gscr', + '\uD835\uDD58': 'gopf', + '\uD835\uDD24': 'gfr', + '\uD835\uDCA2': 'Gscr', + '\uD835\uDD3E': 'Gopf', + '\uD835\uDD0A': 'Gfr', + 'ǵ': 'gacute', + 'ğ': 'gbreve', + 'Ğ': 'Gbreve', + 'ĝ': 'gcirc', + 'Ĝ': 'Gcirc', + 'ġ': 'gdot', + 'Ġ': 'Gdot', + 'Ģ': 'Gcedil', + '\uD835\uDD25': 'hfr', + 'ℎ': 'planckh', + '\uD835\uDCBD': 'hscr', + '\uD835\uDD59': 'hopf', + 'ℋ': 'Hscr', + 'ℌ': 'Hfr', + 'ℍ': 'Hopf', + 'ĥ': 'hcirc', + 'Ĥ': 'Hcirc', + 'ℏ': 'hbar', + 'ħ': 'hstrok', + 'Ħ': 'Hstrok', + '\uD835\uDD5A': 'iopf', + '\uD835\uDD26': 'ifr', + '\uD835\uDCBE': 'iscr', + 'ⅈ': 'ii', + '\uD835\uDD40': 'Iopf', + 'ℐ': 'Iscr', + 'ℑ': 'Im', + 'í': 'iacute', + 'Í': 'Iacute', + 'ì': 'igrave', + 'Ì': 'Igrave', + 'î': 'icirc', + 'Î': 'Icirc', + 'ï': 'iuml', + 'Ï': 'Iuml', + 'ĩ': 'itilde', + 'Ĩ': 'Itilde', + 'İ': 'Idot', + 'į': 'iogon', + 'Į': 'Iogon', + 'ī': 'imacr', + 'Ī': 'Imacr', + 'ij': 'ijlig', + 'IJ': 'IJlig', + 'ı': 'imath', + '\uD835\uDCBF': 'jscr', + '\uD835\uDD5B': 'jopf', + '\uD835\uDD27': 'jfr', + '\uD835\uDCA5': 'Jscr', + '\uD835\uDD0D': 'Jfr', + '\uD835\uDD41': 'Jopf', + 'ĵ': 'jcirc', + 'Ĵ': 'Jcirc', + 'ȷ': 'jmath', + '\uD835\uDD5C': 'kopf', + '\uD835\uDCC0': 'kscr', + '\uD835\uDD28': 'kfr', + '\uD835\uDCA6': 'Kscr', + '\uD835\uDD42': 'Kopf', + '\uD835\uDD0E': 'Kfr', + 'ķ': 'kcedil', + 'Ķ': 'Kcedil', + '\uD835\uDD29': 'lfr', + '\uD835\uDCC1': 'lscr', + 'ℓ': 'ell', + '\uD835\uDD5D': 'lopf', + 'ℒ': 'Lscr', + '\uD835\uDD0F': 'Lfr', + '\uD835\uDD43': 'Lopf', + 'ĺ': 'lacute', + 'Ĺ': 'Lacute', + 'ľ': 'lcaron', + 'Ľ': 'Lcaron', + 'ļ': 'lcedil', + 'Ļ': 'Lcedil', + 'ł': 'lstrok', + 'Ł': 'Lstrok', + 'ŀ': 'lmidot', + 'Ŀ': 'Lmidot', + '\uD835\uDD2A': 'mfr', + '\uD835\uDD5E': 'mopf', + '\uD835\uDCC2': 'mscr', + '\uD835\uDD10': 'Mfr', + '\uD835\uDD44': 'Mopf', + 'ℳ': 'Mscr', + '\uD835\uDD2B': 'nfr', + '\uD835\uDD5F': 'nopf', + '\uD835\uDCC3': 'nscr', + 'ℕ': 'Nopf', + '\uD835\uDCA9': 'Nscr', + '\uD835\uDD11': 'Nfr', + 'ń': 'nacute', + 'Ń': 'Nacute', + 'ň': 'ncaron', + 'Ň': 'Ncaron', + 'ñ': 'ntilde', + 'Ñ': 'Ntilde', + 'ņ': 'ncedil', + 'Ņ': 'Ncedil', + '\u2116': 'numero', + 'ŋ': 'eng', + 'Ŋ': 'ENG', + '\uD835\uDD60': 'oopf', + '\uD835\uDD2C': 'ofr', + 'ℴ': 'oscr', + '\uD835\uDCAA': 'Oscr', + '\uD835\uDD12': 'Ofr', + '\uD835\uDD46': 'Oopf', + 'º': 'ordm', + 'ó': 'oacute', + 'Ó': 'Oacute', + 'ò': 'ograve', + 'Ò': 'Ograve', + 'ô': 'ocirc', + 'Ô': 'Ocirc', + 'ö': 'ouml', + 'Ö': 'Ouml', + 'ő': 'odblac', + 'Ő': 'Odblac', + 'õ': 'otilde', + 'Õ': 'Otilde', + 'ø': 'oslash', + 'Ø': 'Oslash', + 'ō': 'omacr', + 'Ō': 'Omacr', + 'œ': 'oelig', + 'Œ': 'OElig', + '\uD835\uDD2D': 'pfr', + '\uD835\uDCC5': 'pscr', + '\uD835\uDD61': 'popf', + 'ℙ': 'Popf', + '\uD835\uDD13': 'Pfr', + '\uD835\uDCAB': 'Pscr', + '\uD835\uDD62': 'qopf', + '\uD835\uDD2E': 'qfr', + '\uD835\uDCC6': 'qscr', + '\uD835\uDCAC': 'Qscr', + '\uD835\uDD14': 'Qfr', + 'ℚ': 'Qopf', + 'ĸ': 'kgreen', + '\uD835\uDD2F': 'rfr', + '\uD835\uDD63': 'ropf', + '\uD835\uDCC7': 'rscr', + 'ℛ': 'Rscr', + 'ℜ': 'Re', + 'ℝ': 'Ropf', + 'ŕ': 'racute', + 'Ŕ': 'Racute', + 'ř': 'rcaron', + 'Ř': 'Rcaron', + 'ŗ': 'rcedil', + 'Ŗ': 'Rcedil', + '\uD835\uDD64': 'sopf', + '\uD835\uDCC8': 'sscr', + '\uD835\uDD30': 'sfr', + '\uD835\uDD4A': 'Sopf', + '\uD835\uDD16': 'Sfr', + '\uD835\uDCAE': 'Sscr', + '\u24C8': 'oS', + 'ś': 'sacute', + 'Ś': 'Sacute', + 'ŝ': 'scirc', + 'Ŝ': 'Scirc', + 'š': 'scaron', + 'Š': 'Scaron', + 'ş': 'scedil', + 'Ş': 'Scedil', + 'ß': 'szlig', + '\uD835\uDD31': 'tfr', + '\uD835\uDCC9': 'tscr', + '\uD835\uDD65': 'topf', + '\uD835\uDCAF': 'Tscr', + '\uD835\uDD17': 'Tfr', + '\uD835\uDD4B': 'Topf', + 'ť': 'tcaron', + 'Ť': 'Tcaron', + 'ţ': 'tcedil', + 'Ţ': 'Tcedil', + '\u2122': 'trade', + 'ŧ': 'tstrok', + 'Ŧ': 'Tstrok', + '\uD835\uDCCA': 'uscr', + '\uD835\uDD66': 'uopf', + '\uD835\uDD32': 'ufr', + '\uD835\uDD4C': 'Uopf', + '\uD835\uDD18': 'Ufr', + '\uD835\uDCB0': 'Uscr', + 'ú': 'uacute', + 'Ú': 'Uacute', + 'ù': 'ugrave', + 'Ù': 'Ugrave', + 'ŭ': 'ubreve', + 'Ŭ': 'Ubreve', + 'û': 'ucirc', + 'Û': 'Ucirc', + 'ů': 'uring', + 'Ů': 'Uring', + 'ü': 'uuml', + 'Ü': 'Uuml', + 'ű': 'udblac', + 'Ű': 'Udblac', + 'ũ': 'utilde', + 'Ũ': 'Utilde', + 'ų': 'uogon', + 'Ų': 'Uogon', + 'ū': 'umacr', + 'Ū': 'Umacr', + '\uD835\uDD33': 'vfr', + '\uD835\uDD67': 'vopf', + '\uD835\uDCCB': 'vscr', + '\uD835\uDD19': 'Vfr', + '\uD835\uDD4D': 'Vopf', + '\uD835\uDCB1': 'Vscr', + '\uD835\uDD68': 'wopf', + '\uD835\uDCCC': 'wscr', + '\uD835\uDD34': 'wfr', + '\uD835\uDCB2': 'Wscr', + '\uD835\uDD4E': 'Wopf', + '\uD835\uDD1A': 'Wfr', + 'ŵ': 'wcirc', + 'Ŵ': 'Wcirc', + '\uD835\uDD35': 'xfr', + '\uD835\uDCCD': 'xscr', + '\uD835\uDD69': 'xopf', + '\uD835\uDD4F': 'Xopf', + '\uD835\uDD1B': 'Xfr', + '\uD835\uDCB3': 'Xscr', + '\uD835\uDD36': 'yfr', + '\uD835\uDCCE': 'yscr', + '\uD835\uDD6A': 'yopf', + '\uD835\uDCB4': 'Yscr', + '\uD835\uDD1C': 'Yfr', + '\uD835\uDD50': 'Yopf', + 'ý': 'yacute', + 'Ý': 'Yacute', + 'ŷ': 'ycirc', + 'Ŷ': 'Ycirc', + 'ÿ': 'yuml', + 'Ÿ': 'Yuml', + '\uD835\uDCCF': 'zscr', + '\uD835\uDD37': 'zfr', + '\uD835\uDD6B': 'zopf', + 'ℨ': 'Zfr', + 'ℤ': 'Zopf', + '\uD835\uDCB5': 'Zscr', + 'ź': 'zacute', + 'Ź': 'Zacute', + 'ž': 'zcaron', + 'Ž': 'Zcaron', + 'ż': 'zdot', + 'Ż': 'Zdot', + 'Ƶ': 'imped', + 'þ': 'thorn', + 'Þ': 'THORN', + 'ʼn': 'napos', + 'α': 'alpha', + 'Α': 'Alpha', + 'β': 'beta', + 'Β': 'Beta', + 'γ': 'gamma', + 'Γ': 'Gamma', + 'δ': 'delta', + 'Δ': 'Delta', + 'ε': 'epsi', + 'ϵ': 'epsiv', + 'Ε': 'Epsilon', + 'ϝ': 'gammad', + 'Ϝ': 'Gammad', + 'ζ': 'zeta', + 'Ζ': 'Zeta', + 'η': 'eta', + 'Η': 'Eta', + 'θ': 'theta', + 'ϑ': 'thetav', + 'Θ': 'Theta', + 'ι': 'iota', + 'Ι': 'Iota', + 'κ': 'kappa', + 'ϰ': 'kappav', + 'Κ': 'Kappa', + 'λ': 'lambda', + 'Λ': 'Lambda', + 'μ': 'mu', + 'µ': 'micro', + 'Μ': 'Mu', + 'ν': 'nu', + 'Ν': 'Nu', + 'ξ': 'xi', + 'Ξ': 'Xi', + 'ο': 'omicron', + 'Ο': 'Omicron', + 'π': 'pi', + 'ϖ': 'piv', + 'Π': 'Pi', + 'ρ': 'rho', + 'ϱ': 'rhov', + 'Ρ': 'Rho', + 'σ': 'sigma', + 'Σ': 'Sigma', + 'ς': 'sigmaf', + 'τ': 'tau', + 'Τ': 'Tau', + 'υ': 'upsi', + 'Υ': 'Upsilon', + 'ϒ': 'Upsi', + 'φ': 'phi', + 'ϕ': 'phiv', + 'Φ': 'Phi', + 'χ': 'chi', + 'Χ': 'Chi', + 'ψ': 'psi', + 'Ψ': 'Psi', + 'ω': 'omega', + 'Ω': 'ohm', + 'а': 'acy', + 'А': 'Acy', + 'б': 'bcy', + 'Б': 'Bcy', + 'в': 'vcy', + 'В': 'Vcy', + 'г': 'gcy', + 'Г': 'Gcy', + 'ѓ': 'gjcy', + 'Ѓ': 'GJcy', + 'д': 'dcy', + 'Д': 'Dcy', + 'ђ': 'djcy', + 'Ђ': 'DJcy', + 'е': 'iecy', + 'Е': 'IEcy', + 'ё': 'iocy', + 'Ё': 'IOcy', + 'є': 'jukcy', + 'Є': 'Jukcy', + 'ж': 'zhcy', + 'Ж': 'ZHcy', + 'з': 'zcy', + 'З': 'Zcy', + 'ѕ': 'dscy', + 'Ѕ': 'DScy', + 'и': 'icy', + 'И': 'Icy', + 'і': 'iukcy', + 'І': 'Iukcy', + 'ї': 'yicy', + 'Ї': 'YIcy', + 'й': 'jcy', + 'Й': 'Jcy', + 'ј': 'jsercy', + 'Ј': 'Jsercy', + 'к': 'kcy', + 'К': 'Kcy', + 'ќ': 'kjcy', + 'Ќ': 'KJcy', + 'л': 'lcy', + 'Л': 'Lcy', + 'љ': 'ljcy', + 'Љ': 'LJcy', + 'м': 'mcy', + 'М': 'Mcy', + 'н': 'ncy', + 'Н': 'Ncy', + 'њ': 'njcy', + 'Њ': 'NJcy', + 'о': 'ocy', + 'О': 'Ocy', + 'п': 'pcy', + 'П': 'Pcy', + 'р': 'rcy', + 'Р': 'Rcy', + 'с': 'scy', + 'С': 'Scy', + 'т': 'tcy', + 'Т': 'Tcy', + 'ћ': 'tshcy', + 'Ћ': 'TSHcy', + 'у': 'ucy', + 'У': 'Ucy', + 'ў': 'ubrcy', + 'Ў': 'Ubrcy', + 'ф': 'fcy', + 'Ф': 'Fcy', + 'х': 'khcy', + 'Х': 'KHcy', + 'ц': 'tscy', + 'Ц': 'TScy', + 'ч': 'chcy', + 'Ч': 'CHcy', + 'џ': 'dzcy', + 'Џ': 'DZcy', + 'ш': 'shcy', + 'Ш': 'SHcy', + 'щ': 'shchcy', + 'Щ': 'SHCHcy', + 'ъ': 'hardcy', + 'Ъ': 'HARDcy', + 'ы': 'ycy', + 'Ы': 'Ycy', + 'ь': 'softcy', + 'Ь': 'SOFTcy', + 'э': 'ecy', + 'Э': 'Ecy', + 'ю': 'yucy', + 'Ю': 'YUcy', + 'я': 'yacy', + 'Я': 'YAcy', + 'ℵ': 'aleph', + 'ℶ': 'beth', + 'ℷ': 'gimel', + 'ℸ': 'daleth' + }; + var regexEscape = /["&'<>`]/g; + var escapeMap = { + '"': '"', + '&': '&', + '\'': ''', + '<': '<', + '>': '>', + '`': '`' + }; + var regexInvalidEntity = /&#(?:[xX][^a-fA-F0-9]|[^0-9xX])/; + var regexInvalidRawCodePoint = /[\0-\x08\x0B\x0E-\x1F\x7F-\x9F\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; + var regexDecode = /&(CounterClockwiseContourIntegral|DoubleLongLeftRightArrow|ClockwiseContourIntegral|NotNestedGreaterGreater|NotSquareSupersetEqual|DiacriticalDoubleAcute|NotRightTriangleEqual|NotSucceedsSlantEqual|NotPrecedesSlantEqual|CloseCurlyDoubleQuote|NegativeVeryThinSpace|DoubleContourIntegral|FilledVerySmallSquare|CapitalDifferentialD|OpenCurlyDoubleQuote|EmptyVerySmallSquare|NestedGreaterGreater|DoubleLongRightArrow|NotLeftTriangleEqual|NotGreaterSlantEqual|ReverseUpEquilibrium|DoubleLeftRightArrow|NotSquareSubsetEqual|NotDoubleVerticalBar|RightArrowLeftArrow|NotGreaterFullEqual|NotRightTriangleBar|SquareSupersetEqual|DownLeftRightVector|DoubleLongLeftArrow|leftrightsquigarrow|LeftArrowRightArrow|NegativeMediumSpace|blacktriangleright|RightDownVectorBar|PrecedesSlantEqual|RightDoubleBracket|SucceedsSlantEqual|NotLeftTriangleBar|RightTriangleEqual|SquareIntersection|RightDownTeeVector|ReverseEquilibrium|NegativeThickSpace|longleftrightarrow|Longleftrightarrow|LongLeftRightArrow|DownRightTeeVector|DownRightVectorBar|GreaterSlantEqual|SquareSubsetEqual|LeftDownVectorBar|LeftDoubleBracket|VerticalSeparator|rightleftharpoons|NotGreaterGreater|NotSquareSuperset|blacktriangleleft|blacktriangledown|NegativeThinSpace|LeftDownTeeVector|NotLessSlantEqual|leftrightharpoons|DoubleUpDownArrow|DoubleVerticalBar|LeftTriangleEqual|FilledSmallSquare|twoheadrightarrow|NotNestedLessLess|DownLeftTeeVector|DownLeftVectorBar|RightAngleBracket|NotTildeFullEqual|NotReverseElement|RightUpDownVector|DiacriticalTilde|NotSucceedsTilde|circlearrowright|NotPrecedesEqual|rightharpoondown|DoubleRightArrow|NotSucceedsEqual|NonBreakingSpace|NotRightTriangle|LessEqualGreater|RightUpTeeVector|LeftAngleBracket|GreaterFullEqual|DownArrowUpArrow|RightUpVectorBar|twoheadleftarrow|GreaterEqualLess|downharpoonright|RightTriangleBar|ntrianglerighteq|NotSupersetEqual|LeftUpDownVector|DiacriticalAcute|rightrightarrows|vartriangleright|UpArrowDownArrow|DiacriticalGrave|UnderParenthesis|EmptySmallSquare|LeftUpVectorBar|leftrightarrows|DownRightVector|downharpoonleft|trianglerighteq|ShortRightArrow|OverParenthesis|DoubleLeftArrow|DoubleDownArrow|NotSquareSubset|bigtriangledown|ntrianglelefteq|UpperRightArrow|curvearrowright|vartriangleleft|NotLeftTriangle|nleftrightarrow|LowerRightArrow|NotHumpDownHump|NotGreaterTilde|rightthreetimes|LeftUpTeeVector|NotGreaterEqual|straightepsilon|LeftTriangleBar|rightsquigarrow|ContourIntegral|rightleftarrows|CloseCurlyQuote|RightDownVector|LeftRightVector|nLeftrightarrow|leftharpoondown|circlearrowleft|SquareSuperset|OpenCurlyQuote|hookrightarrow|HorizontalLine|DiacriticalDot|NotLessGreater|ntriangleright|DoubleRightTee|InvisibleComma|InvisibleTimes|LowerLeftArrow|DownLeftVector|NotSubsetEqual|curvearrowleft|trianglelefteq|NotVerticalBar|TildeFullEqual|downdownarrows|NotGreaterLess|RightTeeVector|ZeroWidthSpace|looparrowright|LongRightArrow|doublebarwedge|ShortLeftArrow|ShortDownArrow|RightVectorBar|GreaterGreater|ReverseElement|rightharpoonup|LessSlantEqual|leftthreetimes|upharpoonright|rightarrowtail|LeftDownVector|Longrightarrow|NestedLessLess|UpperLeftArrow|nshortparallel|leftleftarrows|leftrightarrow|Leftrightarrow|LeftRightArrow|longrightarrow|upharpoonleft|RightArrowBar|ApplyFunction|LeftTeeVector|leftarrowtail|NotEqualTilde|varsubsetneqq|varsupsetneqq|RightTeeArrow|SucceedsEqual|SucceedsTilde|LeftVectorBar|SupersetEqual|hookleftarrow|DifferentialD|VerticalTilde|VeryThinSpace|blacktriangle|bigtriangleup|LessFullEqual|divideontimes|leftharpoonup|UpEquilibrium|ntriangleleft|RightTriangle|measuredangle|shortparallel|longleftarrow|Longleftarrow|LongLeftArrow|DoubleLeftTee|Poincareplane|PrecedesEqual|triangleright|DoubleUpArrow|RightUpVector|fallingdotseq|looparrowleft|PrecedesTilde|NotTildeEqual|NotTildeTilde|smallsetminus|Proportional|triangleleft|triangledown|UnderBracket|NotHumpEqual|exponentiale|ExponentialE|NotLessTilde|HilbertSpace|RightCeiling|blacklozenge|varsupsetneq|HumpDownHump|GreaterEqual|VerticalLine|LeftTeeArrow|NotLessEqual|DownTeeArrow|LeftTriangle|varsubsetneq|Intersection|NotCongruent|DownArrowBar|LeftUpVector|LeftArrowBar|risingdotseq|GreaterTilde|RoundImplies|SquareSubset|ShortUpArrow|NotSuperset|quaternions|precnapprox|backepsilon|preccurlyeq|OverBracket|blacksquare|MediumSpace|VerticalBar|circledcirc|circleddash|CircleMinus|CircleTimes|LessGreater|curlyeqprec|curlyeqsucc|diamondsuit|UpDownArrow|Updownarrow|RuleDelayed|Rrightarrow|updownarrow|RightVector|nRightarrow|nrightarrow|eqslantless|LeftCeiling|Equilibrium|SmallCircle|expectation|NotSucceeds|thickapprox|GreaterLess|SquareUnion|NotPrecedes|NotLessLess|straightphi|succnapprox|succcurlyeq|SubsetEqual|sqsupseteq|Proportion|Laplacetrf|ImaginaryI|supsetneqq|NotGreater|gtreqqless|NotElement|ThickSpace|TildeEqual|TildeTilde|Fouriertrf|rmoustache|EqualTilde|eqslantgtr|UnderBrace|LeftVector|UpArrowBar|nLeftarrow|nsubseteqq|subsetneqq|nsupseteqq|nleftarrow|succapprox|lessapprox|UpTeeArrow|upuparrows|curlywedge|lesseqqgtr|varepsilon|varnothing|RightFloor|complement|CirclePlus|sqsubseteq|Lleftarrow|circledast|RightArrow|Rightarrow|rightarrow|lmoustache|Bernoullis|precapprox|mapstoleft|mapstodown|longmapsto|dotsquare|downarrow|DoubleDot|nsubseteq|supsetneq|leftarrow|nsupseteq|subsetneq|ThinSpace|ngeqslant|subseteqq|HumpEqual|NotSubset|triangleq|NotCupCap|lesseqgtr|heartsuit|TripleDot|Leftarrow|Coproduct|Congruent|varpropto|complexes|gvertneqq|LeftArrow|LessTilde|supseteqq|MinusPlus|CircleDot|nleqslant|NotExists|gtreqless|nparallel|UnionPlus|LeftFloor|checkmark|CenterDot|centerdot|Mellintrf|gtrapprox|bigotimes|OverBrace|spadesuit|therefore|pitchfork|rationals|PlusMinus|Backslash|Therefore|DownBreve|backsimeq|backprime|DownArrow|nshortmid|Downarrow|lvertneqq|eqvparsl|imagline|imagpart|infintie|integers|Integral|intercal|LessLess|Uarrocir|intlarhk|sqsupset|angmsdaf|sqsubset|llcorner|vartheta|cupbrcap|lnapprox|Superset|SuchThat|succnsim|succneqq|angmsdag|biguplus|curlyvee|trpezium|Succeeds|NotTilde|bigwedge|angmsdah|angrtvbd|triminus|cwconint|fpartint|lrcorner|smeparsl|subseteq|urcorner|lurdshar|laemptyv|DDotrahd|approxeq|ldrushar|awconint|mapstoup|backcong|shortmid|triangle|geqslant|gesdotol|timesbar|circledR|circledS|setminus|multimap|naturals|scpolint|ncongdot|RightTee|boxminus|gnapprox|boxtimes|andslope|thicksim|angmsdaa|varsigma|cirfnint|rtriltri|angmsdab|rppolint|angmsdac|barwedge|drbkarow|clubsuit|thetasym|bsolhsub|capbrcup|dzigrarr|doteqdot|DotEqual|dotminus|UnderBar|NotEqual|realpart|otimesas|ulcorner|hksearow|hkswarow|parallel|PartialD|elinters|emptyset|plusacir|bbrktbrk|angmsdad|pointint|bigoplus|angmsdae|Precedes|bigsqcup|varkappa|notindot|supseteq|precneqq|precnsim|profalar|profline|profsurf|leqslant|lesdotor|raemptyv|subplus|notnivb|notnivc|subrarr|zigrarr|vzigzag|submult|subedot|Element|between|cirscir|larrbfs|larrsim|lotimes|lbrksld|lbrkslu|lozenge|ldrdhar|dbkarow|bigcirc|epsilon|simrarr|simplus|ltquest|Epsilon|luruhar|gtquest|maltese|npolint|eqcolon|npreceq|bigodot|ddagger|gtrless|bnequiv|harrcir|ddotseq|equivDD|backsim|demptyv|nsqsube|nsqsupe|Upsilon|nsubset|upsilon|minusdu|nsucceq|swarrow|nsupset|coloneq|searrow|boxplus|napprox|natural|asympeq|alefsym|congdot|nearrow|bigstar|diamond|supplus|tritime|LeftTee|nvinfin|triplus|NewLine|nvltrie|nvrtrie|nwarrow|nexists|Diamond|ruluhar|Implies|supmult|angzarr|suplarr|suphsub|questeq|because|digamma|Because|olcross|bemptyv|omicron|Omicron|rotimes|NoBreak|intprod|angrtvb|orderof|uwangle|suphsol|lesdoto|orslope|DownTee|realine|cudarrl|rdldhar|OverBar|supedot|lessdot|supdsub|topfork|succsim|rbrkslu|rbrksld|pertenk|cudarrr|isindot|planckh|lessgtr|pluscir|gesdoto|plussim|plustwo|lesssim|cularrp|rarrsim|Cayleys|notinva|notinvb|notinvc|UpArrow|Uparrow|uparrow|NotLess|dwangle|precsim|Product|curarrm|Cconint|dotplus|rarrbfs|ccupssm|Cedilla|cemptyv|notniva|quatint|frac35|frac38|frac45|frac56|frac58|frac78|tridot|xoplus|gacute|gammad|Gammad|lfisht|lfloor|bigcup|sqsupe|gbreve|Gbreve|lharul|sqsube|sqcups|Gcedil|apacir|llhard|lmidot|Lmidot|lmoust|andand|sqcaps|approx|Abreve|spades|circeq|tprime|divide|topcir|Assign|topbot|gesdot|divonx|xuplus|timesd|gesles|atilde|solbar|SOFTcy|loplus|timesb|lowast|lowbar|dlcorn|dlcrop|softcy|dollar|lparlt|thksim|lrhard|Atilde|lsaquo|smashp|bigvee|thinsp|wreath|bkarow|lsquor|lstrok|Lstrok|lthree|ltimes|ltlarr|DotDot|simdot|ltrPar|weierp|xsqcup|angmsd|sigmav|sigmaf|zeetrf|Zcaron|zcaron|mapsto|vsupne|thetav|cirmid|marker|mcomma|Zacute|vsubnE|there4|gtlPar|vsubne|bottom|gtrarr|SHCHcy|shchcy|midast|midcir|middot|minusb|minusd|gtrdot|bowtie|sfrown|mnplus|models|colone|seswar|Colone|mstpos|searhk|gtrsim|nacute|Nacute|boxbox|telrec|hairsp|Tcedil|nbumpe|scnsim|ncaron|Ncaron|ncedil|Ncedil|hamilt|Scedil|nearhk|hardcy|HARDcy|tcedil|Tcaron|commat|nequiv|nesear|tcaron|target|hearts|nexist|varrho|scedil|Scaron|scaron|hellip|Sacute|sacute|hercon|swnwar|compfn|rtimes|rthree|rsquor|rsaquo|zacute|wedgeq|homtht|barvee|barwed|Barwed|rpargt|horbar|conint|swarhk|roplus|nltrie|hslash|hstrok|Hstrok|rmoust|Conint|bprime|hybull|hyphen|iacute|Iacute|supsup|supsub|supsim|varphi|coprod|brvbar|agrave|Supset|supset|igrave|Igrave|notinE|Agrave|iiiint|iinfin|copysr|wedbar|Verbar|vangrt|becaus|incare|verbar|inodot|bullet|drcorn|intcal|drcrop|cularr|vellip|Utilde|bumpeq|cupcap|dstrok|Dstrok|CupCap|cupcup|cupdot|eacute|Eacute|supdot|iquest|easter|ecaron|Ecaron|ecolon|isinsv|utilde|itilde|Itilde|curarr|succeq|Bumpeq|cacute|ulcrop|nparsl|Cacute|nprcue|egrave|Egrave|nrarrc|nrarrw|subsup|subsub|nrtrie|jsercy|nsccue|Jsercy|kappav|kcedil|Kcedil|subsim|ulcorn|nsimeq|egsdot|veebar|kgreen|capand|elsdot|Subset|subset|curren|aacute|lacute|Lacute|emptyv|ntilde|Ntilde|lagran|lambda|Lambda|capcap|Ugrave|langle|subdot|emsp13|numero|emsp14|nvdash|nvDash|nVdash|nVDash|ugrave|ufisht|nvHarr|larrfs|nvlArr|larrhk|larrlp|larrpl|nvrArr|Udblac|nwarhk|larrtl|nwnear|oacute|Oacute|latail|lAtail|sstarf|lbrace|odblac|Odblac|lbrack|udblac|odsold|eparsl|lcaron|Lcaron|ograve|Ograve|lcedil|Lcedil|Aacute|ssmile|ssetmn|squarf|ldquor|capcup|ominus|cylcty|rharul|eqcirc|dagger|rfloor|rfisht|Dagger|daleth|equals|origof|capdot|equest|dcaron|Dcaron|rdquor|oslash|Oslash|otilde|Otilde|otimes|Otimes|urcrop|Ubreve|ubreve|Yacute|Uacute|uacute|Rcedil|rcedil|urcorn|parsim|Rcaron|Vdashl|rcaron|Tstrok|percnt|period|permil|Exists|yacute|rbrack|rbrace|phmmat|ccaron|Ccaron|planck|ccedil|plankv|tstrok|female|plusdo|plusdu|ffilig|plusmn|ffllig|Ccedil|rAtail|dfisht|bernou|ratail|Rarrtl|rarrtl|angsph|rarrpl|rarrlp|rarrhk|xwedge|xotime|forall|ForAll|Vvdash|vsupnE|preceq|bigcap|frac12|frac13|frac14|primes|rarrfs|prnsim|frac15|Square|frac16|square|lesdot|frac18|frac23|propto|prurel|rarrap|rangle|puncsp|frac25|Racute|qprime|racute|lesges|frac34|abreve|AElig|eqsim|utdot|setmn|urtri|Equal|Uring|seArr|uring|searr|dashv|Dashv|mumap|nabla|iogon|Iogon|sdote|sdotb|scsim|napid|napos|equiv|natur|Acirc|dblac|erarr|nbump|iprod|erDot|ucirc|awint|esdot|angrt|ncong|isinE|scnap|Scirc|scirc|ndash|isins|Ubrcy|nearr|neArr|isinv|nedot|ubrcy|acute|Ycirc|iukcy|Iukcy|xutri|nesim|caret|jcirc|Jcirc|caron|twixt|ddarr|sccue|exist|jmath|sbquo|ngeqq|angst|ccaps|lceil|ngsim|UpTee|delta|Delta|rtrif|nharr|nhArr|nhpar|rtrie|jukcy|Jukcy|kappa|rsquo|Kappa|nlarr|nlArr|TSHcy|rrarr|aogon|Aogon|fflig|xrarr|tshcy|ccirc|nleqq|filig|upsih|nless|dharl|nlsim|fjlig|ropar|nltri|dharr|robrk|roarr|fllig|fltns|roang|rnmid|subnE|subne|lAarr|trisb|Ccirc|acirc|ccups|blank|VDash|forkv|Vdash|langd|cedil|blk12|blk14|laquo|strns|diams|notin|vDash|larrb|blk34|block|disin|uplus|vdash|vBarv|aelig|starf|Wedge|check|xrArr|lates|lbarr|lBarr|notni|lbbrk|bcong|frasl|lbrke|frown|vrtri|vprop|vnsup|gamma|Gamma|wedge|xodot|bdquo|srarr|doteq|ldquo|boxdl|boxdL|gcirc|Gcirc|boxDl|boxDL|boxdr|boxdR|boxDr|TRADE|trade|rlhar|boxDR|vnsub|npart|vltri|rlarr|boxhd|boxhD|nprec|gescc|nrarr|nrArr|boxHd|boxHD|boxhu|boxhU|nrtri|boxHu|clubs|boxHU|times|colon|Colon|gimel|xlArr|Tilde|nsime|tilde|nsmid|nspar|THORN|thorn|xlarr|nsube|nsubE|thkap|xhArr|comma|nsucc|boxul|boxuL|nsupe|nsupE|gneqq|gnsim|boxUl|boxUL|grave|boxur|boxuR|boxUr|boxUR|lescc|angle|bepsi|boxvh|varpi|boxvH|numsp|Theta|gsime|gsiml|theta|boxVh|boxVH|boxvl|gtcir|gtdot|boxvL|boxVl|boxVL|crarr|cross|Cross|nvsim|boxvr|nwarr|nwArr|sqsup|dtdot|Uogon|lhard|lharu|dtrif|ocirc|Ocirc|lhblk|duarr|odash|sqsub|Hacek|sqcup|llarr|duhar|oelig|OElig|ofcir|boxvR|uogon|lltri|boxVr|csube|uuarr|ohbar|csupe|ctdot|olarr|olcir|harrw|oline|sqcap|omacr|Omacr|omega|Omega|boxVR|aleph|lneqq|lnsim|loang|loarr|rharu|lobrk|hcirc|operp|oplus|rhard|Hcirc|orarr|Union|order|ecirc|Ecirc|cuepr|szlig|cuesc|breve|reals|eDDot|Breve|hoarr|lopar|utrif|rdquo|Umacr|umacr|efDot|swArr|ultri|alpha|rceil|ovbar|swarr|Wcirc|wcirc|smtes|smile|bsemi|lrarr|aring|parsl|lrhar|bsime|uhblk|lrtri|cupor|Aring|uharr|uharl|slarr|rbrke|bsolb|lsime|rbbrk|RBarr|lsimg|phone|rBarr|rbarr|icirc|lsquo|Icirc|emacr|Emacr|ratio|simne|plusb|simlE|simgE|simeq|pluse|ltcir|ltdot|empty|xharr|xdtri|iexcl|Alpha|ltrie|rarrw|pound|ltrif|xcirc|bumpe|prcue|bumpE|asymp|amacr|cuvee|Sigma|sigma|iiint|udhar|iiota|ijlig|IJlig|supnE|imacr|Imacr|prime|Prime|image|prnap|eogon|Eogon|rarrc|mdash|mDDot|cuwed|imath|supne|imped|Amacr|udarr|prsim|micro|rarrb|cwint|raquo|infin|eplus|range|rangd|Ucirc|radic|minus|amalg|veeeq|rAarr|epsiv|ycirc|quest|sharp|quot|zwnj|Qscr|race|qscr|Qopf|qopf|qint|rang|Rang|Zscr|zscr|Zopf|zopf|rarr|rArr|Rarr|Pscr|pscr|prop|prod|prnE|prec|ZHcy|zhcy|prap|Zeta|zeta|Popf|popf|Zdot|plus|zdot|Yuml|yuml|phiv|YUcy|yucy|Yscr|yscr|perp|Yopf|yopf|part|para|YIcy|Ouml|rcub|yicy|YAcy|rdca|ouml|osol|Oscr|rdsh|yacy|real|oscr|xvee|andd|rect|andv|Xscr|oror|ordm|ordf|xscr|ange|aopf|Aopf|rHar|Xopf|opar|Oopf|xopf|xnis|rhov|oopf|omid|xmap|oint|apid|apos|ogon|ascr|Ascr|odot|odiv|xcup|xcap|ocir|oast|nvlt|nvle|nvgt|nvge|nvap|Wscr|wscr|auml|ntlg|ntgl|nsup|nsub|nsim|Nscr|nscr|nsce|Wopf|ring|npre|wopf|npar|Auml|Barv|bbrk|Nopf|nopf|nmid|nLtv|beta|ropf|Ropf|Beta|beth|nles|rpar|nleq|bnot|bNot|nldr|NJcy|rscr|Rscr|Vscr|vscr|rsqb|njcy|bopf|nisd|Bopf|rtri|Vopf|nGtv|ngtr|vopf|boxh|boxH|boxv|nges|ngeq|boxV|bscr|scap|Bscr|bsim|Vert|vert|bsol|bull|bump|caps|cdot|ncup|scnE|ncap|nbsp|napE|Cdot|cent|sdot|Vbar|nang|vBar|chcy|Mscr|mscr|sect|semi|CHcy|Mopf|mopf|sext|circ|cire|mldr|mlcp|cirE|comp|shcy|SHcy|vArr|varr|cong|copf|Copf|copy|COPY|malt|male|macr|lvnE|cscr|ltri|sime|ltcc|simg|Cscr|siml|csub|Uuml|lsqb|lsim|uuml|csup|Lscr|lscr|utri|smid|lpar|cups|smte|lozf|darr|Lopf|Uscr|solb|lopf|sopf|Sopf|lneq|uscr|spar|dArr|lnap|Darr|dash|Sqrt|LJcy|ljcy|lHar|dHar|Upsi|upsi|diam|lesg|djcy|DJcy|leqq|dopf|Dopf|dscr|Dscr|dscy|ldsh|ldca|squf|DScy|sscr|Sscr|dsol|lcub|late|star|Star|Uopf|Larr|lArr|larr|uopf|dtri|dzcy|sube|subE|Lang|lang|Kscr|kscr|Kopf|kopf|KJcy|kjcy|KHcy|khcy|DZcy|ecir|edot|eDot|Jscr|jscr|succ|Jopf|jopf|Edot|uHar|emsp|ensp|Iuml|iuml|eopf|isin|Iscr|iscr|Eopf|epar|sung|epsi|escr|sup1|sup2|sup3|Iota|iota|supe|supE|Iopf|iopf|IOcy|iocy|Escr|esim|Esim|imof|Uarr|QUOT|uArr|uarr|euml|IEcy|iecy|Idot|Euml|euro|excl|Hscr|hscr|Hopf|hopf|TScy|tscy|Tscr|hbar|tscr|flat|tbrk|fnof|hArr|harr|half|fopf|Fopf|tdot|gvnE|fork|trie|gtcc|fscr|Fscr|gdot|gsim|Gscr|gscr|Gopf|gopf|gneq|Gdot|tosa|gnap|Topf|topf|geqq|toea|GJcy|gjcy|tint|gesl|mid|Sfr|ggg|top|ges|gla|glE|glj|geq|gne|gEl|gel|gnE|Gcy|gcy|gap|Tfr|tfr|Tcy|tcy|Hat|Tau|Ffr|tau|Tab|hfr|Hfr|ffr|Fcy|fcy|icy|Icy|iff|ETH|eth|ifr|Ifr|Eta|eta|int|Int|Sup|sup|ucy|Ucy|Sum|sum|jcy|ENG|ufr|Ufr|eng|Jcy|jfr|els|ell|egs|Efr|efr|Jfr|uml|kcy|Kcy|Ecy|ecy|kfr|Kfr|lap|Sub|sub|lat|lcy|Lcy|leg|Dot|dot|lEg|leq|les|squ|div|die|lfr|Lfr|lgE|Dfr|dfr|Del|deg|Dcy|dcy|lne|lnE|sol|loz|smt|Cup|lrm|cup|lsh|Lsh|sim|shy|map|Map|mcy|Mcy|mfr|Mfr|mho|gfr|Gfr|sfr|cir|Chi|chi|nap|Cfr|vcy|Vcy|cfr|Scy|scy|ncy|Ncy|vee|Vee|Cap|cap|nfr|scE|sce|Nfr|nge|ngE|nGg|vfr|Vfr|ngt|bot|nGt|nis|niv|Rsh|rsh|nle|nlE|bne|Bfr|bfr|nLl|nlt|nLt|Bcy|bcy|not|Not|rlm|wfr|Wfr|npr|nsc|num|ocy|ast|Ocy|ofr|xfr|Xfr|Ofr|ogt|ohm|apE|olt|Rho|ape|rho|Rfr|rfr|ord|REG|ang|reg|orv|And|and|AMP|Rcy|amp|Afr|ycy|Ycy|yen|yfr|Yfr|rcy|par|pcy|Pcy|pfr|Pfr|phi|Phi|afr|Acy|acy|zcy|Zcy|piv|acE|acd|zfr|Zfr|pre|prE|psi|Psi|qfr|Qfr|zwj|Or|ge|Gg|gt|gg|el|oS|lt|Lt|LT|Re|lg|gl|eg|ne|Im|it|le|DD|wp|wr|nu|Nu|dd|lE|Sc|sc|pi|Pi|ee|af|ll|Ll|rx|gE|xi|pm|Xi|ic|pr|Pr|in|ni|mp|mu|ac|Mu|or|ap|Gt|GT|ii);|&(Aacute|Agrave|Atilde|Ccedil|Eacute|Egrave|Iacute|Igrave|Ntilde|Oacute|Ograve|Oslash|Otilde|Uacute|Ugrave|Yacute|aacute|agrave|atilde|brvbar|ccedil|curren|divide|eacute|egrave|frac12|frac14|frac34|iacute|igrave|iquest|middot|ntilde|oacute|ograve|oslash|otilde|plusmn|uacute|ugrave|yacute|AElig|Acirc|Aring|Ecirc|Icirc|Ocirc|THORN|Ucirc|acirc|acute|aelig|aring|cedil|ecirc|icirc|iexcl|laquo|micro|ocirc|pound|raquo|szlig|thorn|times|ucirc|Auml|COPY|Euml|Iuml|Ouml|QUOT|Uuml|auml|cent|copy|euml|iuml|macr|nbsp|ordf|ordm|ouml|para|quot|sect|sup1|sup2|sup3|uuml|yuml|AMP|ETH|REG|amp|deg|eth|not|reg|shy|uml|yen|GT|LT|gt|lt)(?!;)([=a-zA-Z0-9]?)|&#([0-9]+)(;?)|&#[xX]([a-fA-F0-9]+)(;?)|&([0-9a-zA-Z]+)/g; + var decodeMap = { + 'aacute': 'á', + 'Aacute': 'Á', + 'abreve': 'ă', + 'Abreve': 'Ă', + 'ac': '\u223E', + 'acd': '\u223F', + 'acE': '\u223E̳', + 'acirc': 'â', + 'Acirc': 'Â', + 'acute': '\xB4', + 'acy': 'а', + 'Acy': 'А', + 'aelig': 'æ', + 'AElig': 'Æ', + 'af': '\u2061', + 'afr': '\uD835\uDD1E', + 'Afr': '\uD835\uDD04', + 'agrave': 'à', + 'Agrave': 'À', + 'alefsym': 'ℵ', + 'aleph': 'ℵ', + 'alpha': 'α', + 'Alpha': 'Α', + 'amacr': 'ā', + 'Amacr': 'Ā', + 'amalg': '\u2A3F', + 'amp': '&', + 'AMP': '&', + 'and': '\u2227', + 'And': '\u2A53', + 'andand': '\u2A55', + 'andd': '\u2A5C', + 'andslope': '\u2A58', + 'andv': '\u2A5A', + 'ang': '\u2220', + 'ange': '\u29A4', + 'angle': '\u2220', + 'angmsd': '\u2221', + 'angmsdaa': '\u29A8', + 'angmsdab': '\u29A9', + 'angmsdac': '\u29AA', + 'angmsdad': '\u29AB', + 'angmsdae': '\u29AC', + 'angmsdaf': '\u29AD', + 'angmsdag': '\u29AE', + 'angmsdah': '\u29AF', + 'angrt': '\u221F', + 'angrtvb': '\u22BE', + 'angrtvbd': '\u299D', + 'angsph': '\u2222', + 'angst': 'Å', + 'angzarr': '\u237C', + 'aogon': 'ą', + 'Aogon': 'Ą', + 'aopf': '\uD835\uDD52', + 'Aopf': '\uD835\uDD38', + 'ap': '\u2248', + 'apacir': '\u2A6F', + 'ape': '\u224A', + 'apE': '\u2A70', + 'apid': '\u224B', + 'apos': '\'', + 'ApplyFunction': '\u2061', + 'approx': '\u2248', + 'approxeq': '\u224A', + 'aring': 'å', + 'Aring': 'Å', + 'ascr': '\uD835\uDCB6', + 'Ascr': '\uD835\uDC9C', + 'Assign': '\u2254', + 'ast': '*', + 'asymp': '\u2248', + 'asympeq': '\u224D', + 'atilde': 'ã', + 'Atilde': 'Ã', + 'auml': 'ä', + 'Auml': 'Ä', + 'awconint': '\u2233', + 'awint': '\u2A11', + 'backcong': '\u224C', + 'backepsilon': '\u03F6', + 'backprime': '\u2035', + 'backsim': '\u223D', + 'backsimeq': '\u22CD', + 'Backslash': '\u2216', + 'Barv': '\u2AE7', + 'barvee': '\u22BD', + 'barwed': '\u2305', + 'Barwed': '\u2306', + 'barwedge': '\u2305', + 'bbrk': '\u23B5', + 'bbrktbrk': '\u23B6', + 'bcong': '\u224C', + 'bcy': 'б', + 'Bcy': 'Б', + 'bdquo': '\u201E', + 'becaus': '\u2235', + 'because': '\u2235', + 'Because': '\u2235', + 'bemptyv': '\u29B0', + 'bepsi': '\u03F6', + 'bernou': 'ℬ', + 'Bernoullis': 'ℬ', + 'beta': 'β', + 'Beta': 'Β', + 'beth': 'ℶ', + 'between': '\u226C', + 'bfr': '\uD835\uDD1F', + 'Bfr': '\uD835\uDD05', + 'bigcap': '\u22C2', + 'bigcirc': '\u25EF', + 'bigcup': '\u22C3', + 'bigodot': '\u2A00', + 'bigoplus': '\u2A01', + 'bigotimes': '\u2A02', + 'bigsqcup': '\u2A06', + 'bigstar': '\u2605', + 'bigtriangledown': '\u25BD', + 'bigtriangleup': '\u25B3', + 'biguplus': '\u2A04', + 'bigvee': '\u22C1', + 'bigwedge': '\u22C0', + 'bkarow': '\u290D', + 'blacklozenge': '\u29EB', + 'blacksquare': '\u25AA', + 'blacktriangle': '\u25B4', + 'blacktriangledown': '\u25BE', + 'blacktriangleleft': '\u25C2', + 'blacktriangleright': '\u25B8', + 'blank': '\u2423', + 'blk12': '\u2592', + 'blk14': '\u2591', + 'blk34': '\u2593', + 'block': '\u2588', + 'bne': '=⃥', + 'bnequiv': '\u2261⃥', + 'bnot': '\u2310', + 'bNot': '\u2AED', + 'bopf': '\uD835\uDD53', + 'Bopf': '\uD835\uDD39', + 'bot': '\u22A5', + 'bottom': '\u22A5', + 'bowtie': '\u22C8', + 'boxbox': '\u29C9', + 'boxdl': '\u2510', + 'boxdL': '\u2555', + 'boxDl': '\u2556', + 'boxDL': '\u2557', + 'boxdr': '\u250C', + 'boxdR': '\u2552', + 'boxDr': '\u2553', + 'boxDR': '\u2554', + 'boxh': '\u2500', + 'boxH': '\u2550', + 'boxhd': '\u252C', + 'boxhD': '\u2565', + 'boxHd': '\u2564', + 'boxHD': '\u2566', + 'boxhu': '\u2534', + 'boxhU': '\u2568', + 'boxHu': '\u2567', + 'boxHU': '\u2569', + 'boxminus': '\u229F', + 'boxplus': '\u229E', + 'boxtimes': '\u22A0', + 'boxul': '\u2518', + 'boxuL': '\u255B', + 'boxUl': '\u255C', + 'boxUL': '\u255D', + 'boxur': '\u2514', + 'boxuR': '\u2558', + 'boxUr': '\u2559', + 'boxUR': '\u255A', + 'boxv': '\u2502', + 'boxV': '\u2551', + 'boxvh': '\u253C', + 'boxvH': '\u256A', + 'boxVh': '\u256B', + 'boxVH': '\u256C', + 'boxvl': '\u2524', + 'boxvL': '\u2561', + 'boxVl': '\u2562', + 'boxVL': '\u2563', + 'boxvr': '\u251C', + 'boxvR': '\u255E', + 'boxVr': '\u255F', + 'boxVR': '\u2560', + 'bprime': '\u2035', + 'breve': '\u02D8', + 'Breve': '\u02D8', + 'brvbar': '\xA6', + 'bscr': '\uD835\uDCB7', + 'Bscr': 'ℬ', + 'bsemi': '\u204F', + 'bsim': '\u223D', + 'bsime': '\u22CD', + 'bsol': '\\', + 'bsolb': '\u29C5', + 'bsolhsub': '\u27C8', + 'bull': '\u2022', + 'bullet': '\u2022', + 'bump': '\u224E', + 'bumpe': '\u224F', + 'bumpE': '\u2AAE', + 'bumpeq': '\u224F', + 'Bumpeq': '\u224E', + 'cacute': 'ć', + 'Cacute': 'Ć', + 'cap': '\u2229', + 'Cap': '\u22D2', + 'capand': '\u2A44', + 'capbrcup': '\u2A49', + 'capcap': '\u2A4B', + 'capcup': '\u2A47', + 'capdot': '\u2A40', + 'CapitalDifferentialD': 'ⅅ', + 'caps': '\u2229︀', + 'caret': '\u2041', + 'caron': 'ˇ', + 'Cayleys': 'ℭ', + 'ccaps': '\u2A4D', + 'ccaron': 'č', + 'Ccaron': 'Č', + 'ccedil': 'ç', + 'Ccedil': 'Ç', + 'ccirc': 'ĉ', + 'Ccirc': 'Ĉ', + 'Cconint': '\u2230', + 'ccups': '\u2A4C', + 'ccupssm': '\u2A50', + 'cdot': 'ċ', + 'Cdot': 'Ċ', + 'cedil': '\xB8', + 'Cedilla': '\xB8', + 'cemptyv': '\u29B2', + 'cent': '\xA2', + 'centerdot': '\xB7', + 'CenterDot': '\xB7', + 'cfr': '\uD835\uDD20', + 'Cfr': 'ℭ', + 'chcy': 'ч', + 'CHcy': 'Ч', + 'check': '\u2713', + 'checkmark': '\u2713', + 'chi': 'χ', + 'Chi': 'Χ', + 'cir': '\u25CB', + 'circ': 'ˆ', + 'circeq': '\u2257', + 'circlearrowleft': '\u21BA', + 'circlearrowright': '\u21BB', + 'circledast': '\u229B', + 'circledcirc': '\u229A', + 'circleddash': '\u229D', + 'CircleDot': '\u2299', + 'circledR': '\xAE', + 'circledS': '\u24C8', + 'CircleMinus': '\u2296', + 'CirclePlus': '\u2295', + 'CircleTimes': '\u2297', + 'cire': '\u2257', + 'cirE': '\u29C3', + 'cirfnint': '\u2A10', + 'cirmid': '\u2AEF', + 'cirscir': '\u29C2', + 'ClockwiseContourIntegral': '\u2232', + 'CloseCurlyDoubleQuote': '\u201D', + 'CloseCurlyQuote': '\u2019', + 'clubs': '\u2663', + 'clubsuit': '\u2663', + 'colon': ':', + 'Colon': '\u2237', + 'colone': '\u2254', + 'Colone': '\u2A74', + 'coloneq': '\u2254', + 'comma': ',', + 'commat': '@', + 'comp': '\u2201', + 'compfn': '\u2218', + 'complement': '\u2201', + 'complexes': 'ℂ', + 'cong': '\u2245', + 'congdot': '\u2A6D', + 'Congruent': '\u2261', + 'conint': '\u222E', + 'Conint': '\u222F', + 'ContourIntegral': '\u222E', + 'copf': '\uD835\uDD54', + 'Copf': 'ℂ', + 'coprod': '\u2210', + 'Coproduct': '\u2210', + 'copy': '\xA9', + 'COPY': '\xA9', + 'copysr': '\u2117', + 'CounterClockwiseContourIntegral': '\u2233', + 'crarr': '\u21B5', + 'cross': '\u2717', + 'Cross': '\u2A2F', + 'cscr': '\uD835\uDCB8', + 'Cscr': '\uD835\uDC9E', + 'csub': '\u2ACF', + 'csube': '\u2AD1', + 'csup': '\u2AD0', + 'csupe': '\u2AD2', + 'ctdot': '\u22EF', + 'cudarrl': '\u2938', + 'cudarrr': '\u2935', + 'cuepr': '\u22DE', + 'cuesc': '\u22DF', + 'cularr': '\u21B6', + 'cularrp': '\u293D', + 'cup': '\u222A', + 'Cup': '\u22D3', + 'cupbrcap': '\u2A48', + 'cupcap': '\u2A46', + 'CupCap': '\u224D', + 'cupcup': '\u2A4A', + 'cupdot': '\u228D', + 'cupor': '\u2A45', + 'cups': '\u222A︀', + 'curarr': '\u21B7', + 'curarrm': '\u293C', + 'curlyeqprec': '\u22DE', + 'curlyeqsucc': '\u22DF', + 'curlyvee': '\u22CE', + 'curlywedge': '\u22CF', + 'curren': '\xA4', + 'curvearrowleft': '\u21B6', + 'curvearrowright': '\u21B7', + 'cuvee': '\u22CE', + 'cuwed': '\u22CF', + 'cwconint': '\u2232', + 'cwint': '\u2231', + 'cylcty': '\u232D', + 'dagger': '\u2020', + 'Dagger': '\u2021', + 'daleth': 'ℸ', + 'darr': '\u2193', + 'dArr': '\u21D3', + 'Darr': '\u21A1', + 'dash': '\u2010', + 'dashv': '\u22A3', + 'Dashv': '\u2AE4', + 'dbkarow': '\u290F', + 'dblac': '\u02DD', + 'dcaron': 'ď', + 'Dcaron': 'Ď', + 'dcy': 'д', + 'Dcy': 'Д', + 'dd': 'ⅆ', + 'DD': 'ⅅ', + 'ddagger': '\u2021', + 'ddarr': '\u21CA', + 'DDotrahd': '\u2911', + 'ddotseq': '\u2A77', + 'deg': '\xB0', + 'Del': '\u2207', + 'delta': 'δ', + 'Delta': 'Δ', + 'demptyv': '\u29B1', + 'dfisht': '\u297F', + 'dfr': '\uD835\uDD21', + 'Dfr': '\uD835\uDD07', + 'dHar': '\u2965', + 'dharl': '\u21C3', + 'dharr': '\u21C2', + 'DiacriticalAcute': '\xB4', + 'DiacriticalDot': '\u02D9', + 'DiacriticalDoubleAcute': '\u02DD', + 'DiacriticalGrave': '`', + 'DiacriticalTilde': '\u02DC', + 'diam': '\u22C4', + 'diamond': '\u22C4', + 'Diamond': '\u22C4', + 'diamondsuit': '\u2666', + 'diams': '\u2666', + 'die': '\xA8', + 'DifferentialD': 'ⅆ', + 'digamma': 'ϝ', + 'disin': '\u22F2', + 'div': '\xF7', + 'divide': '\xF7', + 'divideontimes': '\u22C7', + 'divonx': '\u22C7', + 'djcy': 'ђ', + 'DJcy': 'Ђ', + 'dlcorn': '\u231E', + 'dlcrop': '\u230D', + 'dollar': '$', + 'dopf': '\uD835\uDD55', + 'Dopf': '\uD835\uDD3B', + 'dot': '\u02D9', + 'Dot': '\xA8', + 'DotDot': '⃜', + 'doteq': '\u2250', + 'doteqdot': '\u2251', + 'DotEqual': '\u2250', + 'dotminus': '\u2238', + 'dotplus': '\u2214', + 'dotsquare': '\u22A1', + 'doublebarwedge': '\u2306', + 'DoubleContourIntegral': '\u222F', + 'DoubleDot': '\xA8', + 'DoubleDownArrow': '\u21D3', + 'DoubleLeftArrow': '\u21D0', + 'DoubleLeftRightArrow': '\u21D4', + 'DoubleLeftTee': '\u2AE4', + 'DoubleLongLeftArrow': '\u27F8', + 'DoubleLongLeftRightArrow': '\u27FA', + 'DoubleLongRightArrow': '\u27F9', + 'DoubleRightArrow': '\u21D2', + 'DoubleRightTee': '\u22A8', + 'DoubleUpArrow': '\u21D1', + 'DoubleUpDownArrow': '\u21D5', + 'DoubleVerticalBar': '\u2225', + 'downarrow': '\u2193', + 'Downarrow': '\u21D3', + 'DownArrow': '\u2193', + 'DownArrowBar': '\u2913', + 'DownArrowUpArrow': '\u21F5', + 'DownBreve': '̑', + 'downdownarrows': '\u21CA', + 'downharpoonleft': '\u21C3', + 'downharpoonright': '\u21C2', + 'DownLeftRightVector': '\u2950', + 'DownLeftTeeVector': '\u295E', + 'DownLeftVector': '\u21BD', + 'DownLeftVectorBar': '\u2956', + 'DownRightTeeVector': '\u295F', + 'DownRightVector': '\u21C1', + 'DownRightVectorBar': '\u2957', + 'DownTee': '\u22A4', + 'DownTeeArrow': '\u21A7', + 'drbkarow': '\u2910', + 'drcorn': '\u231F', + 'drcrop': '\u230C', + 'dscr': '\uD835\uDCB9', + 'Dscr': '\uD835\uDC9F', + 'dscy': 'ѕ', + 'DScy': 'Ѕ', + 'dsol': '\u29F6', + 'dstrok': 'đ', + 'Dstrok': 'Đ', + 'dtdot': '\u22F1', + 'dtri': '\u25BF', + 'dtrif': '\u25BE', + 'duarr': '\u21F5', + 'duhar': '\u296F', + 'dwangle': '\u29A6', + 'dzcy': 'џ', + 'DZcy': 'Џ', + 'dzigrarr': '\u27FF', + 'eacute': 'é', + 'Eacute': 'É', + 'easter': '\u2A6E', + 'ecaron': 'ě', + 'Ecaron': 'Ě', + 'ecir': '\u2256', + 'ecirc': 'ê', + 'Ecirc': 'Ê', + 'ecolon': '\u2255', + 'ecy': 'э', + 'Ecy': 'Э', + 'eDDot': '\u2A77', + 'edot': 'ė', + 'eDot': '\u2251', + 'Edot': 'Ė', + 'ee': 'ⅇ', + 'efDot': '\u2252', + 'efr': '\uD835\uDD22', + 'Efr': '\uD835\uDD08', + 'eg': '\u2A9A', + 'egrave': 'è', + 'Egrave': 'È', + 'egs': '\u2A96', + 'egsdot': '\u2A98', + 'el': '\u2A99', + 'Element': '\u2208', + 'elinters': '\u23E7', + 'ell': 'ℓ', + 'els': '\u2A95', + 'elsdot': '\u2A97', + 'emacr': 'ē', + 'Emacr': 'Ē', + 'empty': '\u2205', + 'emptyset': '\u2205', + 'EmptySmallSquare': '\u25FB', + 'emptyv': '\u2205', + 'EmptyVerySmallSquare': '\u25AB', + 'emsp': '\u2003', + 'emsp13': '\u2004', + 'emsp14': '\u2005', + 'eng': 'ŋ', + 'ENG': 'Ŋ', + 'ensp': '\u2002', + 'eogon': 'ę', + 'Eogon': 'Ę', + 'eopf': '\uD835\uDD56', + 'Eopf': '\uD835\uDD3C', + 'epar': '\u22D5', + 'eparsl': '\u29E3', + 'eplus': '\u2A71', + 'epsi': 'ε', + 'epsilon': 'ε', + 'Epsilon': 'Ε', + 'epsiv': 'ϵ', + 'eqcirc': '\u2256', + 'eqcolon': '\u2255', + 'eqsim': '\u2242', + 'eqslantgtr': '\u2A96', + 'eqslantless': '\u2A95', + 'Equal': '\u2A75', + 'equals': '=', + 'EqualTilde': '\u2242', + 'equest': '\u225F', + 'Equilibrium': '\u21CC', + 'equiv': '\u2261', + 'equivDD': '\u2A78', + 'eqvparsl': '\u29E5', + 'erarr': '\u2971', + 'erDot': '\u2253', + 'escr': 'ℯ', + 'Escr': 'ℰ', + 'esdot': '\u2250', + 'esim': '\u2242', + 'Esim': '\u2A73', + 'eta': 'η', + 'Eta': 'Η', + 'eth': 'ð', + 'ETH': 'Ð', + 'euml': 'ë', + 'Euml': 'Ë', + 'euro': '\u20AC', + 'excl': '!', + 'exist': '\u2203', + 'Exists': '\u2203', + 'expectation': 'ℰ', + 'exponentiale': 'ⅇ', + 'ExponentialE': 'ⅇ', + 'fallingdotseq': '\u2252', + 'fcy': 'ф', + 'Fcy': 'Ф', + 'female': '\u2640', + 'ffilig': 'ffi', + 'fflig': 'ff', + 'ffllig': 'ffl', + 'ffr': '\uD835\uDD23', + 'Ffr': '\uD835\uDD09', + 'filig': 'fi', + 'FilledSmallSquare': '\u25FC', + 'FilledVerySmallSquare': '\u25AA', + 'fjlig': 'fj', + 'flat': '\u266D', + 'fllig': 'fl', + 'fltns': '\u25B1', + 'fnof': 'ƒ', + 'fopf': '\uD835\uDD57', + 'Fopf': '\uD835\uDD3D', + 'forall': '\u2200', + 'ForAll': '\u2200', + 'fork': '\u22D4', + 'forkv': '\u2AD9', + 'Fouriertrf': 'ℱ', + 'fpartint': '\u2A0D', + 'frac12': '\xBD', + 'frac13': '\u2153', + 'frac14': '\xBC', + 'frac15': '\u2155', + 'frac16': '\u2159', + 'frac18': '\u215B', + 'frac23': '\u2154', + 'frac25': '\u2156', + 'frac34': '\xBE', + 'frac35': '\u2157', + 'frac38': '\u215C', + 'frac45': '\u2158', + 'frac56': '\u215A', + 'frac58': '\u215D', + 'frac78': '\u215E', + 'frasl': '\u2044', + 'frown': '\u2322', + 'fscr': '\uD835\uDCBB', + 'Fscr': 'ℱ', + 'gacute': 'ǵ', + 'gamma': 'γ', + 'Gamma': 'Γ', + 'gammad': 'ϝ', + 'Gammad': 'Ϝ', + 'gap': '\u2A86', + 'gbreve': 'ğ', + 'Gbreve': 'Ğ', + 'Gcedil': 'Ģ', + 'gcirc': 'ĝ', + 'Gcirc': 'Ĝ', + 'gcy': 'г', + 'Gcy': 'Г', + 'gdot': 'ġ', + 'Gdot': 'Ġ', + 'ge': '\u2265', + 'gE': '\u2267', + 'gel': '\u22DB', + 'gEl': '\u2A8C', + 'geq': '\u2265', + 'geqq': '\u2267', + 'geqslant': '\u2A7E', + 'ges': '\u2A7E', + 'gescc': '\u2AA9', + 'gesdot': '\u2A80', + 'gesdoto': '\u2A82', + 'gesdotol': '\u2A84', + 'gesl': '\u22DB︀', + 'gesles': '\u2A94', + 'gfr': '\uD835\uDD24', + 'Gfr': '\uD835\uDD0A', + 'gg': '\u226B', + 'Gg': '\u22D9', + 'ggg': '\u22D9', + 'gimel': 'ℷ', + 'gjcy': 'ѓ', + 'GJcy': 'Ѓ', + 'gl': '\u2277', + 'gla': '\u2AA5', + 'glE': '\u2A92', + 'glj': '\u2AA4', + 'gnap': '\u2A8A', + 'gnapprox': '\u2A8A', + 'gne': '\u2A88', + 'gnE': '\u2269', + 'gneq': '\u2A88', + 'gneqq': '\u2269', + 'gnsim': '\u22E7', + 'gopf': '\uD835\uDD58', + 'Gopf': '\uD835\uDD3E', + 'grave': '`', + 'GreaterEqual': '\u2265', + 'GreaterEqualLess': '\u22DB', + 'GreaterFullEqual': '\u2267', + 'GreaterGreater': '\u2AA2', + 'GreaterLess': '\u2277', + 'GreaterSlantEqual': '\u2A7E', + 'GreaterTilde': '\u2273', + 'gscr': 'ℊ', + 'Gscr': '\uD835\uDCA2', + 'gsim': '\u2273', + 'gsime': '\u2A8E', + 'gsiml': '\u2A90', + 'gt': '>', + 'Gt': '\u226B', + 'GT': '>', + 'gtcc': '\u2AA7', + 'gtcir': '\u2A7A', + 'gtdot': '\u22D7', + 'gtlPar': '\u2995', + 'gtquest': '\u2A7C', + 'gtrapprox': '\u2A86', + 'gtrarr': '\u2978', + 'gtrdot': '\u22D7', + 'gtreqless': '\u22DB', + 'gtreqqless': '\u2A8C', + 'gtrless': '\u2277', + 'gtrsim': '\u2273', + 'gvertneqq': '\u2269︀', + 'gvnE': '\u2269︀', + 'Hacek': 'ˇ', + 'hairsp': '\u200A', + 'half': '\xBD', + 'hamilt': 'ℋ', + 'hardcy': 'ъ', + 'HARDcy': 'Ъ', + 'harr': '\u2194', + 'hArr': '\u21D4', + 'harrcir': '\u2948', + 'harrw': '\u21AD', + 'Hat': '^', + 'hbar': 'ℏ', + 'hcirc': 'ĥ', + 'Hcirc': 'Ĥ', + 'hearts': '\u2665', + 'heartsuit': '\u2665', + 'hellip': '\u2026', + 'hercon': '\u22B9', + 'hfr': '\uD835\uDD25', + 'Hfr': 'ℌ', + 'HilbertSpace': 'ℋ', + 'hksearow': '\u2925', + 'hkswarow': '\u2926', + 'hoarr': '\u21FF', + 'homtht': '\u223B', + 'hookleftarrow': '\u21A9', + 'hookrightarrow': '\u21AA', + 'hopf': '\uD835\uDD59', + 'Hopf': 'ℍ', + 'horbar': '\u2015', + 'HorizontalLine': '\u2500', + 'hscr': '\uD835\uDCBD', + 'Hscr': 'ℋ', + 'hslash': 'ℏ', + 'hstrok': 'ħ', + 'Hstrok': 'Ħ', + 'HumpDownHump': '\u224E', + 'HumpEqual': '\u224F', + 'hybull': '\u2043', + 'hyphen': '\u2010', + 'iacute': 'í', + 'Iacute': 'Í', + 'ic': '\u2063', + 'icirc': 'î', + 'Icirc': 'Î', + 'icy': 'и', + 'Icy': 'И', + 'Idot': 'İ', + 'iecy': 'е', + 'IEcy': 'Е', + 'iexcl': '\xA1', + 'iff': '\u21D4', + 'ifr': '\uD835\uDD26', + 'Ifr': 'ℑ', + 'igrave': 'ì', + 'Igrave': 'Ì', + 'ii': 'ⅈ', + 'iiiint': '\u2A0C', + 'iiint': '\u222D', + 'iinfin': '\u29DC', + 'iiota': '\u2129', + 'ijlig': 'ij', + 'IJlig': 'IJ', + 'Im': 'ℑ', + 'imacr': 'ī', + 'Imacr': 'Ī', + 'image': 'ℑ', + 'ImaginaryI': 'ⅈ', + 'imagline': 'ℐ', + 'imagpart': 'ℑ', + 'imath': 'ı', + 'imof': '\u22B7', + 'imped': 'Ƶ', + 'Implies': '\u21D2', + 'in': '\u2208', + 'incare': '\u2105', + 'infin': '\u221E', + 'infintie': '\u29DD', + 'inodot': 'ı', + 'int': '\u222B', + 'Int': '\u222C', + 'intcal': '\u22BA', + 'integers': 'ℤ', + 'Integral': '\u222B', + 'intercal': '\u22BA', + 'Intersection': '\u22C2', + 'intlarhk': '\u2A17', + 'intprod': '\u2A3C', + 'InvisibleComma': '\u2063', + 'InvisibleTimes': '\u2062', + 'iocy': 'ё', + 'IOcy': 'Ё', + 'iogon': 'į', + 'Iogon': 'Į', + 'iopf': '\uD835\uDD5A', + 'Iopf': '\uD835\uDD40', + 'iota': 'ι', + 'Iota': 'Ι', + 'iprod': '\u2A3C', + 'iquest': '\xBF', + 'iscr': '\uD835\uDCBE', + 'Iscr': 'ℐ', + 'isin': '\u2208', + 'isindot': '\u22F5', + 'isinE': '\u22F9', + 'isins': '\u22F4', + 'isinsv': '\u22F3', + 'isinv': '\u2208', + 'it': '\u2062', + 'itilde': 'ĩ', + 'Itilde': 'Ĩ', + 'iukcy': 'і', + 'Iukcy': 'І', + 'iuml': 'ï', + 'Iuml': 'Ï', + 'jcirc': 'ĵ', + 'Jcirc': 'Ĵ', + 'jcy': 'й', + 'Jcy': 'Й', + 'jfr': '\uD835\uDD27', + 'Jfr': '\uD835\uDD0D', + 'jmath': 'ȷ', + 'jopf': '\uD835\uDD5B', + 'Jopf': '\uD835\uDD41', + 'jscr': '\uD835\uDCBF', + 'Jscr': '\uD835\uDCA5', + 'jsercy': 'ј', + 'Jsercy': 'Ј', + 'jukcy': 'є', + 'Jukcy': 'Є', + 'kappa': 'κ', + 'Kappa': 'Κ', + 'kappav': 'ϰ', + 'kcedil': 'ķ', + 'Kcedil': 'Ķ', + 'kcy': 'к', + 'Kcy': 'К', + 'kfr': '\uD835\uDD28', + 'Kfr': '\uD835\uDD0E', + 'kgreen': 'ĸ', + 'khcy': 'х', + 'KHcy': 'Х', + 'kjcy': 'ќ', + 'KJcy': 'Ќ', + 'kopf': '\uD835\uDD5C', + 'Kopf': '\uD835\uDD42', + 'kscr': '\uD835\uDCC0', + 'Kscr': '\uD835\uDCA6', + 'lAarr': '\u21DA', + 'lacute': 'ĺ', + 'Lacute': 'Ĺ', + 'laemptyv': '\u29B4', + 'lagran': 'ℒ', + 'lambda': 'λ', + 'Lambda': 'Λ', + 'lang': '\u27E8', + 'Lang': '\u27EA', + 'langd': '\u2991', + 'langle': '\u27E8', + 'lap': '\u2A85', + 'Laplacetrf': 'ℒ', + 'laquo': '\xAB', + 'larr': '\u2190', + 'lArr': '\u21D0', + 'Larr': '\u219E', + 'larrb': '\u21E4', + 'larrbfs': '\u291F', + 'larrfs': '\u291D', + 'larrhk': '\u21A9', + 'larrlp': '\u21AB', + 'larrpl': '\u2939', + 'larrsim': '\u2973', + 'larrtl': '\u21A2', + 'lat': '\u2AAB', + 'latail': '\u2919', + 'lAtail': '\u291B', + 'late': '\u2AAD', + 'lates': '\u2AAD︀', + 'lbarr': '\u290C', + 'lBarr': '\u290E', + 'lbbrk': '\u2772', + 'lbrace': '{', + 'lbrack': '[', + 'lbrke': '\u298B', + 'lbrksld': '\u298F', + 'lbrkslu': '\u298D', + 'lcaron': 'ľ', + 'Lcaron': 'Ľ', + 'lcedil': 'ļ', + 'Lcedil': 'Ļ', + 'lceil': '\u2308', + 'lcub': '{', + 'lcy': 'л', + 'Lcy': 'Л', + 'ldca': '\u2936', + 'ldquo': '\u201C', + 'ldquor': '\u201E', + 'ldrdhar': '\u2967', + 'ldrushar': '\u294B', + 'ldsh': '\u21B2', + 'le': '\u2264', + 'lE': '\u2266', + 'LeftAngleBracket': '\u27E8', + 'leftarrow': '\u2190', + 'Leftarrow': '\u21D0', + 'LeftArrow': '\u2190', + 'LeftArrowBar': '\u21E4', + 'LeftArrowRightArrow': '\u21C6', + 'leftarrowtail': '\u21A2', + 'LeftCeiling': '\u2308', + 'LeftDoubleBracket': '\u27E6', + 'LeftDownTeeVector': '\u2961', + 'LeftDownVector': '\u21C3', + 'LeftDownVectorBar': '\u2959', + 'LeftFloor': '\u230A', + 'leftharpoondown': '\u21BD', + 'leftharpoonup': '\u21BC', + 'leftleftarrows': '\u21C7', + 'leftrightarrow': '\u2194', + 'Leftrightarrow': '\u21D4', + 'LeftRightArrow': '\u2194', + 'leftrightarrows': '\u21C6', + 'leftrightharpoons': '\u21CB', + 'leftrightsquigarrow': '\u21AD', + 'LeftRightVector': '\u294E', + 'LeftTee': '\u22A3', + 'LeftTeeArrow': '\u21A4', + 'LeftTeeVector': '\u295A', + 'leftthreetimes': '\u22CB', + 'LeftTriangle': '\u22B2', + 'LeftTriangleBar': '\u29CF', + 'LeftTriangleEqual': '\u22B4', + 'LeftUpDownVector': '\u2951', + 'LeftUpTeeVector': '\u2960', + 'LeftUpVector': '\u21BF', + 'LeftUpVectorBar': '\u2958', + 'LeftVector': '\u21BC', + 'LeftVectorBar': '\u2952', + 'leg': '\u22DA', + 'lEg': '\u2A8B', + 'leq': '\u2264', + 'leqq': '\u2266', + 'leqslant': '\u2A7D', + 'les': '\u2A7D', + 'lescc': '\u2AA8', + 'lesdot': '\u2A7F', + 'lesdoto': '\u2A81', + 'lesdotor': '\u2A83', + 'lesg': '\u22DA︀', + 'lesges': '\u2A93', + 'lessapprox': '\u2A85', + 'lessdot': '\u22D6', + 'lesseqgtr': '\u22DA', + 'lesseqqgtr': '\u2A8B', + 'LessEqualGreater': '\u22DA', + 'LessFullEqual': '\u2266', + 'LessGreater': '\u2276', + 'lessgtr': '\u2276', + 'LessLess': '\u2AA1', + 'lesssim': '\u2272', + 'LessSlantEqual': '\u2A7D', + 'LessTilde': '\u2272', + 'lfisht': '\u297C', + 'lfloor': '\u230A', + 'lfr': '\uD835\uDD29', + 'Lfr': '\uD835\uDD0F', + 'lg': '\u2276', + 'lgE': '\u2A91', + 'lHar': '\u2962', + 'lhard': '\u21BD', + 'lharu': '\u21BC', + 'lharul': '\u296A', + 'lhblk': '\u2584', + 'ljcy': 'љ', + 'LJcy': 'Љ', + 'll': '\u226A', + 'Ll': '\u22D8', + 'llarr': '\u21C7', + 'llcorner': '\u231E', + 'Lleftarrow': '\u21DA', + 'llhard': '\u296B', + 'lltri': '\u25FA', + 'lmidot': 'ŀ', + 'Lmidot': 'Ŀ', + 'lmoust': '\u23B0', + 'lmoustache': '\u23B0', + 'lnap': '\u2A89', + 'lnapprox': '\u2A89', + 'lne': '\u2A87', + 'lnE': '\u2268', + 'lneq': '\u2A87', + 'lneqq': '\u2268', + 'lnsim': '\u22E6', + 'loang': '\u27EC', + 'loarr': '\u21FD', + 'lobrk': '\u27E6', + 'longleftarrow': '\u27F5', + 'Longleftarrow': '\u27F8', + 'LongLeftArrow': '\u27F5', + 'longleftrightarrow': '\u27F7', + 'Longleftrightarrow': '\u27FA', + 'LongLeftRightArrow': '\u27F7', + 'longmapsto': '\u27FC', + 'longrightarrow': '\u27F6', + 'Longrightarrow': '\u27F9', + 'LongRightArrow': '\u27F6', + 'looparrowleft': '\u21AB', + 'looparrowright': '\u21AC', + 'lopar': '\u2985', + 'lopf': '\uD835\uDD5D', + 'Lopf': '\uD835\uDD43', + 'loplus': '\u2A2D', + 'lotimes': '\u2A34', + 'lowast': '\u2217', + 'lowbar': '_', + 'LowerLeftArrow': '\u2199', + 'LowerRightArrow': '\u2198', + 'loz': '\u25CA', + 'lozenge': '\u25CA', + 'lozf': '\u29EB', + 'lpar': '(', + 'lparlt': '\u2993', + 'lrarr': '\u21C6', + 'lrcorner': '\u231F', + 'lrhar': '\u21CB', + 'lrhard': '\u296D', + 'lrm': '\u200E', + 'lrtri': '\u22BF', + 'lsaquo': '\u2039', + 'lscr': '\uD835\uDCC1', + 'Lscr': 'ℒ', + 'lsh': '\u21B0', + 'Lsh': '\u21B0', + 'lsim': '\u2272', + 'lsime': '\u2A8D', + 'lsimg': '\u2A8F', + 'lsqb': '[', + 'lsquo': '\u2018', + 'lsquor': '\u201A', + 'lstrok': 'ł', + 'Lstrok': 'Ł', + 'lt': '<', + 'Lt': '\u226A', + 'LT': '<', + 'ltcc': '\u2AA6', + 'ltcir': '\u2A79', + 'ltdot': '\u22D6', + 'lthree': '\u22CB', + 'ltimes': '\u22C9', + 'ltlarr': '\u2976', + 'ltquest': '\u2A7B', + 'ltri': '\u25C3', + 'ltrie': '\u22B4', + 'ltrif': '\u25C2', + 'ltrPar': '\u2996', + 'lurdshar': '\u294A', + 'luruhar': '\u2966', + 'lvertneqq': '\u2268︀', + 'lvnE': '\u2268︀', + 'macr': '\xAF', + 'male': '\u2642', + 'malt': '\u2720', + 'maltese': '\u2720', + 'map': '\u21A6', + 'Map': '\u2905', + 'mapsto': '\u21A6', + 'mapstodown': '\u21A7', + 'mapstoleft': '\u21A4', + 'mapstoup': '\u21A5', + 'marker': '\u25AE', + 'mcomma': '\u2A29', + 'mcy': 'м', + 'Mcy': 'М', + 'mdash': '\u2014', + 'mDDot': '\u223A', + 'measuredangle': '\u2221', + 'MediumSpace': '\u205F', + 'Mellintrf': 'ℳ', + 'mfr': '\uD835\uDD2A', + 'Mfr': '\uD835\uDD10', + 'mho': '\u2127', + 'micro': 'µ', + 'mid': '\u2223', + 'midast': '*', + 'midcir': '\u2AF0', + 'middot': '\xB7', + 'minus': '\u2212', + 'minusb': '\u229F', + 'minusd': '\u2238', + 'minusdu': '\u2A2A', + 'MinusPlus': '\u2213', + 'mlcp': '\u2ADB', + 'mldr': '\u2026', + 'mnplus': '\u2213', + 'models': '\u22A7', + 'mopf': '\uD835\uDD5E', + 'Mopf': '\uD835\uDD44', + 'mp': '\u2213', + 'mscr': '\uD835\uDCC2', + 'Mscr': 'ℳ', + 'mstpos': '\u223E', + 'mu': 'μ', + 'Mu': 'Μ', + 'multimap': '\u22B8', + 'mumap': '\u22B8', + 'nabla': '\u2207', + 'nacute': 'ń', + 'Nacute': 'Ń', + 'nang': '\u2220⃒', + 'nap': '\u2249', + 'napE': '\u2A70̸', + 'napid': '\u224B̸', + 'napos': 'ʼn', + 'napprox': '\u2249', + 'natur': '\u266E', + 'natural': '\u266E', + 'naturals': 'ℕ', + 'nbsp': '\xA0', + 'nbump': '\u224E̸', + 'nbumpe': '\u224F̸', + 'ncap': '\u2A43', + 'ncaron': 'ň', + 'Ncaron': 'Ň', + 'ncedil': 'ņ', + 'Ncedil': 'Ņ', + 'ncong': '\u2247', + 'ncongdot': '\u2A6D̸', + 'ncup': '\u2A42', + 'ncy': 'н', + 'Ncy': 'Н', + 'ndash': '\u2013', + 'ne': '\u2260', + 'nearhk': '\u2924', + 'nearr': '\u2197', + 'neArr': '\u21D7', + 'nearrow': '\u2197', + 'nedot': '\u2250̸', + 'NegativeMediumSpace': '\u200B', + 'NegativeThickSpace': '\u200B', + 'NegativeThinSpace': '\u200B', + 'NegativeVeryThinSpace': '\u200B', + 'nequiv': '\u2262', + 'nesear': '\u2928', + 'nesim': '\u2242̸', + 'NestedGreaterGreater': '\u226B', + 'NestedLessLess': '\u226A', + 'NewLine': '\n', + 'nexist': '\u2204', + 'nexists': '\u2204', + 'nfr': '\uD835\uDD2B', + 'Nfr': '\uD835\uDD11', + 'nge': '\u2271', + 'ngE': '\u2267̸', + 'ngeq': '\u2271', + 'ngeqq': '\u2267̸', + 'ngeqslant': '\u2A7E̸', + 'nges': '\u2A7E̸', + 'nGg': '\u22D9̸', + 'ngsim': '\u2275', + 'ngt': '\u226F', + 'nGt': '\u226B⃒', + 'ngtr': '\u226F', + 'nGtv': '\u226B̸', + 'nharr': '\u21AE', + 'nhArr': '\u21CE', + 'nhpar': '\u2AF2', + 'ni': '\u220B', + 'nis': '\u22FC', + 'nisd': '\u22FA', + 'niv': '\u220B', + 'njcy': 'њ', + 'NJcy': 'Њ', + 'nlarr': '\u219A', + 'nlArr': '\u21CD', + 'nldr': '\u2025', + 'nle': '\u2270', + 'nlE': '\u2266̸', + 'nleftarrow': '\u219A', + 'nLeftarrow': '\u21CD', + 'nleftrightarrow': '\u21AE', + 'nLeftrightarrow': '\u21CE', + 'nleq': '\u2270', + 'nleqq': '\u2266̸', + 'nleqslant': '\u2A7D̸', + 'nles': '\u2A7D̸', + 'nless': '\u226E', + 'nLl': '\u22D8̸', + 'nlsim': '\u2274', + 'nlt': '\u226E', + 'nLt': '\u226A⃒', + 'nltri': '\u22EA', + 'nltrie': '\u22EC', + 'nLtv': '\u226A̸', + 'nmid': '\u2224', + 'NoBreak': '\u2060', + 'NonBreakingSpace': '\xA0', + 'nopf': '\uD835\uDD5F', + 'Nopf': 'ℕ', + 'not': '\xAC', + 'Not': '\u2AEC', + 'NotCongruent': '\u2262', + 'NotCupCap': '\u226D', + 'NotDoubleVerticalBar': '\u2226', + 'NotElement': '\u2209', + 'NotEqual': '\u2260', + 'NotEqualTilde': '\u2242̸', + 'NotExists': '\u2204', + 'NotGreater': '\u226F', + 'NotGreaterEqual': '\u2271', + 'NotGreaterFullEqual': '\u2267̸', + 'NotGreaterGreater': '\u226B̸', + 'NotGreaterLess': '\u2279', + 'NotGreaterSlantEqual': '\u2A7E̸', + 'NotGreaterTilde': '\u2275', + 'NotHumpDownHump': '\u224E̸', + 'NotHumpEqual': '\u224F̸', + 'notin': '\u2209', + 'notindot': '\u22F5̸', + 'notinE': '\u22F9̸', + 'notinva': '\u2209', + 'notinvb': '\u22F7', + 'notinvc': '\u22F6', + 'NotLeftTriangle': '\u22EA', + 'NotLeftTriangleBar': '\u29CF̸', + 'NotLeftTriangleEqual': '\u22EC', + 'NotLess': '\u226E', + 'NotLessEqual': '\u2270', + 'NotLessGreater': '\u2278', + 'NotLessLess': '\u226A̸', + 'NotLessSlantEqual': '\u2A7D̸', + 'NotLessTilde': '\u2274', + 'NotNestedGreaterGreater': '\u2AA2̸', + 'NotNestedLessLess': '\u2AA1̸', + 'notni': '\u220C', + 'notniva': '\u220C', + 'notnivb': '\u22FE', + 'notnivc': '\u22FD', + 'NotPrecedes': '\u2280', + 'NotPrecedesEqual': '\u2AAF̸', + 'NotPrecedesSlantEqual': '\u22E0', + 'NotReverseElement': '\u220C', + 'NotRightTriangle': '\u22EB', + 'NotRightTriangleBar': '\u29D0̸', + 'NotRightTriangleEqual': '\u22ED', + 'NotSquareSubset': '\u228F̸', + 'NotSquareSubsetEqual': '\u22E2', + 'NotSquareSuperset': '\u2290̸', + 'NotSquareSupersetEqual': '\u22E3', + 'NotSubset': '\u2282⃒', + 'NotSubsetEqual': '\u2288', + 'NotSucceeds': '\u2281', + 'NotSucceedsEqual': '\u2AB0̸', + 'NotSucceedsSlantEqual': '\u22E1', + 'NotSucceedsTilde': '\u227F̸', + 'NotSuperset': '\u2283⃒', + 'NotSupersetEqual': '\u2289', + 'NotTilde': '\u2241', + 'NotTildeEqual': '\u2244', + 'NotTildeFullEqual': '\u2247', + 'NotTildeTilde': '\u2249', + 'NotVerticalBar': '\u2224', + 'npar': '\u2226', + 'nparallel': '\u2226', + 'nparsl': '\u2AFD⃥', + 'npart': '\u2202̸', + 'npolint': '\u2A14', + 'npr': '\u2280', + 'nprcue': '\u22E0', + 'npre': '\u2AAF̸', + 'nprec': '\u2280', + 'npreceq': '\u2AAF̸', + 'nrarr': '\u219B', + 'nrArr': '\u21CF', + 'nrarrc': '\u2933̸', + 'nrarrw': '\u219D̸', + 'nrightarrow': '\u219B', + 'nRightarrow': '\u21CF', + 'nrtri': '\u22EB', + 'nrtrie': '\u22ED', + 'nsc': '\u2281', + 'nsccue': '\u22E1', + 'nsce': '\u2AB0̸', + 'nscr': '\uD835\uDCC3', + 'Nscr': '\uD835\uDCA9', + 'nshortmid': '\u2224', + 'nshortparallel': '\u2226', + 'nsim': '\u2241', + 'nsime': '\u2244', + 'nsimeq': '\u2244', + 'nsmid': '\u2224', + 'nspar': '\u2226', + 'nsqsube': '\u22E2', + 'nsqsupe': '\u22E3', + 'nsub': '\u2284', + 'nsube': '\u2288', + 'nsubE': '\u2AC5̸', + 'nsubset': '\u2282⃒', + 'nsubseteq': '\u2288', + 'nsubseteqq': '\u2AC5̸', + 'nsucc': '\u2281', + 'nsucceq': '\u2AB0̸', + 'nsup': '\u2285', + 'nsupe': '\u2289', + 'nsupE': '\u2AC6̸', + 'nsupset': '\u2283⃒', + 'nsupseteq': '\u2289', + 'nsupseteqq': '\u2AC6̸', + 'ntgl': '\u2279', + 'ntilde': 'ñ', + 'Ntilde': 'Ñ', + 'ntlg': '\u2278', + 'ntriangleleft': '\u22EA', + 'ntrianglelefteq': '\u22EC', + 'ntriangleright': '\u22EB', + 'ntrianglerighteq': '\u22ED', + 'nu': 'ν', + 'Nu': 'Ν', + 'num': '#', + 'numero': '\u2116', + 'numsp': '\u2007', + 'nvap': '\u224D⃒', + 'nvdash': '\u22AC', + 'nvDash': '\u22AD', + 'nVdash': '\u22AE', + 'nVDash': '\u22AF', + 'nvge': '\u2265⃒', + 'nvgt': '>⃒', + 'nvHarr': '\u2904', + 'nvinfin': '\u29DE', + 'nvlArr': '\u2902', + 'nvle': '\u2264⃒', + 'nvlt': '<⃒', + 'nvltrie': '\u22B4⃒', + 'nvrArr': '\u2903', + 'nvrtrie': '\u22B5⃒', + 'nvsim': '\u223C⃒', + 'nwarhk': '\u2923', + 'nwarr': '\u2196', + 'nwArr': '\u21D6', + 'nwarrow': '\u2196', + 'nwnear': '\u2927', + 'oacute': 'ó', + 'Oacute': 'Ó', + 'oast': '\u229B', + 'ocir': '\u229A', + 'ocirc': 'ô', + 'Ocirc': 'Ô', + 'ocy': 'о', + 'Ocy': 'О', + 'odash': '\u229D', + 'odblac': 'ő', + 'Odblac': 'Ő', + 'odiv': '\u2A38', + 'odot': '\u2299', + 'odsold': '\u29BC', + 'oelig': 'œ', + 'OElig': 'Œ', + 'ofcir': '\u29BF', + 'ofr': '\uD835\uDD2C', + 'Ofr': '\uD835\uDD12', + 'ogon': '\u02DB', + 'ograve': 'ò', + 'Ograve': 'Ò', + 'ogt': '\u29C1', + 'ohbar': '\u29B5', + 'ohm': 'Ω', + 'oint': '\u222E', + 'olarr': '\u21BA', + 'olcir': '\u29BE', + 'olcross': '\u29BB', + 'oline': '\u203E', + 'olt': '\u29C0', + 'omacr': 'ō', + 'Omacr': 'Ō', + 'omega': 'ω', + 'Omega': 'Ω', + 'omicron': 'ο', + 'Omicron': 'Ο', + 'omid': '\u29B6', + 'ominus': '\u2296', + 'oopf': '\uD835\uDD60', + 'Oopf': '\uD835\uDD46', + 'opar': '\u29B7', + 'OpenCurlyDoubleQuote': '\u201C', + 'OpenCurlyQuote': '\u2018', + 'operp': '\u29B9', + 'oplus': '\u2295', + 'or': '\u2228', + 'Or': '\u2A54', + 'orarr': '\u21BB', + 'ord': '\u2A5D', + 'order': 'ℴ', + 'orderof': 'ℴ', + 'ordf': 'ª', + 'ordm': 'º', + 'origof': '\u22B6', + 'oror': '\u2A56', + 'orslope': '\u2A57', + 'orv': '\u2A5B', + 'oS': '\u24C8', + 'oscr': 'ℴ', + 'Oscr': '\uD835\uDCAA', + 'oslash': 'ø', + 'Oslash': 'Ø', + 'osol': '\u2298', + 'otilde': 'õ', + 'Otilde': 'Õ', + 'otimes': '\u2297', + 'Otimes': '\u2A37', + 'otimesas': '\u2A36', + 'ouml': 'ö', + 'Ouml': 'Ö', + 'ovbar': '\u233D', + 'OverBar': '\u203E', + 'OverBrace': '\u23DE', + 'OverBracket': '\u23B4', + 'OverParenthesis': '\u23DC', + 'par': '\u2225', + 'para': '\xB6', + 'parallel': '\u2225', + 'parsim': '\u2AF3', + 'parsl': '\u2AFD', + 'part': '\u2202', + 'PartialD': '\u2202', + 'pcy': 'п', + 'Pcy': 'П', + 'percnt': '%', + 'period': '.', + 'permil': '\u2030', + 'perp': '\u22A5', + 'pertenk': '\u2031', + 'pfr': '\uD835\uDD2D', + 'Pfr': '\uD835\uDD13', + 'phi': 'φ', + 'Phi': 'Φ', + 'phiv': 'ϕ', + 'phmmat': 'ℳ', + 'phone': '\u260E', + 'pi': 'π', + 'Pi': 'Π', + 'pitchfork': '\u22D4', + 'piv': 'ϖ', + 'planck': 'ℏ', + 'planckh': 'ℎ', + 'plankv': 'ℏ', + 'plus': '+', + 'plusacir': '\u2A23', + 'plusb': '\u229E', + 'pluscir': '\u2A22', + 'plusdo': '\u2214', + 'plusdu': '\u2A25', + 'pluse': '\u2A72', + 'PlusMinus': '\xB1', + 'plusmn': '\xB1', + 'plussim': '\u2A26', + 'plustwo': '\u2A27', + 'pm': '\xB1', + 'Poincareplane': 'ℌ', + 'pointint': '\u2A15', + 'popf': '\uD835\uDD61', + 'Popf': 'ℙ', + 'pound': '\xA3', + 'pr': '\u227A', + 'Pr': '\u2ABB', + 'prap': '\u2AB7', + 'prcue': '\u227C', + 'pre': '\u2AAF', + 'prE': '\u2AB3', + 'prec': '\u227A', + 'precapprox': '\u2AB7', + 'preccurlyeq': '\u227C', + 'Precedes': '\u227A', + 'PrecedesEqual': '\u2AAF', + 'PrecedesSlantEqual': '\u227C', + 'PrecedesTilde': '\u227E', + 'preceq': '\u2AAF', + 'precnapprox': '\u2AB9', + 'precneqq': '\u2AB5', + 'precnsim': '\u22E8', + 'precsim': '\u227E', + 'prime': '\u2032', + 'Prime': '\u2033', + 'primes': 'ℙ', + 'prnap': '\u2AB9', + 'prnE': '\u2AB5', + 'prnsim': '\u22E8', + 'prod': '\u220F', + 'Product': '\u220F', + 'profalar': '\u232E', + 'profline': '\u2312', + 'profsurf': '\u2313', + 'prop': '\u221D', + 'Proportion': '\u2237', + 'Proportional': '\u221D', + 'propto': '\u221D', + 'prsim': '\u227E', + 'prurel': '\u22B0', + 'pscr': '\uD835\uDCC5', + 'Pscr': '\uD835\uDCAB', + 'psi': 'ψ', + 'Psi': 'Ψ', + 'puncsp': '\u2008', + 'qfr': '\uD835\uDD2E', + 'Qfr': '\uD835\uDD14', + 'qint': '\u2A0C', + 'qopf': '\uD835\uDD62', + 'Qopf': 'ℚ', + 'qprime': '\u2057', + 'qscr': '\uD835\uDCC6', + 'Qscr': '\uD835\uDCAC', + 'quaternions': 'ℍ', + 'quatint': '\u2A16', + 'quest': '?', + 'questeq': '\u225F', + 'quot': '"', + 'QUOT': '"', + 'rAarr': '\u21DB', + 'race': '\u223Ḏ', + 'racute': 'ŕ', + 'Racute': 'Ŕ', + 'radic': '\u221A', + 'raemptyv': '\u29B3', + 'rang': '\u27E9', + 'Rang': '\u27EB', + 'rangd': '\u2992', + 'range': '\u29A5', + 'rangle': '\u27E9', + 'raquo': '\xBB', + 'rarr': '\u2192', + 'rArr': '\u21D2', + 'Rarr': '\u21A0', + 'rarrap': '\u2975', + 'rarrb': '\u21E5', + 'rarrbfs': '\u2920', + 'rarrc': '\u2933', + 'rarrfs': '\u291E', + 'rarrhk': '\u21AA', + 'rarrlp': '\u21AC', + 'rarrpl': '\u2945', + 'rarrsim': '\u2974', + 'rarrtl': '\u21A3', + 'Rarrtl': '\u2916', + 'rarrw': '\u219D', + 'ratail': '\u291A', + 'rAtail': '\u291C', + 'ratio': '\u2236', + 'rationals': 'ℚ', + 'rbarr': '\u290D', + 'rBarr': '\u290F', + 'RBarr': '\u2910', + 'rbbrk': '\u2773', + 'rbrace': '}', + 'rbrack': ']', + 'rbrke': '\u298C', + 'rbrksld': '\u298E', + 'rbrkslu': '\u2990', + 'rcaron': 'ř', + 'Rcaron': 'Ř', + 'rcedil': 'ŗ', + 'Rcedil': 'Ŗ', + 'rceil': '\u2309', + 'rcub': '}', + 'rcy': 'р', + 'Rcy': 'Р', + 'rdca': '\u2937', + 'rdldhar': '\u2969', + 'rdquo': '\u201D', + 'rdquor': '\u201D', + 'rdsh': '\u21B3', + 'Re': 'ℜ', + 'real': 'ℜ', + 'realine': 'ℛ', + 'realpart': 'ℜ', + 'reals': 'ℝ', + 'rect': '\u25AD', + 'reg': '\xAE', + 'REG': '\xAE', + 'ReverseElement': '\u220B', + 'ReverseEquilibrium': '\u21CB', + 'ReverseUpEquilibrium': '\u296F', + 'rfisht': '\u297D', + 'rfloor': '\u230B', + 'rfr': '\uD835\uDD2F', + 'Rfr': 'ℜ', + 'rHar': '\u2964', + 'rhard': '\u21C1', + 'rharu': '\u21C0', + 'rharul': '\u296C', + 'rho': 'ρ', + 'Rho': 'Ρ', + 'rhov': 'ϱ', + 'RightAngleBracket': '\u27E9', + 'rightarrow': '\u2192', + 'Rightarrow': '\u21D2', + 'RightArrow': '\u2192', + 'RightArrowBar': '\u21E5', + 'RightArrowLeftArrow': '\u21C4', + 'rightarrowtail': '\u21A3', + 'RightCeiling': '\u2309', + 'RightDoubleBracket': '\u27E7', + 'RightDownTeeVector': '\u295D', + 'RightDownVector': '\u21C2', + 'RightDownVectorBar': '\u2955', + 'RightFloor': '\u230B', + 'rightharpoondown': '\u21C1', + 'rightharpoonup': '\u21C0', + 'rightleftarrows': '\u21C4', + 'rightleftharpoons': '\u21CC', + 'rightrightarrows': '\u21C9', + 'rightsquigarrow': '\u219D', + 'RightTee': '\u22A2', + 'RightTeeArrow': '\u21A6', + 'RightTeeVector': '\u295B', + 'rightthreetimes': '\u22CC', + 'RightTriangle': '\u22B3', + 'RightTriangleBar': '\u29D0', + 'RightTriangleEqual': '\u22B5', + 'RightUpDownVector': '\u294F', + 'RightUpTeeVector': '\u295C', + 'RightUpVector': '\u21BE', + 'RightUpVectorBar': '\u2954', + 'RightVector': '\u21C0', + 'RightVectorBar': '\u2953', + 'ring': '\u02DA', + 'risingdotseq': '\u2253', + 'rlarr': '\u21C4', + 'rlhar': '\u21CC', + 'rlm': '\u200F', + 'rmoust': '\u23B1', + 'rmoustache': '\u23B1', + 'rnmid': '\u2AEE', + 'roang': '\u27ED', + 'roarr': '\u21FE', + 'robrk': '\u27E7', + 'ropar': '\u2986', + 'ropf': '\uD835\uDD63', + 'Ropf': 'ℝ', + 'roplus': '\u2A2E', + 'rotimes': '\u2A35', + 'RoundImplies': '\u2970', + 'rpar': ')', + 'rpargt': '\u2994', + 'rppolint': '\u2A12', + 'rrarr': '\u21C9', + 'Rrightarrow': '\u21DB', + 'rsaquo': '\u203A', + 'rscr': '\uD835\uDCC7', + 'Rscr': 'ℛ', + 'rsh': '\u21B1', + 'Rsh': '\u21B1', + 'rsqb': ']', + 'rsquo': '\u2019', + 'rsquor': '\u2019', + 'rthree': '\u22CC', + 'rtimes': '\u22CA', + 'rtri': '\u25B9', + 'rtrie': '\u22B5', + 'rtrif': '\u25B8', + 'rtriltri': '\u29CE', + 'RuleDelayed': '\u29F4', + 'ruluhar': '\u2968', + 'rx': '\u211E', + 'sacute': 'ś', + 'Sacute': 'Ś', + 'sbquo': '\u201A', + 'sc': '\u227B', + 'Sc': '\u2ABC', + 'scap': '\u2AB8', + 'scaron': 'š', + 'Scaron': 'Š', + 'sccue': '\u227D', + 'sce': '\u2AB0', + 'scE': '\u2AB4', + 'scedil': 'ş', + 'Scedil': 'Ş', + 'scirc': 'ŝ', + 'Scirc': 'Ŝ', + 'scnap': '\u2ABA', + 'scnE': '\u2AB6', + 'scnsim': '\u22E9', + 'scpolint': '\u2A13', + 'scsim': '\u227F', + 'scy': 'с', + 'Scy': 'С', + 'sdot': '\u22C5', + 'sdotb': '\u22A1', + 'sdote': '\u2A66', + 'searhk': '\u2925', + 'searr': '\u2198', + 'seArr': '\u21D8', + 'searrow': '\u2198', + 'sect': '\xA7', + 'semi': ';', + 'seswar': '\u2929', + 'setminus': '\u2216', + 'setmn': '\u2216', + 'sext': '\u2736', + 'sfr': '\uD835\uDD30', + 'Sfr': '\uD835\uDD16', + 'sfrown': '\u2322', + 'sharp': '\u266F', + 'shchcy': 'щ', + 'SHCHcy': 'Щ', + 'shcy': 'ш', + 'SHcy': 'Ш', + 'ShortDownArrow': '\u2193', + 'ShortLeftArrow': '\u2190', + 'shortmid': '\u2223', + 'shortparallel': '\u2225', + 'ShortRightArrow': '\u2192', + 'ShortUpArrow': '\u2191', + 'shy': '\xAD', + 'sigma': 'σ', + 'Sigma': 'Σ', + 'sigmaf': 'ς', + 'sigmav': 'ς', + 'sim': '\u223C', + 'simdot': '\u2A6A', + 'sime': '\u2243', + 'simeq': '\u2243', + 'simg': '\u2A9E', + 'simgE': '\u2AA0', + 'siml': '\u2A9D', + 'simlE': '\u2A9F', + 'simne': '\u2246', + 'simplus': '\u2A24', + 'simrarr': '\u2972', + 'slarr': '\u2190', + 'SmallCircle': '\u2218', + 'smallsetminus': '\u2216', + 'smashp': '\u2A33', + 'smeparsl': '\u29E4', + 'smid': '\u2223', + 'smile': '\u2323', + 'smt': '\u2AAA', + 'smte': '\u2AAC', + 'smtes': '\u2AAC︀', + 'softcy': 'ь', + 'SOFTcy': 'Ь', + 'sol': '/', + 'solb': '\u29C4', + 'solbar': '\u233F', + 'sopf': '\uD835\uDD64', + 'Sopf': '\uD835\uDD4A', + 'spades': '\u2660', + 'spadesuit': '\u2660', + 'spar': '\u2225', + 'sqcap': '\u2293', + 'sqcaps': '\u2293︀', + 'sqcup': '\u2294', + 'sqcups': '\u2294︀', + 'Sqrt': '\u221A', + 'sqsub': '\u228F', + 'sqsube': '\u2291', + 'sqsubset': '\u228F', + 'sqsubseteq': '\u2291', + 'sqsup': '\u2290', + 'sqsupe': '\u2292', + 'sqsupset': '\u2290', + 'sqsupseteq': '\u2292', + 'squ': '\u25A1', + 'square': '\u25A1', + 'Square': '\u25A1', + 'SquareIntersection': '\u2293', + 'SquareSubset': '\u228F', + 'SquareSubsetEqual': '\u2291', + 'SquareSuperset': '\u2290', + 'SquareSupersetEqual': '\u2292', + 'SquareUnion': '\u2294', + 'squarf': '\u25AA', + 'squf': '\u25AA', + 'srarr': '\u2192', + 'sscr': '\uD835\uDCC8', + 'Sscr': '\uD835\uDCAE', + 'ssetmn': '\u2216', + 'ssmile': '\u2323', + 'sstarf': '\u22C6', + 'star': '\u2606', + 'Star': '\u22C6', + 'starf': '\u2605', + 'straightepsilon': 'ϵ', + 'straightphi': 'ϕ', + 'strns': '\xAF', + 'sub': '\u2282', + 'Sub': '\u22D0', + 'subdot': '\u2ABD', + 'sube': '\u2286', + 'subE': '\u2AC5', + 'subedot': '\u2AC3', + 'submult': '\u2AC1', + 'subne': '\u228A', + 'subnE': '\u2ACB', + 'subplus': '\u2ABF', + 'subrarr': '\u2979', + 'subset': '\u2282', + 'Subset': '\u22D0', + 'subseteq': '\u2286', + 'subseteqq': '\u2AC5', + 'SubsetEqual': '\u2286', + 'subsetneq': '\u228A', + 'subsetneqq': '\u2ACB', + 'subsim': '\u2AC7', + 'subsub': '\u2AD5', + 'subsup': '\u2AD3', + 'succ': '\u227B', + 'succapprox': '\u2AB8', + 'succcurlyeq': '\u227D', + 'Succeeds': '\u227B', + 'SucceedsEqual': '\u2AB0', + 'SucceedsSlantEqual': '\u227D', + 'SucceedsTilde': '\u227F', + 'succeq': '\u2AB0', + 'succnapprox': '\u2ABA', + 'succneqq': '\u2AB6', + 'succnsim': '\u22E9', + 'succsim': '\u227F', + 'SuchThat': '\u220B', + 'sum': '\u2211', + 'Sum': '\u2211', + 'sung': '\u266A', + 'sup': '\u2283', + 'Sup': '\u22D1', + 'sup1': '\xB9', + 'sup2': '\xB2', + 'sup3': '\xB3', + 'supdot': '\u2ABE', + 'supdsub': '\u2AD8', + 'supe': '\u2287', + 'supE': '\u2AC6', + 'supedot': '\u2AC4', + 'Superset': '\u2283', + 'SupersetEqual': '\u2287', + 'suphsol': '\u27C9', + 'suphsub': '\u2AD7', + 'suplarr': '\u297B', + 'supmult': '\u2AC2', + 'supne': '\u228B', + 'supnE': '\u2ACC', + 'supplus': '\u2AC0', + 'supset': '\u2283', + 'Supset': '\u22D1', + 'supseteq': '\u2287', + 'supseteqq': '\u2AC6', + 'supsetneq': '\u228B', + 'supsetneqq': '\u2ACC', + 'supsim': '\u2AC8', + 'supsub': '\u2AD4', + 'supsup': '\u2AD6', + 'swarhk': '\u2926', + 'swarr': '\u2199', + 'swArr': '\u21D9', + 'swarrow': '\u2199', + 'swnwar': '\u292A', + 'szlig': 'ß', + 'Tab': '\t', + 'target': '\u2316', + 'tau': 'τ', + 'Tau': 'Τ', + 'tbrk': '\u23B4', + 'tcaron': 'ť', + 'Tcaron': 'Ť', + 'tcedil': 'ţ', + 'Tcedil': 'Ţ', + 'tcy': 'т', + 'Tcy': 'Т', + 'tdot': '⃛', + 'telrec': '\u2315', + 'tfr': '\uD835\uDD31', + 'Tfr': '\uD835\uDD17', + 'there4': '\u2234', + 'therefore': '\u2234', + 'Therefore': '\u2234', + 'theta': 'θ', + 'Theta': 'Θ', + 'thetasym': 'ϑ', + 'thetav': 'ϑ', + 'thickapprox': '\u2248', + 'thicksim': '\u223C', + 'ThickSpace': '\u205F\u200A', + 'thinsp': '\u2009', + 'ThinSpace': '\u2009', + 'thkap': '\u2248', + 'thksim': '\u223C', + 'thorn': 'þ', + 'THORN': 'Þ', + 'tilde': '\u02DC', + 'Tilde': '\u223C', + 'TildeEqual': '\u2243', + 'TildeFullEqual': '\u2245', + 'TildeTilde': '\u2248', + 'times': '\xD7', + 'timesb': '\u22A0', + 'timesbar': '\u2A31', + 'timesd': '\u2A30', + 'tint': '\u222D', + 'toea': '\u2928', + 'top': '\u22A4', + 'topbot': '\u2336', + 'topcir': '\u2AF1', + 'topf': '\uD835\uDD65', + 'Topf': '\uD835\uDD4B', + 'topfork': '\u2ADA', + 'tosa': '\u2929', + 'tprime': '\u2034', + 'trade': '\u2122', + 'TRADE': '\u2122', + 'triangle': '\u25B5', + 'triangledown': '\u25BF', + 'triangleleft': '\u25C3', + 'trianglelefteq': '\u22B4', + 'triangleq': '\u225C', + 'triangleright': '\u25B9', + 'trianglerighteq': '\u22B5', + 'tridot': '\u25EC', + 'trie': '\u225C', + 'triminus': '\u2A3A', + 'TripleDot': '⃛', + 'triplus': '\u2A39', + 'trisb': '\u29CD', + 'tritime': '\u2A3B', + 'trpezium': '\u23E2', + 'tscr': '\uD835\uDCC9', + 'Tscr': '\uD835\uDCAF', + 'tscy': 'ц', + 'TScy': 'Ц', + 'tshcy': 'ћ', + 'TSHcy': 'Ћ', + 'tstrok': 'ŧ', + 'Tstrok': 'Ŧ', + 'twixt': '\u226C', + 'twoheadleftarrow': '\u219E', + 'twoheadrightarrow': '\u21A0', + 'uacute': 'ú', + 'Uacute': 'Ú', + 'uarr': '\u2191', + 'uArr': '\u21D1', + 'Uarr': '\u219F', + 'Uarrocir': '\u2949', + 'ubrcy': 'ў', + 'Ubrcy': 'Ў', + 'ubreve': 'ŭ', + 'Ubreve': 'Ŭ', + 'ucirc': 'û', + 'Ucirc': 'Û', + 'ucy': 'у', + 'Ucy': 'У', + 'udarr': '\u21C5', + 'udblac': 'ű', + 'Udblac': 'Ű', + 'udhar': '\u296E', + 'ufisht': '\u297E', + 'ufr': '\uD835\uDD32', + 'Ufr': '\uD835\uDD18', + 'ugrave': 'ù', + 'Ugrave': 'Ù', + 'uHar': '\u2963', + 'uharl': '\u21BF', + 'uharr': '\u21BE', + 'uhblk': '\u2580', + 'ulcorn': '\u231C', + 'ulcorner': '\u231C', + 'ulcrop': '\u230F', + 'ultri': '\u25F8', + 'umacr': 'ū', + 'Umacr': 'Ū', + 'uml': '\xA8', + 'UnderBar': '_', + 'UnderBrace': '\u23DF', + 'UnderBracket': '\u23B5', + 'UnderParenthesis': '\u23DD', + 'Union': '\u22C3', + 'UnionPlus': '\u228E', + 'uogon': 'ų', + 'Uogon': 'Ų', + 'uopf': '\uD835\uDD66', + 'Uopf': '\uD835\uDD4C', + 'uparrow': '\u2191', + 'Uparrow': '\u21D1', + 'UpArrow': '\u2191', + 'UpArrowBar': '\u2912', + 'UpArrowDownArrow': '\u21C5', + 'updownarrow': '\u2195', + 'Updownarrow': '\u21D5', + 'UpDownArrow': '\u2195', + 'UpEquilibrium': '\u296E', + 'upharpoonleft': '\u21BF', + 'upharpoonright': '\u21BE', + 'uplus': '\u228E', + 'UpperLeftArrow': '\u2196', + 'UpperRightArrow': '\u2197', + 'upsi': 'υ', + 'Upsi': 'ϒ', + 'upsih': 'ϒ', + 'upsilon': 'υ', + 'Upsilon': 'Υ', + 'UpTee': '\u22A5', + 'UpTeeArrow': '\u21A5', + 'upuparrows': '\u21C8', + 'urcorn': '\u231D', + 'urcorner': '\u231D', + 'urcrop': '\u230E', + 'uring': 'ů', + 'Uring': 'Ů', + 'urtri': '\u25F9', + 'uscr': '\uD835\uDCCA', + 'Uscr': '\uD835\uDCB0', + 'utdot': '\u22F0', + 'utilde': 'ũ', + 'Utilde': 'Ũ', + 'utri': '\u25B5', + 'utrif': '\u25B4', + 'uuarr': '\u21C8', + 'uuml': 'ü', + 'Uuml': 'Ü', + 'uwangle': '\u29A7', + 'vangrt': '\u299C', + 'varepsilon': 'ϵ', + 'varkappa': 'ϰ', + 'varnothing': '\u2205', + 'varphi': 'ϕ', + 'varpi': 'ϖ', + 'varpropto': '\u221D', + 'varr': '\u2195', + 'vArr': '\u21D5', + 'varrho': 'ϱ', + 'varsigma': 'ς', + 'varsubsetneq': '\u228A︀', + 'varsubsetneqq': '\u2ACB︀', + 'varsupsetneq': '\u228B︀', + 'varsupsetneqq': '\u2ACC︀', + 'vartheta': 'ϑ', + 'vartriangleleft': '\u22B2', + 'vartriangleright': '\u22B3', + 'vBar': '\u2AE8', + 'Vbar': '\u2AEB', + 'vBarv': '\u2AE9', + 'vcy': 'в', + 'Vcy': 'В', + 'vdash': '\u22A2', + 'vDash': '\u22A8', + 'Vdash': '\u22A9', + 'VDash': '\u22AB', + 'Vdashl': '\u2AE6', + 'vee': '\u2228', + 'Vee': '\u22C1', + 'veebar': '\u22BB', + 'veeeq': '\u225A', + 'vellip': '\u22EE', + 'verbar': '|', + 'Verbar': '\u2016', + 'vert': '|', + 'Vert': '\u2016', + 'VerticalBar': '\u2223', + 'VerticalLine': '|', + 'VerticalSeparator': '\u2758', + 'VerticalTilde': '\u2240', + 'VeryThinSpace': '\u200A', + 'vfr': '\uD835\uDD33', + 'Vfr': '\uD835\uDD19', + 'vltri': '\u22B2', + 'vnsub': '\u2282⃒', + 'vnsup': '\u2283⃒', + 'vopf': '\uD835\uDD67', + 'Vopf': '\uD835\uDD4D', + 'vprop': '\u221D', + 'vrtri': '\u22B3', + 'vscr': '\uD835\uDCCB', + 'Vscr': '\uD835\uDCB1', + 'vsubne': '\u228A︀', + 'vsubnE': '\u2ACB︀', + 'vsupne': '\u228B︀', + 'vsupnE': '\u2ACC︀', + 'Vvdash': '\u22AA', + 'vzigzag': '\u299A', + 'wcirc': 'ŵ', + 'Wcirc': 'Ŵ', + 'wedbar': '\u2A5F', + 'wedge': '\u2227', + 'Wedge': '\u22C0', + 'wedgeq': '\u2259', + 'weierp': '\u2118', + 'wfr': '\uD835\uDD34', + 'Wfr': '\uD835\uDD1A', + 'wopf': '\uD835\uDD68', + 'Wopf': '\uD835\uDD4E', + 'wp': '\u2118', + 'wr': '\u2240', + 'wreath': '\u2240', + 'wscr': '\uD835\uDCCC', + 'Wscr': '\uD835\uDCB2', + 'xcap': '\u22C2', + 'xcirc': '\u25EF', + 'xcup': '\u22C3', + 'xdtri': '\u25BD', + 'xfr': '\uD835\uDD35', + 'Xfr': '\uD835\uDD1B', + 'xharr': '\u27F7', + 'xhArr': '\u27FA', + 'xi': 'ξ', + 'Xi': 'Ξ', + 'xlarr': '\u27F5', + 'xlArr': '\u27F8', + 'xmap': '\u27FC', + 'xnis': '\u22FB', + 'xodot': '\u2A00', + 'xopf': '\uD835\uDD69', + 'Xopf': '\uD835\uDD4F', + 'xoplus': '\u2A01', + 'xotime': '\u2A02', + 'xrarr': '\u27F6', + 'xrArr': '\u27F9', + 'xscr': '\uD835\uDCCD', + 'Xscr': '\uD835\uDCB3', + 'xsqcup': '\u2A06', + 'xuplus': '\u2A04', + 'xutri': '\u25B3', + 'xvee': '\u22C1', + 'xwedge': '\u22C0', + 'yacute': 'ý', + 'Yacute': 'Ý', + 'yacy': 'я', + 'YAcy': 'Я', + 'ycirc': 'ŷ', + 'Ycirc': 'Ŷ', + 'ycy': 'ы', + 'Ycy': 'Ы', + 'yen': '\xA5', + 'yfr': '\uD835\uDD36', + 'Yfr': '\uD835\uDD1C', + 'yicy': 'ї', + 'YIcy': 'Ї', + 'yopf': '\uD835\uDD6A', + 'Yopf': '\uD835\uDD50', + 'yscr': '\uD835\uDCCE', + 'Yscr': '\uD835\uDCB4', + 'yucy': 'ю', + 'YUcy': 'Ю', + 'yuml': 'ÿ', + 'Yuml': 'Ÿ', + 'zacute': 'ź', + 'Zacute': 'Ź', + 'zcaron': 'ž', + 'Zcaron': 'Ž', + 'zcy': 'з', + 'Zcy': 'З', + 'zdot': 'ż', + 'Zdot': 'Ż', + 'zeetrf': 'ℨ', + 'ZeroWidthSpace': '\u200B', + 'zeta': 'ζ', + 'Zeta': 'Ζ', + 'zfr': '\uD835\uDD37', + 'Zfr': 'ℨ', + 'zhcy': 'ж', + 'ZHcy': 'Ж', + 'zigrarr': '\u21DD', + 'zopf': '\uD835\uDD6B', + 'Zopf': 'ℤ', + 'zscr': '\uD835\uDCCF', + 'Zscr': '\uD835\uDCB5', + 'zwj': '‍', + 'zwnj': '‌' + }; + var decodeMapLegacy = { + 'aacute': 'á', + 'Aacute': 'Á', + 'acirc': 'â', + 'Acirc': 'Â', + 'acute': '\xB4', + 'aelig': 'æ', + 'AElig': 'Æ', + 'agrave': 'à', + 'Agrave': 'À', + 'amp': '&', + 'AMP': '&', + 'aring': 'å', + 'Aring': 'Å', + 'atilde': 'ã', + 'Atilde': 'Ã', + 'auml': 'ä', + 'Auml': 'Ä', + 'brvbar': '\xA6', + 'ccedil': 'ç', + 'Ccedil': 'Ç', + 'cedil': '\xB8', + 'cent': '\xA2', + 'copy': '\xA9', + 'COPY': '\xA9', + 'curren': '\xA4', + 'deg': '\xB0', + 'divide': '\xF7', + 'eacute': 'é', + 'Eacute': 'É', + 'ecirc': 'ê', + 'Ecirc': 'Ê', + 'egrave': 'è', + 'Egrave': 'È', + 'eth': 'ð', + 'ETH': 'Ð', + 'euml': 'ë', + 'Euml': 'Ë', + 'frac12': '\xBD', + 'frac14': '\xBC', + 'frac34': '\xBE', + 'gt': '>', + 'GT': '>', + 'iacute': 'í', + 'Iacute': 'Í', + 'icirc': 'î', + 'Icirc': 'Î', + 'iexcl': '\xA1', + 'igrave': 'ì', + 'Igrave': 'Ì', + 'iquest': '\xBF', + 'iuml': 'ï', + 'Iuml': 'Ï', + 'laquo': '\xAB', + 'lt': '<', + 'LT': '<', + 'macr': '\xAF', + 'micro': 'µ', + 'middot': '\xB7', + 'nbsp': '\xA0', + 'not': '\xAC', + 'ntilde': 'ñ', + 'Ntilde': 'Ñ', + 'oacute': 'ó', + 'Oacute': 'Ó', + 'ocirc': 'ô', + 'Ocirc': 'Ô', + 'ograve': 'ò', + 'Ograve': 'Ò', + 'ordf': 'ª', + 'ordm': 'º', + 'oslash': 'ø', + 'Oslash': 'Ø', + 'otilde': 'õ', + 'Otilde': 'Õ', + 'ouml': 'ö', + 'Ouml': 'Ö', + 'para': '\xB6', + 'plusmn': '\xB1', + 'pound': '\xA3', + 'quot': '"', + 'QUOT': '"', + 'raquo': '\xBB', + 'reg': '\xAE', + 'REG': '\xAE', + 'sect': '\xA7', + 'shy': '\xAD', + 'sup1': '\xB9', + 'sup2': '\xB2', + 'sup3': '\xB3', + 'szlig': 'ß', + 'thorn': 'þ', + 'THORN': 'Þ', + 'times': '\xD7', + 'uacute': 'ú', + 'Uacute': 'Ú', + 'ucirc': 'û', + 'Ucirc': 'Û', + 'ugrave': 'ù', + 'Ugrave': 'Ù', + 'uml': '\xA8', + 'uuml': 'ü', + 'Uuml': 'Ü', + 'yacute': 'ý', + 'Yacute': 'Ý', + 'yen': '\xA5', + 'yuml': 'ÿ' + }; + var decodeMapNumeric = { + '0': '\uFFFD', + '128': '\u20AC', + '130': '\u201A', + '131': 'ƒ', + '132': '\u201E', + '133': '\u2026', + '134': '\u2020', + '135': '\u2021', + '136': 'ˆ', + '137': '\u2030', + '138': 'Š', + '139': '\u2039', + '140': 'Œ', + '142': 'Ž', + '145': '\u2018', + '146': '\u2019', + '147': '\u201C', + '148': '\u201D', + '149': '\u2022', + '150': '\u2013', + '151': '\u2014', + '152': '\u02DC', + '153': '\u2122', + '154': 'š', + '155': '\u203A', + '156': 'œ', + '158': 'ž', + '159': 'Ÿ' + }; + var invalidReferenceCodePoints = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 11, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 64976, + 64977, + 64978, + 64979, + 64980, + 64981, + 64982, + 64983, + 64984, + 64985, + 64986, + 64987, + 64988, + 64989, + 64990, + 64991, + 64992, + 64993, + 64994, + 64995, + 64996, + 64997, + 64998, + 64999, + 65000, + 65001, + 65002, + 65003, + 65004, + 65005, + 65006, + 65007, + 65534, + 65535, + 131070, + 131071, + 196606, + 196607, + 262142, + 262143, + 327678, + 327679, + 393214, + 393215, + 458750, + 458751, + 524286, + 524287, + 589822, + 589823, + 655358, + 655359, + 720894, + 720895, + 786430, + 786431, + 851966, + 851967, + 917502, + 917503, + 983038, + 983039, + 1048574, + 1048575, + 1114110, + 1114111 + ]; + var stringFromCharCode = String.fromCharCode; + var object = {}; + var hasOwnProperty = object.hasOwnProperty; + var has = function (object, propertyName) { + return hasOwnProperty.call(object, propertyName); + }; + var contains = function (array, value) { + var index = -1; + var length = array.length; + while (++index < length) { + if (array[index] == value) { + return true; + } + } + return false; + }; + var merge = function (options, defaults) { + if (!options) { + return defaults; + } + var result = {}; + var key; + for (key in defaults) { + result[key] = has(options, key) ? options[key] : defaults[key]; + } + return result; + }; + var codePointToSymbol = function (codePoint, strict) { + var output = ''; + if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) { + if (strict) { + parseError('character reference outside the permissible Unicode range'); + } + return '\uFFFD'; + } + if (has(decodeMapNumeric, codePoint)) { + if (strict) { + parseError('disallowed character reference'); + } + return decodeMapNumeric[codePoint]; + } + if (strict && contains(invalidReferenceCodePoints, codePoint)) { + parseError('disallowed character reference'); + } + if (codePoint > 65535) { + codePoint -= 65536; + output += stringFromCharCode(codePoint >>> 10 & 1023 | 55296); + codePoint = 56320 | codePoint & 1023; + } + output += stringFromCharCode(codePoint); + return output; + }; + var hexEscape = function (codePoint) { + return '&#x' + codePoint.toString(16).toUpperCase() + ';'; + }; + var decEscape = function (codePoint) { + return '&#' + codePoint + ';'; + }; + var parseError = function (message) { + throw Error('Parse error: ' + message); + }; + var encode = function (string, options) { + options = merge(options, encode.options); + var strict = options.strict; + if (strict && regexInvalidRawCodePoint.test(string)) { + parseError('forbidden code point'); + } + var encodeEverything = options.encodeEverything; + var useNamedReferences = options.useNamedReferences; + var allowUnsafeSymbols = options.allowUnsafeSymbols; + var escapeCodePoint = options.decimal ? decEscape : hexEscape; + var escapeBmpSymbol = function (symbol) { + return escapeCodePoint(symbol.charCodeAt(0)); + }; + if (encodeEverything) { + string = string.replace(regexAsciiWhitelist, function (symbol) { + if (useNamedReferences && has(encodeMap, symbol)) { + return '&' + encodeMap[symbol] + ';'; + } + return escapeBmpSymbol(symbol); + }); + if (useNamedReferences) { + string = string.replace(/>\u20D2/g, '>⃒').replace(/<\u20D2/g, '<⃒').replace(/fj/g, 'fj'); + } + if (useNamedReferences) { + string = string.replace(regexEncodeNonAscii, function (string) { + return '&' + encodeMap[string] + ';'; + }); + } + } else if (useNamedReferences) { + if (!allowUnsafeSymbols) { + string = string.replace(regexEscape, function (string) { + return '&' + encodeMap[string] + ';'; + }); + } + string = string.replace(/>\u20D2/g, '>⃒').replace(/<\u20D2/g, '<⃒'); + string = string.replace(regexEncodeNonAscii, function (string) { + return '&' + encodeMap[string] + ';'; + }); + } else if (!allowUnsafeSymbols) { + string = string.replace(regexEscape, escapeBmpSymbol); + } + return string.replace(regexAstralSymbols, function ($0) { + var high = $0.charCodeAt(0); + var low = $0.charCodeAt(1); + var codePoint = (high - 55296) * 1024 + low - 56320 + 65536; + return escapeCodePoint(codePoint); + }).replace(regexBmpWhitelist, escapeBmpSymbol); + }; + encode.options = { + 'allowUnsafeSymbols': false, + 'encodeEverything': false, + 'strict': false, + 'useNamedReferences': false, + 'decimal': false + }; + var decode = function (html, options) { + options = merge(options, decode.options); + var strict = options.strict; + if (strict && regexInvalidEntity.test(html)) { + parseError('malformed character reference'); + } + return html.replace(regexDecode, function ($0, $1, $2, $3, $4, $5, $6, $7, $8) { + var codePoint; + var semicolon; + var decDigits; + var hexDigits; + var reference; + var next; + if ($1) { + reference = $1; + return decodeMap[reference]; + } + if ($2) { + reference = $2; + next = $3; + if (next && options.isAttributeValue) { + if (strict && next == '=') { + parseError('`&` did not start a character reference'); + } + return $0; + } else { + if (strict) { + parseError('named character reference was not terminated by a semicolon'); + } + return decodeMapLegacy[reference] + (next || ''); + } + } + if ($4) { + decDigits = $4; + semicolon = $5; + if (strict && !semicolon) { + parseError('character reference was not terminated by a semicolon'); + } + codePoint = parseInt(decDigits, 10); + return codePointToSymbol(codePoint, strict); + } + if ($6) { + hexDigits = $6; + semicolon = $7; + if (strict && !semicolon) { + parseError('character reference was not terminated by a semicolon'); + } + codePoint = parseInt(hexDigits, 16); + return codePointToSymbol(codePoint, strict); + } + if (strict) { + parseError('named character reference was not terminated by a semicolon'); + } + return $0; + }); + }; + decode.options = { + 'isAttributeValue': false, + 'strict': false + }; + var escape = function (string) { + return string.replace(regexEscape, function ($0) { + return escapeMap[$0]; + }); + }; + var he = { + 'version': '1.2.0', + 'encode': encode, + 'decode': decode, + 'escape': escape, + 'unescape': decode + }; + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + define('he@1.2.0#he', function () { + return he; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { + freeModule.exports = he; + } else { + for (var key in he) { + has(he, key) && (freeExports[key] = he[key]); + } + } + } else { + root.he = he; + } +}(this)); +/*can-simple-dom@1.7.1#lib/html-parser*/ +define('can-simple-dom@1.7.1#lib/html-parser', [ + 'require', + 'exports', + 'module', + 'he' +], function (require, exports, module) { + var he = require('he'); + function HTMLParser(tokenize, document, voidMap) { + this.tokenize = tokenize; + this.document = document; + this.voidMap = voidMap; + this.parentStack = []; + } + HTMLParser.prototype.isVoid = function (element) { + return this.voidMap[element.nodeName] === true; + }; + HTMLParser.prototype.pushElement = function (token) { + var el = this.document.createElement(token.tagName); + for (var i = 0; i < token.attributes.length; i++) { + var attr = token.attributes[i]; + if (attr[0] !== 'href' && attr[0] !== 'src') { + attr[1] = he.encode(attr[1]); + } + el.setAttribute(attr[0], attr[1]); + } + if (this.isVoid(el) || token.selfClosing) { + return this.appendChild(el); + } + this.parentStack.push(el); + }; + HTMLParser.prototype.popElement = function (token) { + var el = this.parentStack.pop(); + if (el.nodeName !== token.tagName.toUpperCase()) { + throw new Error('unbalanced tag'); + } + this.appendChild(el); + }; + HTMLParser.prototype.appendText = function (token) { + var text = this.document.createTextNode(token.chars); + this.appendChild(text); + }; + HTMLParser.prototype.appendComment = function (token) { + var comment = this.document.createComment(token.chars); + this.appendChild(comment); + }; + HTMLParser.prototype.appendChild = function (node) { + var parentNode = this.parentStack[this.parentStack.length - 1]; + parentNode.appendChild(node); + }; + HTMLParser.prototype.parse = function (html) { + var fragment = this.document.createDocumentFragment(); + this.parentStack.push(fragment); + var tokens = this.tokenize(html); + for (var i = 0, l = tokens.length; i < l; i++) { + var token = tokens[i]; + switch (token.type) { + case 'StartTag': + this.pushElement(token); + break; + case 'EndTag': + this.popElement(token); + break; + case 'Chars': + this.appendText(token); + break; + case 'Comment': + this.appendComment(token); + break; + } + } + return this.parentStack.pop(); + }; + module.exports = HTMLParser; +}); +/*can-simple-dom@1.7.1#lib/html-serializer*/ +define('can-simple-dom@1.7.1#lib/html-serializer', function (require, exports, module) { + var REG_ESCAPE_ALL = /[<>&]/g; + var REG_ESCAPE_PRESERVE_ENTITIES = /[<>]|&(?:#?[a-zA-Z0-9]+;)?/g; + function HTMLSerializer(voidMap) { + this.voidMap = voidMap; + } + HTMLSerializer.prototype.openTag = function (element) { + return '<' + element.nodeName.toLowerCase() + this.attributes(element.attributes) + '>'; + }; + HTMLSerializer.prototype.closeTag = function (element) { + return ''; + }; + HTMLSerializer.prototype.isVoid = function (element) { + return this.voidMap[element.nodeName] === true; + }; + HTMLSerializer.prototype.attributes = function (namedNodeMap) { + var buffer = ''; + for (var i = 0, l = namedNodeMap.length; i < l; i++) { + buffer += this.attr(namedNodeMap[i]); + } + return buffer; + }; + HTMLSerializer.prototype.escapeAttrValue = function (attrValue) { + return attrValue.replace(/"|&(?:#?[a-zA-Z0-9]+;)?/g, function (match) { + switch (match) { + case '&': + return '&'; + case '"': + return '"'; + default: + return match; + } + }); + }; + HTMLSerializer.prototype.attr = function (attr) { + if (!attr.specified) { + return ''; + } + if (attr.value) { + if (attr.name === 'href' || attr.name === 'src') { + return ' ' + attr.name + '="' + attr.value + '"'; + } + return ' ' + attr.name + '="' + this.escapeAttrValue(attr.value) + '"'; + } + return ' ' + attr.name; + }; + HTMLSerializer.prototype.escapeText = function (textNodeValue, escapeAll) { + return textNodeValue.replace(escapeAll ? REG_ESCAPE_ALL : REG_ESCAPE_PRESERVE_ENTITIES, function (match) { + switch (match) { + case '&': + return '&'; + case '<': + return '<'; + case '>': + return '>'; + default: + return match; + } + }); + }; + var metadataContentTags = { + style: true, + script: true, + template: true + }; + function isMetadataTag(elem) { + return !!elem && metadataContentTags[elem.nodeName.toLowerCase()]; + } + HTMLSerializer.prototype.text = function (text) { + if (isMetadataTag(text.parentNode)) { + return text.nodeValue; + } + return this.escapeText(text.nodeValue); + }; + HTMLSerializer.prototype.comment = function (comment) { + return ''; + }; + HTMLSerializer.prototype.serialize = function (node) { + var buffer = ''; + var next; + switch (node.nodeType) { + case 1: + buffer += this.openTag(node); + break; + case 3: + buffer += this.text(node); + break; + case 8: + buffer += this.comment(node); + break; + default: + break; + } + next = node.firstChild; + if (next) { + while (next) { + buffer += this.serialize(next); + next = next.nextSibling; + } + } else if (node.nodeType === 1 && node.textContent) { + buffer += this.escapeText(node.textContent, true); + } + if (node.nodeType === 1 && !this.isVoid(node)) { + buffer += this.closeTag(node); + } + return buffer; + }; + module.exports = HTMLSerializer; +}); +/*can-simple-dom@1.7.1#lib/void-map*/ +define('can-simple-dom@1.7.1#lib/void-map', function (require, exports, module) { + module.exports = { + AREA: true, + BASE: true, + BR: true, + COL: true, + COMMAND: true, + EMBED: true, + HR: true, + IMG: true, + INPUT: true, + KEYGEN: true, + LINK: true, + META: true, + PARAM: true, + SOURCE: true, + TRACK: true, + WBR: true + }; +}); +/*can-simple-dom@1.7.1#lib/dom*/ +define('can-simple-dom@1.7.1#lib/dom', [ + 'require', + 'exports', + 'module', + './document/node', + './document/element', + './document', + './event', + './html-parser', + './html-serializer', + './void-map' +], function (require, exports, module) { + var Node = require('./document/node').Node; + var Element = require('./document/element'); + var Document = require('./document'); + var Event = require('./event'); + var HTMLParser = require('./html-parser'); + var HTMLSerializer = require('./html-serializer'); + var voidMap = require('./void-map'); + function createDocument(serializer, parser) { + var doc = new Document(); + doc.__serializer = serializer; + doc.__parser = parser; + return doc; + } + exports.Node = Node; + exports.Element = Element; + exports.Document = Document; + exports.Event = Event; + exports.HTMLParser = HTMLParser; + exports.HTMLSerializer = HTMLSerializer; + exports.voidMap = voidMap; + exports.createDocument = createDocument; +}); +/*can-simple-dom@1.7.1#can-simple-dom*/ +define('can-simple-dom@1.7.1#can-simple-dom', [ + 'require', + 'exports', + 'module', + './lib/dom' +], function (require, exports, module) { + var SimpleDOM = require('./lib/dom'); + if (typeof window !== 'undefined') { + window.SimpleDOM = SimpleDOM; + } + exports = module.exports = SimpleDOM.Document; + exports.Node = SimpleDOM.Node; + exports.Element = SimpleDOM.Element; + exports.Document = SimpleDOM.Document; + exports.Event = SimpleDOM.Event; + exports.HTMLParser = SimpleDOM.HTMLParser; + exports.HTMLSerializer = SimpleDOM.HTMLSerializer; + exports.voidMap = SimpleDOM.voidMap; + exports.createDocument = SimpleDOM.createDocument; +}); +/*can-vdom@4.4.2#make-parser/make-parser*/ +define('can-vdom@4.4.2#make-parser/make-parser', [ + 'require', + 'exports', + 'module', + 'can-view-parser', + 'can-simple-dom' +], function (require, exports, module) { + 'use strict'; + var canParser = require('can-view-parser'); + var simpleDOM = require('can-simple-dom'); + module.exports = function (document) { + return new simpleDOM.HTMLParser(function (string) { + var tokens = []; + var currentTag, currentAttr; + canParser(string, { + start: function (tagName, unary) { + currentTag = { + type: 'StartTag', + attributes: [], + tagName: tagName + }; + }, + end: function (tagName, unary) { + tokens.push(currentTag); + currentTag = undefined; + }, + close: function (tagName) { + tokens.push({ + type: 'EndTag', + tagName: tagName + }); + }, + attrStart: function (attrName) { + currentAttr = [ + attrName, + '' + ]; + currentTag.attributes.push(currentAttr); + }, + attrEnd: function (attrName) { + }, + attrValue: function (value) { + currentAttr[1] += value; + }, + chars: function (value) { + tokens.push({ + type: 'Chars', + chars: value + }); + }, + comment: function (value) { + tokens.push({ + type: 'Comment', + chars: value + }); + }, + special: function (value) { + }, + done: function () { + } + }); + return tokens; + }, document, simpleDOM.voidMap); + }; +}); +/*can-vdom@4.4.2#make-document/make-document*/ +define('can-vdom@4.4.2#make-document/make-document', [ + 'require', + 'exports', + 'module', + 'can-simple-dom', + '../make-parser/make-parser' +], function (require, exports, module) { + 'use strict'; + var simpleDOM = require('can-simple-dom'); + var makeParser = require('../make-parser/make-parser'); + function CanSimpleDocument() { + simpleDOM.Document.apply(this, arguments); + var serializer = new simpleDOM.HTMLSerializer(simpleDOM.voidMap); + var parser = makeParser(this); + this.__addSerializerAndParser(serializer, parser); + } + CanSimpleDocument.prototype = new simpleDOM.Document(); + CanSimpleDocument.prototype.constructor = CanSimpleDocument; + module.exports = function () { + return new CanSimpleDocument(); + }; +}); +/*can-stache-bindings@5.0.4#test/helpers*/ +define('can-stache-bindings@5.0.4#test/helpers', [ + 'require', + 'exports', + 'module', + 'can-globals', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-dom-data', + 'can-vdom/make-document/make-document', + 'can-test-helpers', + 'can-queues' +], function (require, exports, module) { + (function (global, require, exports, module) { + var globals = require('can-globals'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var domData = require('can-dom-data'); + var makeDocument = require('can-vdom/make-document/make-document'); + var canTestHelpers = require('can-test-helpers'); + var queues = require('can-queues'); + var helpers = { + makeQUnitModule: function (name, doc, enableMO) { + QUnit.module(name, { + beforeEach: function () { + globals.setKeyValue('document', doc); + if (!enableMO) { + globals.setKeyValue('MutationObserver', null); + } + if (doc === document) { + this.fixture = document.getElementById('qunit-fixture'); + } else { + this.fixture = doc.createElement('qunit-fixture'); + doc.body.appendChild(this.fixture); + } + }, + afterEach: function (assert) { + if (doc !== document) { + doc.body.removeChild(this.fixture); + } + var done = assert.async(); + helpers.afterMutation(function () { + globals.deleteKeyValue('document'); + globals.deleteKeyValue('MutationObserver'); + var fixture = document.getElementById('qunit-fixture'); + while (fixture && fixture.hasChildNodes()) { + domData.delete(fixture.lastChild); + fixture.removeChild(fixture.lastChild); + } + done(); + }); + } + }); + }, + afterMutation: function (cb) { + var doc = globals.getKeyValue('document'); + var div = doc.createElement('div'); + var undo = domMutate.onNodeConnected(div, function () { + undo(); + doc.body.removeChild(div); + setTimeout(cb, 5); + }); + setTimeout(function () { + domMutateNode.appendChild.call(doc.body, div); + }, 10); + }, + makeTests: function (name, makeTest) { + var noop = function () { + }; + helpers.makeQUnitModule(name + ' - dom', document, true); + makeTest(name + ' - dom', document, true, QUnit.test, noop); + makeTest(name + ' - dom - dev only', document, true, noop, canTestHelpers.dev.devOnlyTest); + var doc = makeDocument(); + helpers.makeQUnitModule(name + ' - vdom', doc, false); + makeTest(name + ' - vdom', doc, false, noop, noop); + }, + interceptDomEvents: function (addFn, removeFn) { + var realAddEventListener = domEvents.addEventListener; + var realRemoveEventListener = domEvents.removeEventListener; + domEvents.addEventListener = function (eventName) { + addFn.call(this, arguments); + return realAddEventListener.apply(this, arguments); + }; + domEvents.removeEventListener = function (eventName) { + removeFn.call(this, arguments); + return realRemoveEventListener.apply(this, arguments); + }; + return function undo() { + domEvents.addEventListener = realAddEventListener; + domEvents.removeEventListener = realRemoveEventListener; + }; + }, + cleanupQueues: function () { + while (queues.batch.isCollecting()) { + queues.batch.stop(); + } + } + }; + module.exports = helpers; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-bindings@5.0.4#test/mock-component-simple-map*/ +define('can-stache-bindings@5.0.4#test/mock-component-simple-map', [ + 'require', + 'exports', + 'module', + 'can-stache-bindings', + 'can-simple-map', + 'can-view-callbacks', + 'can-symbol', + 'can-dom-data', + 'can-dom-mutate/node', + 'can-dom-mutate' +], function (require, exports, module) { + var stacheBindings = require('can-stache-bindings'); + var CanSimpleMap = require('can-simple-map'); + var viewCallbacks = require('can-view-callbacks'); + var canSymbol = require('can-symbol'); + var domData = require('can-dom-data'); + var domMutateNode = require('can-dom-mutate/node'); + var domMutate = require('can-dom-mutate'); + var MockComponent; + module.exports = MockComponent = { + extend: function (proto) { + viewCallbacks.tag(proto.tag, function (el, componentTagData) { + var viewModel; + var teardownBindings = stacheBindings.behaviors.viewModel(el, componentTagData, function (initialViewModelData) { + if (typeof proto.viewModel === 'function') { + return viewModel = new proto.viewModel(initialViewModelData); + } else if (proto.viewModel instanceof CanSimpleMap) { + proto.viewModel.set(initialViewModelData); + return viewModel = proto.viewModel; + } else { + var VM = CanSimpleMap.extend(proto.viewModel); + return viewModel = new VM(initialViewModelData); + } + }, {}); + el[canSymbol.for('can.viewModel')] = viewModel; + el.viewModel = viewModel; + el[canSymbol.for('can.preventDataBindings')] = true; + if (proto.template) { + var shadowScope = componentTagData.scope.add(viewModel); + domData.set(el, 'shadowScope', shadowScope); + domMutate.onNodeRemoved(el, function () { + teardownBindings(); + }); + var frag = proto.template(shadowScope, componentTagData.options); + domMutateNode.appendChild.call(el, frag); + } + }); + } + }; +}); +/*can-stache-bindings@5.0.4#test/colon/basics-test*/ +define('can-stache-bindings@5.0.4#test/colon/basics-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache-bindings', + 'can-dom-events', + 'can-stache', + 'can-simple-map', + '../mock-component-simple-map', + 'can-attribute-encoder', + 'can-test-helpers' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + var stacheBindings = require('can-stache-bindings'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var SimpleMap = require('can-simple-map'); + var MockComponent = require('../mock-component-simple-map'); + var encoder = require('can-attribute-encoder'); + var canTestHelpers = require('can-test-helpers'); + function siblingsDataToInfo(siblingData) { + return { + parent: siblingData.parent.source, + child: siblingData.child.source, + childEvent: siblingData.child.event, + parentToChild: siblingData.parent.exports, + childToParent: siblingData.child.exports, + childName: siblingData.child.name, + parentName: siblingData.parent.name, + bindingAttributeName: siblingData.bindingAttributeName, + initializeValues: siblingData.initializeValues, + syncChildWithParent: siblingData.parent.syncSibling + }; + } + stache.addBindings(stacheBindings); + testHelpers.makeTests('can-stache-bindings - colon - basics', function (name, doc, enableMO) { + QUnit.test('basics', function (assert) { + assert.expect(5); + var viewModel = new SimpleMap({ + toChild: 'toChild', + toParent: 'toParent', + twoWay: 'twoWay' + }); + MockComponent.extend({ + tag: 'basic-colon', + viewModel: viewModel + }); + var template = stache(''); + var MySimpleMap = SimpleMap.extend({ + methodD: function () { + assert.ok(true, 'on:vmevent bindings work'); + } + }); + var parent = new MySimpleMap({ + valueA: 'A', + valueB: 'B', + valueC: 'C' + }); + template(parent); + assert.deepEqual(parent.get(), { + valueA: 'A', + valueB: 'toParent', + valueC: 'C' + }, 'initial scope values correct'); + assert.deepEqual(viewModel.get(), { + toChild: 'A', + toParent: 'toParent', + twoWay: 'C' + }, 'initial VM values correct'); + parent.set({ + valueA: 'a', + valueB: 'b', + valueC: 'c' + }); + assert.deepEqual(viewModel.get(), { + toChild: 'a', + toParent: 'toParent', + twoWay: 'c' + }, 'scope set VM values correct'); + viewModel.set({ + toChild: 'to-child', + toParent: 'to-parent', + twoWay: 'two-way' + }); + assert.deepEqual(parent.get(), { + valueA: 'a', + valueB: 'to-parent', + valueC: 'two-way' + }, 'vm set scope values correct'); + viewModel.dispatch({ type: 'vmevent' }); + }); + QUnit.test('getSiblingBindingData', function (assert) { + var info = stacheBindings.getSiblingBindingData({ + name: 'foo-ed:from', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from'); + info = stacheBindings.getSiblingBindingData({ + name: 'foo-ed:bind', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind'); + info = stacheBindings.getSiblingBindingData({ + name: 'foo-ed:to', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to'); + info = stacheBindings.getSiblingBindingData({ + name: 'foo-ed:from', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from, favorViewModel=true'); + info = stacheBindings.getSiblingBindingData({ + name: 'foo-ed:bind', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind, favorViewModel=true'); + info = stacheBindings.getSiblingBindingData({ + name: 'foo-ed:to', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to, favorViewModel=true'); + }); + QUnit.test('getSiblingBindingData for vm:', function (assert) { + var info = stacheBindings.getSiblingBindingData({ + name: 'vm:foo-ed:from', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from'); + info = stacheBindings.getSiblingBindingData({ + name: 'vm:foo-ed:bind', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind'); + info = stacheBindings.getSiblingBindingData({ + name: 'vm:foo-ed:to', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to'); + info = stacheBindings.getSiblingBindingData({ + name: 'vm:foo-ed:from', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from, favorViewModel=true'); + info = stacheBindings.getSiblingBindingData({ + name: 'vm:foo-ed:bind', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind, favorViewModel=true'); + info = stacheBindings.getSiblingBindingData({ + name: 'vm:foo-ed:to', + value: 'bar' + }, { favorViewModel: true }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModel', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'vm:foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to, favorViewModel=true'); + }); + QUnit.test('getSiblingBindingData for el:', function (assert) { + var info = stacheBindings.getSiblingBindingData({ + name: 'el:foo-ed:from', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from'); + info = stacheBindings.getSiblingBindingData({ + name: 'el:foo-ed:bind', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind'); + info = stacheBindings.getSiblingBindingData({ + name: 'el:foo-ed:to', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to'); + info = stacheBindings.getSiblingBindingData({ + name: 'el:foo-ed:from', + value: 'bar' + }, null, null, null, true); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: true, + childToParent: false, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:from', + initializeValues: true, + syncChildWithParent: false + }, ':from, favorViewModel=true'); + info = stacheBindings.getSiblingBindingData({ + name: 'el:foo-ed:bind', + value: 'bar' + }, null, null, null, true); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: true, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:bind', + initializeValues: true, + syncChildWithParent: true + }, ':bind, favorViewModel=true'); + info = stacheBindings.getSiblingBindingData({ + name: 'el:foo-ed:to', + value: 'bar' + }, null, null, null, true); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'attribute', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'foo-ed', + parentName: 'bar', + bindingAttributeName: 'el:foo-ed:to', + initializeValues: true, + syncChildWithParent: false + }, ':to, favorViewModel=true'); + }); + QUnit.test('getSiblingBindingData works for value:to:on:click (#269)', function (assert) { + var info = stacheBindings.getSiblingBindingData({ + name: 'value:to:on:click', + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: 'click', + parentToChild: false, + childToParent: true, + childName: 'value', + parentName: 'bar', + bindingAttributeName: 'value:to:on:click', + initializeValues: false, + syncChildWithParent: false + }, 'new vm binding'); + }); + QUnit.test('decode values with To (#504)', function (assert) { + var name = encoder.encode('goToHome:to'); + var info = stacheBindings.getSiblingBindingData({ + name: name, + value: 'bar' + }); + assert.deepEqual(siblingsDataToInfo(info), { + parent: 'scope', + child: 'viewModelOrAttribute', + childEvent: undefined, + parentToChild: false, + childToParent: true, + childName: 'goToHome', + parentName: 'bar', + bindingAttributeName: 'goToHome:to', + initializeValues: true, + syncChildWithParent: false + }, 'to parent binding'); + }); + canTestHelpers.dev.devOnlyTest('warning when binding to non-existing value (#136) (#119)', function (assert) { + var teardown = canTestHelpers.dev.willWarn('This element does not have a viewModel. (Attempting to bind `target:vm:bind="source.bar"`)'); + var template = stache('
      '); + var map = new SimpleMap({ source: new SimpleMap({ foo: 'foo' }) }); + template(map); + assert.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('parent stache is able to teardown child bindings (#278)', function (assert) { + var map = new SimpleMap({ value: 'VALUE' }); + var template = stache('
      {{#if value}}{{/if}}
      '); + var frag = template(map), input = frag.firstChild.getElementsByTagName('input')[0]; + this.fixture.appendChild(frag); + assert.equal(input.value, 'VALUE', 'value set initially'); + map.set('value', ''); + assert.equal(input.value, 'VALUE', 'value should not have been updated'); + }); + QUnit.test('bindings still work for moved elements (#460)', function (assert) { + var done = assert.async(); + var map = new SimpleMap({ value: 'first' }); + var template = stache(''); + var frag = template(map); + var input = frag.firstChild; + this.fixture.appendChild(frag); + var div = doc.createElement('div'); + this.fixture.appendChild(div); + div.appendChild(input); + testHelpers.afterMutation(function () { + map.set('value', 'second'); + assert.equal(input.value, 'second', 'value should have been updated'); + input.value = 'third'; + domEvents.dispatch(input, 'change'); + assert.equal(map.get('value'), 'third', 'map should have been updated'); + done(); + }); + }); + }); +}); +/*can-string-to-any@1.2.1#can-string-to-any*/ +define('can-string-to-any@1.2.1#can-string-to-any', function (require, exports, module) { + 'use strict'; + module.exports = function (str) { + switch (str) { + case 'NaN': + case 'Infinity': + return +str; + case 'null': + return null; + case 'undefined': + return undefined; + case 'true': + case 'false': + return str === 'true'; + default: + var val = +str; + if (!isNaN(val)) { + return val; + } else { + return str; + } + } + }; +}); +/*can-data-types@1.2.1#maybe-boolean/maybe-boolean*/ +define('can-data-types@1.2.1#maybe-boolean/maybe-boolean', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function toBoolean(val) { + if (val == null) { + return val; + } + if (val === 'false' || val === '0' || !val) { + return false; + } + return true; + } + module.exports = canReflect.assignSymbols(toBoolean, { + 'can.new': toBoolean, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + true, + false, + undefined, + null + ] + }; + }, + 'can.getName': function () { + return 'MaybeBoolean'; + }, + 'can.isMember': function (value) { + return value == null || typeof value === 'boolean'; + } + }); +}); +/*can-data-types@1.2.1#maybe-date/maybe-date*/ +define('can-data-types@1.2.1#maybe-date/maybe-date', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function toDate(str) { + var type = typeof str; + if (type === 'string') { + str = Date.parse(str); + return isNaN(str) ? null : new Date(str); + } else if (type === 'number') { + return new Date(str); + } else { + return str; + } + } + function DateStringSet(dateStr) { + this.setValue = dateStr; + var date = toDate(dateStr); + this.value = date == null ? date : date.getTime(); + } + DateStringSet.prototype.valueOf = function () { + return this.value; + }; + canReflect.assignSymbols(DateStringSet.prototype, { + 'can.serialize': function () { + return this.setValue; + } + }); + module.exports = canReflect.assignSymbols(toDate, { + 'can.new': toDate, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Date, + undefined, + null + ] + }; + }, + 'can.ComparisonSetType': DateStringSet, + 'can.getName': function () { + return 'MaybeDate'; + }, + 'can.isMember': function (value) { + return value == null || value instanceof Date; + } + }); +}); +/*can-data-types@1.2.1#maybe-number/maybe-number*/ +define('can-data-types@1.2.1#maybe-number/maybe-number', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function toNumber(val) { + if (val == null) { + return val; + } + return +val; + } + module.exports = canReflect.assignSymbols(toNumber, { + 'can.new': toNumber, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Number, + undefined, + null + ] + }; + }, + 'can.getName': function () { + return 'MaybeNumber'; + }, + 'can.isMember': function (value) { + return value == null || typeof value === 'number'; + } + }); +}); +/*can-data-types@1.2.1#maybe-string/maybe-string*/ +define('can-data-types@1.2.1#maybe-string/maybe-string', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + function toString(val) { + if (val == null) { + return val; + } + return '' + val; + } + module.exports = canReflect.assignSymbols(toString, { + 'can.new': toString, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + String, + undefined, + null + ] + }; + }, + 'can.getName': function () { + return 'MaybeString'; + }, + 'can.isMember': function (value) { + return value == null || typeof value === 'string'; + } + }); +}); +/*can-define@2.8.0#can-define*/ +define('can-define@2.8.0#can-define', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-symbol', + 'can-reflect', + 'can-observation', + 'can-observation-recorder', + 'can-simple-observable/async/async', + 'can-simple-observable/settable/settable', + 'can-simple-observable/resolver/resolver', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + 'can-queues', + 'can-assign', + 'can-log/dev/dev', + 'can-string-to-any', + 'can-define-lazy-value', + 'can-data-types/maybe-boolean/maybe-boolean', + 'can-data-types/maybe-date/maybe-date', + 'can-data-types/maybe-number/maybe-number', + 'can-data-types/maybe-string/maybe-string' +], function (require, exports, module) { + 'use strict'; + 'format cjs'; + var ns = require('can-namespace'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var AsyncObservable = require('can-simple-observable/async/async'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var ResolverObservable = require('can-simple-observable/resolver/resolver'); + var eventQueue = require('can-event-queue/map/map'); + var addTypeEvents = require('can-event-queue/type/type'); + var queues = require('can-queues'); + var assign = require('can-assign'); + var canLogDev = require('can-log/dev/dev'); + var stringToAny = require('can-string-to-any'); + var defineLazyValue = require('can-define-lazy-value'); + var MaybeBoolean = require('can-data-types/maybe-boolean/maybe-boolean'), MaybeDate = require('can-data-types/maybe-date/maybe-date'), MaybeNumber = require('can-data-types/maybe-number/maybe-number'), MaybeString = require('can-data-types/maybe-string/maybe-string'); + var newSymbol = canSymbol.for('can.new'), serializeSymbol = canSymbol.for('can.serialize'), inSetupSymbol = canSymbol.for('can.initializing'); + var eventsProto, define, make, makeDefinition, getDefinitionsAndMethods, getDefinitionOrMethod; + function isDefineType(func) { + return func && (func.canDefineType === true || func[newSymbol]); + } + var peek = ObservationRecorder.ignore(canReflect.getValue.bind(canReflect)); + var Object_defineNamedPrototypeProperty = Object.defineProperty; + function defineConfigurableAndNotEnumerable(obj, prop, value) { + Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: value + }); + } + function eachPropertyDescriptor(map, cb) { + for (var prop in map) { + if (map.hasOwnProperty(prop)) { + cb.call(map, prop, Object.getOwnPropertyDescriptor(map, prop)); + } + } + } + function getEveryPropertyAndSymbol(obj) { + var props = Object.getOwnPropertyNames(obj); + var symbols = 'getOwnPropertySymbols' in Object ? Object.getOwnPropertySymbols(obj) : []; + return props.concat(symbols); + } + function cleanUpDefinition(prop, definition, shouldWarn, typePrototype) { + if (definition.value !== undefined && (typeof definition.value !== 'function' || definition.value.length === 0)) { + definition.default = definition.value; + delete definition.value; + } + if (definition.Value !== undefined) { + definition.Default = definition.Value; + delete definition.Value; + } + } + function isValueResolver(definition) { + return typeof definition.value === 'function' && definition.value.length; + } + module.exports = define = ns.define = function (typePrototype, defines, baseDefine) { + var prop, dataInitializers = Object.create(baseDefine ? baseDefine.dataInitializers : null), computedInitializers = Object.create(baseDefine ? baseDefine.computedInitializers : null); + var result = getDefinitionsAndMethods(defines, baseDefine, typePrototype); + result.dataInitializers = dataInitializers; + result.computedInitializers = computedInitializers; + canReflect.eachKey(result.definitions, function (definition, property) { + define.property(typePrototype, property, definition, dataInitializers, computedInitializers, result.defaultDefinition); + }); + if (typePrototype.hasOwnProperty('_data')) { + for (prop in dataInitializers) { + defineLazyValue(typePrototype._data, prop, dataInitializers[prop].bind(typePrototype), true); + } + } else { + defineLazyValue(typePrototype, '_data', function () { + var map = this; + var data = {}; + for (var prop in dataInitializers) { + defineLazyValue(data, prop, dataInitializers[prop].bind(map), true); + } + return data; + }); + } + if (typePrototype.hasOwnProperty('_computed')) { + for (prop in computedInitializers) { + defineLazyValue(typePrototype._computed, prop, computedInitializers[prop].bind(typePrototype)); + } + } else { + defineLazyValue(typePrototype, '_computed', function () { + var map = this; + var data = Object.create(null); + for (var prop in computedInitializers) { + defineLazyValue(data, prop, computedInitializers[prop].bind(map)); + } + return data; + }); + } + getEveryPropertyAndSymbol(eventsProto).forEach(function (prop) { + Object.defineProperty(typePrototype, prop, { + enumerable: false, + value: eventsProto[prop], + configurable: true, + writable: true + }); + }); + Object.defineProperty(typePrototype, '_define', { + enumerable: false, + value: result, + configurable: true, + writable: true + }); + var iteratorSymbol = canSymbol.iterator || canSymbol.for('iterator'); + if (!typePrototype[iteratorSymbol]) { + defineConfigurableAndNotEnumerable(typePrototype, iteratorSymbol, function () { + return new define.Iterator(this); + }); + } + return result; + }; + var onlyType = function (obj) { + for (var prop in obj) { + if (prop !== 'type') { + return false; + } + } + return true; + }; + define.extensions = function () { + }; + define.property = function (typePrototype, prop, definition, dataInitializers, computedInitializers, defaultDefinition) { + var propertyDefinition = define.extensions.apply(this, arguments); + if (propertyDefinition) { + definition = makeDefinition(prop, propertyDefinition, defaultDefinition || {}, typePrototype); + } + var type = definition.type; + if (type && onlyType(definition) && type === define.types['*']) { + Object_defineNamedPrototypeProperty(typePrototype, prop, { + get: make.get.data(prop), + set: make.set.events(prop, make.get.data(prop), make.set.data(prop), make.eventType.data(prop)), + enumerable: true, + configurable: true + }); + return; + } + definition.type = type; + var dataProperty = definition.get || isValueResolver(definition) ? 'computed' : 'data', reader = make.read[dataProperty](prop), getter = make.get[dataProperty](prop), setter = make.set[dataProperty](prop), getInitialValue; + var typeConvert = function (val) { + return val; + }; + if (definition.Type) { + typeConvert = make.set.Type(prop, definition.Type, typeConvert); + } + if (type) { + typeConvert = make.set.type(prop, type, typeConvert); + } + var eventsSetter = make.set.events(prop, reader, setter, make.eventType[dataProperty](prop)); + if (isValueResolver(definition)) { + computedInitializers[prop] = make.valueResolver(prop, definition, typeConvert); + } else if (definition.default !== undefined || definition.Default !== undefined) { + getInitialValue = ObservationRecorder.ignore(make.get.defaultValue(prop, definition, typeConvert, eventsSetter)); + } + if (definition.get) { + computedInitializers[prop] = make.compute(prop, definition.get, getInitialValue); + } else if (getInitialValue) { + dataInitializers[prop] = getInitialValue; + } + if (definition.get && definition.set) { + setter = make.set.setter(prop, definition.set, make.read.lastSet(prop), setter, true); + if (definition.get.length === 0) { + } + } else if (definition.set) { + setter = make.set.setter(prop, definition.set, reader, eventsSetter, false); + } else if (dataProperty === 'data') { + setter = eventsSetter; + } else if (definition.get && definition.get.length < 1) { + setter = function () { + }; + } + if (type) { + setter = make.set.type(prop, type, setter); + } + if (definition.Type) { + setter = make.set.Type(prop, definition.Type, setter); + } + Object_defineNamedPrototypeProperty(typePrototype, prop, { + get: getter, + set: setter, + enumerable: 'serialize' in definition ? !!definition.serialize : !definition.get, + configurable: true + }); + }; + define.makeDefineInstanceKey = function (constructor) { + constructor[canSymbol.for('can.defineInstanceKey')] = function (property, value) { + var defineResult = this.prototype._define; + if (typeof value === 'object') { + cleanUpDefinition(property, value, false, this); + } + var definition = getDefinitionOrMethod(property, value, defineResult.defaultDefinition, this); + if (definition && typeof definition === 'object') { + define.property(constructor.prototype, property, definition, defineResult.dataInitializers, defineResult.computedInitializers, defineResult.defaultDefinition); + defineResult.definitions[property] = definition; + } else { + defineResult.methods[property] = definition; + } + this.prototype.dispatch({ + action: 'can.keys', + type: 'can.keys', + target: this.prototype + }); + }; + }; + define.Constructor = function (defines, sealed) { + var constructor = function DefineConstructor(props) { + Object.defineProperty(this, inSetupSymbol, { + configurable: true, + enumerable: false, + value: true, + writable: true + }); + define.setup.call(this, props, sealed); + this[inSetupSymbol] = false; + }; + var result = define(constructor.prototype, defines); + addTypeEvents(constructor); + define.makeDefineInstanceKey(constructor, result); + return constructor; + }; + make = { + computeObj: function (map, prop, observable) { + var computeObj = { + oldValue: undefined, + compute: observable, + count: 0, + handler: function (newVal) { + var oldValue = computeObj.oldValue; + computeObj.oldValue = newVal; + map.dispatch({ + action: 'set', + key: 'prop', + target: map, + value: newVal, + oldValue: oldValue, + type: prop + }, [ + newVal, + oldValue + ]); + } + }; + return computeObj; + }, + valueResolver: function (prop, definition, typeConvert) { + var getDefault = make.get.defaultValue(prop, definition, typeConvert); + return function () { + var map = this; + var defaultValue = getDefault.call(this); + var computeObj = make.computeObj(map, prop, new ResolverObservable(definition.value, map, defaultValue)); + return computeObj; + }; + }, + compute: function (prop, get, defaultValueFn) { + return function () { + var map = this, defaultValue = defaultValueFn && defaultValueFn.call(this), observable, computeObj; + if (get.length === 0) { + observable = new Observation(get, map); + } else if (get.length === 1) { + observable = new SettableObservable(get, map, defaultValue); + } else { + observable = new AsyncObservable(get, map, defaultValue); + } + computeObj = make.computeObj(map, prop, observable); + return computeObj; + }; + }, + set: { + data: function (prop) { + return function (newVal) { + this._data[prop] = newVal; + }; + }, + computed: function (prop) { + return function (val) { + canReflect.setValue(this._computed[prop].compute, val); + }; + }, + events: function (prop, getCurrent, setData, eventType) { + return function (newVal) { + if (this[inSetupSymbol]) { + setData.call(this, newVal); + } else { + var current = getCurrent.call(this); + if (newVal === current) { + return; + } + var dispatched; + setData.call(this, newVal); + dispatched = { + patches: [{ + type: 'set', + key: prop, + value: newVal + }], + target: this, + action: 'set', + value: newVal, + oldValue: current, + key: prop, + type: prop + }; + this.dispatch(dispatched, [ + newVal, + current + ]); + } + }; + }, + setter: function (prop, setter, getCurrent, setEvents, hasGetter) { + return function (value) { + var self = this; + queues.batch.start(); + var setterCalled = false, current = getCurrent.call(this), setValue = setter.call(this, value, function (value) { + setEvents.call(self, value); + setterCalled = true; + }, current); + if (setterCalled) { + queues.batch.stop(); + } else { + if (hasGetter) { + if (setValue !== undefined) { + if (current !== setValue) { + setEvents.call(this, setValue); + } + queues.batch.stop(); + } else if (setter.length === 0) { + setEvents.call(this, value); + queues.batch.stop(); + return; + } else if (setter.length === 1) { + queues.batch.stop(); + } else { + queues.batch.stop(); + return; + } + } else { + if (setValue !== undefined) { + setEvents.call(this, setValue); + queues.batch.stop(); + } else if (setter.length === 0) { + setEvents.call(this, value); + queues.batch.stop(); + return; + } else if (setter.length === 1) { + setEvents.call(this, undefined); + queues.batch.stop(); + } else { + queues.batch.stop(); + return; + } + } + } + }; + }, + type: function (prop, type, set) { + function setter(newValue) { + return set.call(this, type.call(this, newValue, prop)); + } + if (isDefineType(type)) { + if (type.canDefineType) { + return setter; + } else { + return function setter(newValue) { + return set.call(this, canReflect.convert(newValue, type)); + }; + } + } + if (typeof type === 'object') { + return make.set.Type(prop, type, set); + } else { + return setter; + } + }, + Type: function (prop, Type, set) { + if (Array.isArray(Type) && define.DefineList) { + Type = define.DefineList.extend({ '#': Type[0] }); + } else if (typeof Type === 'object') { + if (define.DefineMap) { + Type = define.DefineMap.extend(Type); + } else { + Type = define.Constructor(Type); + } + } + return function (newValue) { + if (newValue instanceof Type || newValue == null) { + return set.call(this, newValue); + } else { + return set.call(this, new Type(newValue)); + } + }; + } + }, + eventType: { + data: function (prop) { + return function (newVal, oldVal) { + return oldVal !== undefined || this._data.hasOwnProperty(prop) ? 'set' : 'add'; + }; + }, + computed: function () { + return function () { + return 'set'; + }; + } + }, + read: { + data: function (prop) { + return function () { + return this._data[prop]; + }; + }, + computed: function (prop) { + return function () { + return canReflect.getValue(this._computed[prop].compute); + }; + }, + lastSet: function (prop) { + return function () { + var observable = this._computed[prop].compute; + if (observable.lastSetValue) { + return canReflect.getValue(observable.lastSetValue); + } + }; + } + }, + get: { + defaultValue: function (prop, definition, typeConvert, callSetter) { + return function () { + var value = definition.default; + if (value !== undefined) { + if (typeof value === 'function') { + value = value.call(this); + } + value = typeConvert.call(this, value); + } else { + var Default = definition.Default; + if (Default) { + value = typeConvert.call(this, new Default()); + } + } + if (definition.set) { + var VALUE; + var sync = true; + var setter = make.set.setter(prop, definition.set, function () { + }, function (value) { + if (sync) { + VALUE = value; + } else { + callSetter.call(this, value); + } + }, definition.get); + setter.call(this, value); + sync = false; + return VALUE; + } + return value; + }; + }, + data: function (prop) { + return function () { + if (!this[inSetupSymbol]) { + ObservationRecorder.add(this, prop); + } + return this._data[prop]; + }; + }, + computed: function (prop) { + return function (val) { + var compute = this._computed[prop].compute; + if (ObservationRecorder.isRecording()) { + ObservationRecorder.add(this, prop); + if (!canReflect.isBound(compute)) { + Observation.temporarilyBind(compute); + } + } + return peek(compute); + }; + } + } + }; + define.behaviors = [ + 'get', + 'set', + 'value', + 'Value', + 'type', + 'Type', + 'serialize' + ]; + var addBehaviorToDefinition = function (definition, behavior, value) { + if (behavior === 'enumerable') { + definition.serialize = !!value; + } else if (behavior === 'type') { + var behaviorDef = value; + if (typeof behaviorDef === 'string') { + behaviorDef = define.types[behaviorDef]; + if (typeof behaviorDef === 'object' && !isDefineType(behaviorDef)) { + assign(definition, behaviorDef); + behaviorDef = behaviorDef[behavior]; + } + } + if (typeof behaviorDef !== 'undefined') { + definition[behavior] = behaviorDef; + } + } else { + definition[behavior] = value; + } + }; + makeDefinition = function (prop, def, defaultDefinition, typePrototype) { + var definition = {}; + canReflect.eachKey(def, function (value, behavior) { + addBehaviorToDefinition(definition, behavior, value); + }); + canReflect.eachKey(defaultDefinition, function (value, prop) { + if (definition[prop] === undefined) { + if (prop !== 'type' && prop !== 'Type') { + definition[prop] = value; + } + } + }); + if (def.Type) { + var value = def.Type; + var serialize = value[serializeSymbol]; + if (serialize) { + definition.serialize = function (val) { + return serialize.call(val); + }; + } + if (value[newSymbol]) { + definition.type = value; + delete definition.Type; + } + } + if (typeof def.type !== 'string') { + if (!definition.type && !definition.Type) { + var defaultsCopy = canReflect.assignMap({}, defaultDefinition); + definition = canReflect.assignMap(defaultsCopy, definition); + } + if (canReflect.size(definition) === 0) { + definition.type = define.types['*']; + } + } + cleanUpDefinition(prop, definition, true, typePrototype); + return definition; + }; + getDefinitionOrMethod = function (prop, value, defaultDefinition, typePrototype) { + var definition; + if (typeof value === 'string') { + definition = { type: value }; + } else if (value && (value[serializeSymbol] || value[newSymbol])) { + definition = { Type: value }; + } else if (typeof value === 'function') { + if (canReflect.isConstructorLike(value)) { + definition = { Type: value }; + } + } else if (Array.isArray(value)) { + definition = { Type: value }; + } else if (canReflect.isPlainObject(value)) { + definition = value; + } + if (definition) { + return makeDefinition(prop, definition, defaultDefinition, typePrototype); + } else { + return value; + } + }; + getDefinitionsAndMethods = function (defines, baseDefines, typePrototype) { + var definitions = Object.create(baseDefines ? baseDefines.definitions : null); + var methods = {}; + var defaults = defines['*'], defaultDefinition; + if (defaults) { + delete defines['*']; + defaultDefinition = getDefinitionOrMethod('*', defaults, {}); + } else { + defaultDefinition = Object.create(null); + } + eachPropertyDescriptor(defines, function (prop, propertyDescriptor) { + var value; + if (propertyDescriptor.get || propertyDescriptor.set) { + value = { + get: propertyDescriptor.get, + set: propertyDescriptor.set + }; + } else { + value = propertyDescriptor.value; + } + if (prop === 'constructor') { + methods[prop] = value; + return; + } else { + var result = getDefinitionOrMethod(prop, value, defaultDefinition, typePrototype); + if (result && typeof result === 'object' && canReflect.size(result) > 0) { + definitions[prop] = result; + } else { + if (typeof result === 'function') { + methods[prop] = result; + } + } + } + }); + if (defaults) { + defineConfigurableAndNotEnumerable(defines, '*', defaults); + } + return { + definitions: definitions, + methods: methods, + defaultDefinition: defaultDefinition + }; + }; + eventsProto = eventQueue({}); + function setupComputed(instance, eventName) { + var computedBinding = instance._computed && instance._computed[eventName]; + if (computedBinding && computedBinding.compute) { + if (!computedBinding.count) { + computedBinding.count = 1; + canReflect.onValue(computedBinding.compute, computedBinding.handler, 'notify'); + computedBinding.oldValue = peek(computedBinding.compute); + } else { + computedBinding.count++; + } + } + } + function teardownComputed(instance, eventName) { + var computedBinding = instance._computed && instance._computed[eventName]; + if (computedBinding) { + if (computedBinding.count === 1) { + computedBinding.count = 0; + canReflect.offValue(computedBinding.compute, computedBinding.handler, 'notify'); + } else { + computedBinding.count--; + } + } + } + var canMetaSymbol = canSymbol.for('can.meta'); + assign(eventsProto, { + _eventSetup: function () { + }, + _eventTeardown: function () { + }, + addEventListener: function (eventName, handler, queue) { + setupComputed(this, eventName); + return eventQueue.addEventListener.apply(this, arguments); + }, + removeEventListener: function (eventName, handler) { + teardownComputed(this, eventName); + return eventQueue.removeEventListener.apply(this, arguments); + } + }); + eventsProto.on = eventsProto.bind = eventsProto.addEventListener; + eventsProto.off = eventsProto.unbind = eventsProto.removeEventListener; + var onKeyValueSymbol = canSymbol.for('can.onKeyValue'); + var offKeyValueSymbol = canSymbol.for('can.offKeyValue'); + canReflect.assignSymbols(eventsProto, { + 'can.onKeyValue': function (key) { + setupComputed(this, key); + return eventQueue[onKeyValueSymbol].apply(this, arguments); + }, + 'can.offKeyValue': function (key) { + teardownComputed(this, key); + return eventQueue[offKeyValueSymbol].apply(this, arguments); + } + }); + delete eventsProto.one; + define.setup = function (props, sealed) { + Object.defineProperty(this, 'constructor', { + value: this.constructor, + enumerable: false, + writable: false + }); + Object.defineProperty(this, canMetaSymbol, { + value: Object.create(null), + enumerable: false, + writable: false + }); + var definitions = this._define.definitions; + var instanceDefinitions = Object.create(null); + var map = this; + canReflect.eachKey(props, function (value, prop) { + if (definitions[prop] !== undefined) { + map[prop] = value; + } else { + define.expando(map, prop, value); + } + }); + if (canReflect.size(instanceDefinitions) > 0) { + defineConfigurableAndNotEnumerable(this, '_instanceDefinitions', instanceDefinitions); + } + }; + var returnFirstArg = function (arg) { + return arg; + }; + define.expando = function (map, prop, value) { + if (define._specialKeys[prop]) { + return true; + } + var constructorDefines = map._define.definitions; + if (constructorDefines && constructorDefines[prop]) { + return; + } + var instanceDefines = map._instanceDefinitions; + if (!instanceDefines) { + if (Object.isSealed(map)) { + return; + } + Object.defineProperty(map, '_instanceDefinitions', { + configurable: true, + enumerable: false, + writable: true, + value: {} + }); + instanceDefines = map._instanceDefinitions; + } + if (!instanceDefines[prop]) { + var defaultDefinition = map._define.defaultDefinition || { type: define.types.observable }; + define.property(map, prop, defaultDefinition, {}, {}); + if (defaultDefinition.type) { + map._data[prop] = define.make.set.type(prop, defaultDefinition.type, returnFirstArg).call(map, value); + } else if (defaultDefinition.Type && canReflect.isConstructorLike(defaultDefinition.Type)) { + map._data[prop] = define.make.set.Type(prop, defaultDefinition.Type, returnFirstArg).call(map, value); + } else { + map._data[prop] = define.types.observable(value); + } + instanceDefines[prop] = defaultDefinition; + if (!map[inSetupSymbol]) { + queues.batch.start(); + map.dispatch({ + action: 'can.keys', + target: map, + type: 'can.keys' + }); + if (Object.prototype.hasOwnProperty.call(map._data, prop)) { + map.dispatch({ + action: 'add', + target: map, + value: map._data[prop], + oldValue: undefined, + key: prop, + type: prop, + patches: [{ + type: 'add', + key: prop, + value: map._data[prop] + }] + }, [ + map._data[prop], + undefined + ]); + } else { + map.dispatch({ + type: 'set', + target: map, + patches: [{ + type: 'add', + key: prop, + value: map._data[prop] + }] + }, [ + map._data[prop], + undefined + ]); + } + queues.batch.stop(); + } + return true; + } + }; + define.replaceWith = defineLazyValue; + define.eventsProto = eventsProto; + define.defineConfigurableAndNotEnumerable = defineConfigurableAndNotEnumerable; + define.make = make; + define.getDefinitionOrMethod = getDefinitionOrMethod; + define._specialKeys = { + _data: true, + _computed: true + }; + var simpleGetterSetters = {}; + define.makeSimpleGetterSetter = function (prop) { + if (simpleGetterSetters[prop] === undefined) { + var setter = make.set.events(prop, make.get.data(prop), make.set.data(prop), make.eventType.data(prop)); + simpleGetterSetters[prop] = { + get: make.get.data(prop), + set: function (newVal) { + return setter.call(this, define.types.observable(newVal)); + }, + enumerable: true, + configurable: true + }; + } + return simpleGetterSetters[prop]; + }; + define.Iterator = function (obj) { + this.obj = obj; + this.definitions = Object.keys(obj._define.definitions); + this.instanceDefinitions = obj._instanceDefinitions ? Object.keys(obj._instanceDefinitions) : Object.keys(obj); + this.hasGet = typeof obj.get === 'function'; + }; + define.Iterator.prototype.next = function () { + var key; + if (this.definitions.length) { + key = this.definitions.shift(); + var def = this.obj._define.definitions[key]; + if (def.get) { + return this.next(); + } + } else if (this.instanceDefinitions.length) { + key = this.instanceDefinitions.shift(); + } else { + return { + value: undefined, + done: true + }; + } + return { + value: [ + key, + this.hasGet ? this.obj.get(key) : this.obj[key] + ], + done: false + }; + }; + function isObservableValue(obj) { + return canReflect.isValueLike(obj) && canReflect.isObservableLike(obj); + } + define.types = { + 'date': MaybeDate, + 'number': MaybeNumber, + 'boolean': MaybeBoolean, + 'observable': function (newVal) { + if (Array.isArray(newVal) && define.DefineList) { + newVal = new define.DefineList(newVal); + } else if (canReflect.isPlainObject(newVal) && define.DefineMap) { + newVal = new define.DefineMap(newVal); + } + return newVal; + }, + 'stringOrObservable': function (newVal) { + if (Array.isArray(newVal)) { + return new define.DefaultList(newVal); + } else if (canReflect.isPlainObject(newVal)) { + return new define.DefaultMap(newVal); + } else { + return canReflect.convert(newVal, define.types.string); + } + }, + 'htmlbool': function (val) { + if (val === '') { + return true; + } + return !!stringToAny(val); + }, + '*': function (val) { + return val; + }, + 'any': function (val) { + return val; + }, + 'string': MaybeString, + 'compute': { + set: function (newValue, setVal, setErr, oldValue) { + if (isObservableValue(newValue)) { + return newValue; + } + if (isObservableValue(oldValue)) { + canReflect.setValue(oldValue, newValue); + return oldValue; + } + return newValue; + }, + get: function (value) { + return isObservableValue(value) ? canReflect.getValue(value) : value; + } + } + }; + define.updateSchemaKeys = function (schema, definitions) { + for (var prop in definitions) { + var definition = definitions[prop]; + if (definition.serialize !== false) { + if (definition.Type) { + schema.keys[prop] = definition.Type; + } else if (definition.type) { + schema.keys[prop] = definition.type; + } else { + schema.keys[prop] = function (val) { + return val; + }; + } + if (definitions[prop].identity === true) { + schema.identity.push(prop); + } + } + } + return schema; + }; +}); +/*can-define@2.8.0#ensure-meta*/ +define('can-define@2.8.0#ensure-meta', [ + 'require', + 'exports', + 'module', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + module.exports = function ensureMeta(obj) { + var metaSymbol = canSymbol.for('can.meta'); + var meta = obj[metaSymbol]; + if (!meta) { + meta = {}; + canReflect.setKeyValue(obj, metaSymbol, meta); + } + return meta; + }; +}); +/*can-define@2.8.0#define-helpers/define-helpers*/ +define('can-define@2.8.0#define-helpers/define-helpers', [ + 'require', + 'exports', + 'module', + 'can-define', + 'can-reflect', + 'can-queues', + 'can-log/dev/dev', + '../ensure-meta' +], function (require, exports, module) { + 'use strict'; + var define = require('can-define'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var dev = require('can-log/dev/dev'); + var ensureMeta = require('../ensure-meta'); + var defineHelpers = { + defineExpando: define.expando, + reflectSerialize: function (unwrapped) { + var constructorDefinitions = this._define.definitions; + var defaultDefinition = this._define.defaultDefinition; + this.forEach(function (val, name) { + var propDef = constructorDefinitions[name]; + if (propDef && typeof propDef.serialize === 'function') { + val = propDef.serialize.call(this, val, name); + } else if (defaultDefinition && typeof defaultDefinition.serialize === 'function') { + val = defaultDefinition.serialize.call(this, val, name); + } else { + val = canReflect.serialize(val); + } + if (val !== undefined) { + unwrapped[name] = val; + } + }, this); + return unwrapped; + }, + reflectUnwrap: function (unwrapped) { + this.forEach(function (value, key) { + if (value !== undefined) { + unwrapped[key] = canReflect.unwrap(value); + } + }); + return unwrapped; + }, + log: function (key) { + var instance = this; + var quoteString = function quoteString(x) { + return typeof x === 'string' ? JSON.stringify(x) : x; + }; + var meta = ensureMeta(instance); + var allowed = meta.allowedLogKeysSet || new Set(); + meta.allowedLogKeysSet = allowed; + if (key) { + allowed.add(key); + } + meta._log = function (event, data) { + var type = event.type; + if (type === 'can.onPatches' || key && !allowed.has(type) || type === 'can.keys' || key && !allowed.has(type)) { + return; + } + if (type === 'add' || type === 'remove') { + dev.log(canReflect.getName(instance), '\n how ', quoteString(type), '\n what ', quoteString(data[0]), '\n index ', quoteString(data[1])); + } else { + dev.log(canReflect.getName(instance), '\n key ', quoteString(type), '\n is ', quoteString(data[0]), '\n was ', quoteString(data[1])); + } + }; + }, + deleteKey: function (prop) { + var instanceDefines = this._instanceDefinitions; + if (instanceDefines && Object.prototype.hasOwnProperty.call(instanceDefines, prop) && !Object.isSealed(this)) { + delete instanceDefines[prop]; + queues.batch.start(); + this.dispatch({ + action: 'can.keys', + type: 'can.keys', + target: this + }); + var oldValue = this._data[prop]; + if (oldValue !== undefined) { + delete this._data[prop]; + this.dispatch({ + action: 'delete', + key: prop, + value: undefined, + oldValue: oldValue, + type: prop, + target: this, + patches: [{ + type: 'delete', + key: prop + }] + }, [ + undefined, + oldValue + ]); + } + queues.batch.stop(); + } else { + this.set(prop, undefined); + } + return this; + } + }; + module.exports = defineHelpers; +}); +/*can-define@2.8.0#list/list*/ +define('can-define@2.8.0#list/list', [ + 'require', + 'exports', + 'module', + 'can-construct', + 'can-define', + 'can-queues', + 'can-event-queue/type/type', + 'can-observation-recorder', + 'can-log', + 'can-log/dev/dev', + '../define-helpers/define-helpers', + 'can-assign', + 'can-diff/list/list', + 'can-namespace', + 'can-reflect', + 'can-symbol', + 'can-single-reference' +], function (require, exports, module) { + 'use strict'; + var Construct = require('can-construct'); + var define = require('can-define'); + var make = define.make; + var queues = require('can-queues'); + var addTypeEvents = require('can-event-queue/type/type'); + var ObservationRecorder = require('can-observation-recorder'); + var canLog = require('can-log'); + var canLogDev = require('can-log/dev/dev'); + var defineHelpers = require('../define-helpers/define-helpers'); + var assign = require('can-assign'); + var diff = require('can-diff/list/list'); + var ns = require('can-namespace'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var singleReference = require('can-single-reference'); + var splice = [].splice; + var runningNative = false; + var identity = function (x) { + return x; + }; + var localOnPatchesSymbol = 'can.patches'; + var makeFilterCallback = function (props) { + return function (item) { + for (var prop in props) { + if (item[prop] !== props[prop]) { + return false; + } + } + return true; + }; + }; + var onKeyValue = define.eventsProto[canSymbol.for('can.onKeyValue')]; + var offKeyValue = define.eventsProto[canSymbol.for('can.offKeyValue')]; + var getSchemaSymbol = canSymbol.for('can.getSchema'); + var inSetupSymbol = canSymbol.for('can.initializing'); + function getSchema() { + var definitions = this.prototype._define.definitions; + var schema = { + type: 'list', + keys: {} + }; + schema = define.updateSchemaKeys(schema, definitions); + if (schema.keys['#']) { + schema.values = definitions['#'].Type; + delete schema.keys['#']; + } + return schema; + } + var DefineList = Construct.extend('DefineList', { + setup: function (base) { + if (DefineList) { + addTypeEvents(this); + var prototype = this.prototype; + var result = define(prototype, prototype, base.prototype._define); + define.makeDefineInstanceKey(this, result); + var itemsDefinition = result.definitions['#'] || result.defaultDefinition; + if (itemsDefinition) { + if (itemsDefinition.Type) { + this.prototype.__type = make.set.Type('*', itemsDefinition.Type, identity); + } else if (itemsDefinition.type) { + this.prototype.__type = make.set.type('*', itemsDefinition.type, identity); + } + } + this[getSchemaSymbol] = getSchema; + } + } + }, { + setup: function (items) { + if (!this._define) { + Object.defineProperty(this, '_define', { + enumerable: false, + value: { + definitions: { + length: { type: 'number' }, + _length: { type: 'number' } + } + } + }); + Object.defineProperty(this, '_data', { + enumerable: false, + value: {} + }); + } + define.setup.call(this, {}, false); + Object.defineProperty(this, '_length', { + enumerable: false, + configurable: true, + writable: true, + value: 0 + }); + if (items) { + this.splice.apply(this, [ + 0, + 0 + ].concat(canReflect.toArray(items))); + } + }, + __type: define.types.observable, + _triggerChange: function (attr, how, newVal, oldVal) { + var index = +attr; + if (!isNaN(index)) { + var itemsDefinition = this._define.definitions['#']; + var patches, dispatched; + if (how === 'add') { + if (itemsDefinition && typeof itemsDefinition.added === 'function') { + ObservationRecorder.ignore(itemsDefinition.added).call(this, newVal, index); + } + patches = [{ + type: 'splice', + insert: newVal, + index: index, + deleteCount: 0 + }]; + dispatched = { + type: how, + action: 'splice', + insert: newVal, + index: index, + deleteCount: 0, + patches: patches + }; + this.dispatch(dispatched, [ + newVal, + index + ]); + } else if (how === 'remove') { + if (itemsDefinition && typeof itemsDefinition.removed === 'function') { + ObservationRecorder.ignore(itemsDefinition.removed).call(this, oldVal, index); + } + patches = [{ + type: 'splice', + index: index, + deleteCount: oldVal.length + }]; + dispatched = { + type: how, + patches: patches, + action: 'splice', + index: index, + deleteCount: oldVal.length, + target: this + }; + this.dispatch(dispatched, [ + oldVal, + index + ]); + } else { + this.dispatch(how, [ + newVal, + index + ]); + } + } else { + this.dispatch({ + type: '' + attr, + target: this + }, [ + newVal, + oldVal + ]); + } + }, + get: function (index) { + if (arguments.length) { + if (isNaN(index)) { + ObservationRecorder.add(this, index); + } else { + ObservationRecorder.add(this, 'length'); + } + return this[index]; + } else { + return canReflect.unwrap(this, Map); + } + }, + set: function (prop, value) { + if (typeof prop !== 'object') { + prop = isNaN(+prop) || prop % 1 ? prop : +prop; + if (typeof prop === 'number') { + if (typeof prop === 'number' && prop > this._length - 1) { + var newArr = new Array(prop + 1 - this._length); + newArr[newArr.length - 1] = value; + this.push.apply(this, newArr); + return newArr; + } + this.splice(prop, 1, value); + } else { + var defined = defineHelpers.defineExpando(this, prop, value); + if (!defined) { + this[prop] = value; + } + } + } else { + if (canReflect.isListLike(prop)) { + if (value) { + this.replace(prop); + } else { + canReflect.assignList(this, prop); + } + } else { + canReflect.assignMap(this, prop); + } + } + return this; + }, + assign: function (prop) { + if (canReflect.isListLike(prop)) { + canReflect.assignList(this, prop); + } else { + canReflect.assignMap(this, prop); + } + return this; + }, + update: function (prop) { + if (canReflect.isListLike(prop)) { + canReflect.updateList(this, prop); + } else { + canReflect.updateMap(this, prop); + } + return this; + }, + assignDeep: function (prop) { + if (canReflect.isListLike(prop)) { + canReflect.assignDeepList(this, prop); + } else { + canReflect.assignDeepMap(this, prop); + } + return this; + }, + updateDeep: function (prop) { + if (canReflect.isListLike(prop)) { + canReflect.updateDeepList(this, prop); + } else { + canReflect.updateDeepMap(this, prop); + } + return this; + }, + _items: function () { + var arr = []; + this._each(function (item) { + arr.push(item); + }); + return arr; + }, + _each: function (callback) { + for (var i = 0, len = this._length; i < len; i++) { + callback(this[i], i); + } + }, + splice: function (index, howMany) { + var args = canReflect.toArray(arguments), added = [], i, len, listIndex, allSame = args.length > 2, oldLength = this._length; + index = index || 0; + for (i = 0, len = args.length - 2; i < len; i++) { + listIndex = i + 2; + args[listIndex] = this.__type(args[listIndex], listIndex); + added.push(args[listIndex]); + if (this[i + index] !== args[listIndex]) { + allSame = false; + } + } + if (allSame && this._length <= added.length) { + return added; + } + if (howMany === undefined) { + howMany = args[1] = this._length - index; + } + runningNative = true; + var removed = splice.apply(this, args); + runningNative = false; + queues.batch.start(); + if (howMany > 0) { + this._triggerChange('' + index, 'remove', undefined, removed); + } + if (args.length > 2) { + this._triggerChange('' + index, 'add', added, removed); + } + this.dispatch('length', [ + this._length, + oldLength + ]); + queues.batch.stop(); + return removed; + }, + serialize: function () { + return canReflect.serialize(this, Map); + } + }); + for (var prop in define.eventsProto) { + Object.defineProperty(DefineList.prototype, prop, { + enumerable: false, + value: define.eventsProto[prop], + writable: true + }); + } + var eventsProtoSymbols = 'getOwnPropertySymbols' in Object ? Object.getOwnPropertySymbols(define.eventsProto) : [ + canSymbol.for('can.onKeyValue'), + canSymbol.for('can.offKeyValue') + ]; + eventsProtoSymbols.forEach(function (sym) { + Object.defineProperty(DefineList.prototype, sym, { + configurable: true, + enumerable: false, + value: define.eventsProto[sym], + writable: true + }); + }); + var getArgs = function (args) { + return args[0] && Array.isArray(args[0]) ? args[0] : canReflect.toArray(args); + }; + canReflect.eachKey({ + push: 'length', + unshift: 0 + }, function (where, name) { + var orig = [][name]; + DefineList.prototype[name] = function () { + var args = [], len = where ? this._length : 0, i = arguments.length, res, val; + while (i--) { + val = arguments[i]; + args[i] = this.__type(val, i); + } + runningNative = true; + res = orig.apply(this, args); + runningNative = false; + if (!this.comparator || args.length) { + queues.batch.start(); + this._triggerChange('' + len, 'add', args, undefined); + this.dispatch('length', [ + this._length, + len + ]); + queues.batch.stop(); + } + return res; + }; + }); + canReflect.eachKey({ + pop: 'length', + shift: 0 + }, function (where, name) { + var orig = [][name]; + DefineList.prototype[name] = function () { + if (!this._length) { + return undefined; + } + var args = getArgs(arguments), len = where && this._length ? this._length - 1 : 0, oldLength = this._length ? this._length : 0, res; + runningNative = true; + res = orig.apply(this, args); + runningNative = false; + queues.batch.start(); + this._triggerChange('' + len, 'remove', undefined, [res]); + this.dispatch('length', [ + this._length, + oldLength + ]); + queues.batch.stop(); + return res; + }; + }); + canReflect.eachKey({ + 'map': 3, + 'filter': 3, + 'reduce': 4, + 'reduceRight': 4, + 'every': 3, + 'some': 3 + }, function a(fnLength, fnName) { + DefineList.prototype[fnName] = function () { + var self = this; + var args = [].slice.call(arguments, 0); + var callback = args[0]; + var thisArg = args[fnLength - 1] || self; + if (typeof callback === 'object') { + callback = makeFilterCallback(callback); + } + args[0] = function () { + var cbArgs = [].slice.call(arguments, 0); + cbArgs[fnLength - 3] = self.get(cbArgs[fnLength - 2]); + return callback.apply(thisArg, cbArgs); + }; + var ret = Array.prototype[fnName].apply(this, args); + if (fnName === 'map') { + return new DefineList(ret); + } else if (fnName === 'filter') { + return new self.constructor(ret); + } else { + return ret; + } + }; + }); + assign(DefineList.prototype, { + includes: function () { + var arrayIncludes = Array.prototype.includes; + if (arrayIncludes) { + return function includes() { + return arrayIncludes.apply(this, arguments); + }; + } else { + return function includes() { + throw new Error('DefineList.prototype.includes must have Array.prototype.includes available. Please add a polyfill to this environment.'); + }; + } + }(), + indexOf: function (item, fromIndex) { + for (var i = fromIndex || 0, len = this.length; i < len; i++) { + if (this.get(i) === item) { + return i; + } + } + return -1; + }, + lastIndexOf: function (item, fromIndex) { + fromIndex = typeof fromIndex === 'undefined' ? this.length - 1 : fromIndex; + for (var i = fromIndex; i >= 0; i--) { + if (this.get(i) === item) { + return i; + } + } + return -1; + }, + join: function () { + ObservationRecorder.add(this, 'length'); + return [].join.apply(this, arguments); + }, + reverse: function () { + var list = [].reverse.call(this._items()); + return this.replace(list); + }, + slice: function () { + ObservationRecorder.add(this, 'length'); + var temp = Array.prototype.slice.apply(this, arguments); + return new this.constructor(temp); + }, + concat: function () { + var args = []; + canReflect.eachIndex(arguments, function (arg) { + if (canReflect.isListLike(arg)) { + var arr = Array.isArray(arg) ? arg : canReflect.toArray(arg); + arr.forEach(function (innerArg) { + args.push(this.__type(innerArg)); + }, this); + } else { + args.push(this.__type(arg)); + } + }, this); + return new this.constructor(Array.prototype.concat.apply(canReflect.toArray(this), args)); + }, + forEach: function (cb, thisarg) { + var item; + for (var i = 0, len = this.length; i < len; i++) { + item = this.get(i); + if (cb.call(thisarg || item, item, i, this) === false) { + break; + } + } + return this; + }, + replace: function (newList) { + var patches = diff(this, newList); + queues.batch.start(); + for (var i = 0, len = patches.length; i < len; i++) { + this.splice.apply(this, [ + patches[i].index, + patches[i].deleteCount + ].concat(patches[i].insert)); + } + queues.batch.stop(); + return this; + }, + sort: function (compareFunction) { + var sorting = Array.prototype.slice.call(this); + Array.prototype.sort.call(sorting, compareFunction); + this.splice.apply(this, [ + 0, + sorting.length + ].concat(sorting)); + return this; + } + }); + for (var prop in define.eventsProto) { + DefineList[prop] = define.eventsProto[prop]; + Object.defineProperty(DefineList.prototype, prop, { + enumerable: false, + value: define.eventsProto[prop], + writable: true + }); + } + Object.defineProperty(DefineList.prototype, 'length', { + get: function () { + if (!this[inSetupSymbol]) { + ObservationRecorder.add(this, 'length'); + } + return this._length; + }, + set: function (newVal) { + if (runningNative) { + this._length = newVal; + return; + } + if (newVal == null || isNaN(+newVal) || newVal === this._length) { + return; + } + if (newVal > this._length - 1) { + var newArr = new Array(newVal - this._length); + this.push.apply(this, newArr); + } else { + this.splice(newVal); + } + }, + enumerable: true + }); + DefineList.prototype.attr = function (prop, value) { + canLog.warn('DefineMap::attr shouldn\'t be called'); + if (arguments.length === 0) { + return this.get(); + } else if (prop && typeof prop === 'object') { + return this.set.apply(this, arguments); + } else if (arguments.length === 1) { + return this.get(prop); + } else { + return this.set(prop, value); + } + }; + DefineList.prototype.item = function (index, value) { + if (arguments.length === 1) { + return this.get(index); + } else { + return this.set(index, value); + } + }; + DefineList.prototype.items = function () { + canLog.warn('DefineList::get should should be used instead of DefineList::items'); + return this.get(); + }; + var defineListProto = { + 'can.isMoreListLikeThanMapLike': true, + 'can.isMapLike': true, + 'can.isListLike': true, + 'can.isValueLike': false, + 'can.getKeyValue': DefineList.prototype.get, + 'can.setKeyValue': DefineList.prototype.set, + 'can.onKeyValue': function (key, handler, queue) { + var translationHandler; + if (isNaN(key)) { + return onKeyValue.apply(this, arguments); + } else { + translationHandler = function () { + handler(this[key]); + }; + singleReference.set(handler, this, translationHandler, key); + return onKeyValue.call(this, 'length', translationHandler, queue); + } + }, + 'can.offKeyValue': function (key, handler, queue) { + var translationHandler; + if (isNaN(key)) { + return offKeyValue.apply(this, arguments); + } else { + translationHandler = singleReference.getAndDelete(handler, this, key); + return offKeyValue.call(this, 'length', translationHandler, queue); + } + }, + 'can.deleteKeyValue': function (prop) { + prop = isNaN(+prop) || prop % 1 ? prop : +prop; + if (typeof prop === 'number') { + this.splice(prop, 1); + } else if (prop === 'length' || prop === '_length') { + return; + } else { + this.set(prop, undefined); + } + return this; + }, + 'can.assignDeep': function (source) { + queues.batch.start(); + canReflect.assignList(this, source); + queues.batch.stop(); + }, + 'can.updateDeep': function (source) { + queues.batch.start(); + this.replace(source); + queues.batch.stop(); + }, + 'can.keyHasDependencies': function (key) { + return !!(this._computed && this._computed[key] && this._computed[key].compute); + }, + 'can.getKeyDependencies': function (key) { + var ret; + if (this._computed && this._computed[key] && this._computed[key].compute) { + ret = {}; + ret.valueDependencies = new Set(); + ret.valueDependencies.add(this._computed[key].compute); + } + return ret; + }, + 'can.splice': function (index, deleteCount, insert) { + this.splice.apply(this, [ + index, + deleteCount + ].concat(insert)); + }, + 'can.onPatches': function (handler, queue) { + this[canSymbol.for('can.onKeyValue')](localOnPatchesSymbol, handler, queue); + }, + 'can.offPatches': function (handler, queue) { + this[canSymbol.for('can.offKeyValue')](localOnPatchesSymbol, handler, queue); + } + }; + canReflect.assignSymbols(DefineList.prototype, defineListProto); + canReflect.setKeyValue(DefineList.prototype, canSymbol.iterator, function () { + var index = -1; + if (typeof this.length !== 'number') { + this.length = 0; + } + return { + next: function () { + index++; + return { + value: this[index], + done: index >= this.length + }; + }.bind(this) + }; + }); + define.DefineList = DefineList; + module.exports = ns.DefineList = DefineList; +}); +/*can-define@2.8.0#map/map*/ +define('can-define@2.8.0#map/map', [ + 'require', + 'exports', + 'module', + 'can-construct', + 'can-define', + '../define-helpers/define-helpers', + 'can-observation-recorder', + 'can-namespace', + 'can-log', + 'can-log/dev/dev', + 'can-reflect', + 'can-symbol', + 'can-queues', + 'can-event-queue/type/type' +], function (require, exports, module) { + 'use strict'; + var Construct = require('can-construct'); + var define = require('can-define'); + var defineHelpers = require('../define-helpers/define-helpers'); + var ObservationRecorder = require('can-observation-recorder'); + var ns = require('can-namespace'); + var canLog = require('can-log'); + var canLogDev = require('can-log/dev/dev'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var queues = require('can-queues'); + var addTypeEvents = require('can-event-queue/type/type'); + var keysForDefinition = function (definitions) { + var keys = []; + for (var prop in definitions) { + var definition = definitions[prop]; + if (typeof definition !== 'object' || ('serialize' in definition ? !!definition.serialize : !definition.get)) { + keys.push(prop); + } + } + return keys; + }; + function assign(source) { + queues.batch.start(); + canReflect.assignMap(this, source || {}); + queues.batch.stop(); + } + function update(source) { + queues.batch.start(); + canReflect.updateMap(this, source || {}); + queues.batch.stop(); + } + function assignDeep(source) { + queues.batch.start(); + canReflect.assignDeepMap(this, source || {}); + queues.batch.stop(); + } + function updateDeep(source) { + queues.batch.start(); + canReflect.updateDeepMap(this, source || {}); + queues.batch.stop(); + } + function setKeyValue(key, value) { + var defined = defineHelpers.defineExpando(this, key, value); + if (!defined) { + this[key] = value; + } + } + function getKeyValue(key) { + var value = this[key]; + if (value !== undefined || key in this || Object.isSealed(this)) { + return value; + } else { + ObservationRecorder.add(this, key); + return this[key]; + } + } + var getSchemaSymbol = canSymbol.for('can.getSchema'); + function getSchema() { + var def = this.prototype._define; + var definitions = def ? def.definitions : {}; + var schema = { + type: 'map', + identity: [], + keys: {} + }; + return define.updateSchemaKeys(schema, definitions); + } + var sealedSetup = function (props) { + define.setup.call(this, props || {}, this.constructor.seal); + }; + var DefineMap = Construct.extend('DefineMap', { + setup: function (base) { + var key, prototype = this.prototype; + if (DefineMap) { + var result = define(prototype, prototype, base.prototype._define); + define.makeDefineInstanceKey(this, result); + addTypeEvents(this); + for (key in DefineMap.prototype) { + define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]); + } + if (prototype.setup === DefineMap.prototype.setup) { + define.defineConfigurableAndNotEnumerable(prototype, 'setup', sealedSetup); + } + var _computedGetter = Object.getOwnPropertyDescriptor(prototype, '_computed').get; + Object.defineProperty(prototype, '_computed', { + configurable: true, + enumerable: false, + get: function () { + if (this === prototype) { + return; + } + return _computedGetter.call(this, arguments); + } + }); + } else { + for (key in prototype) { + define.defineConfigurableAndNotEnumerable(prototype, key, prototype[key]); + } + } + define.defineConfigurableAndNotEnumerable(prototype, 'constructor', this); + this[getSchemaSymbol] = getSchema; + } + }, { + setup: function (props, sealed) { + if (!this._define) { + Object.defineProperty(this, '_define', { + enumerable: false, + value: { definitions: {} } + }); + Object.defineProperty(this, '_data', { + enumerable: false, + value: {} + }); + } + define.setup.call(this, props || {}, sealed === true); + }, + get: function (prop) { + if (prop) { + return getKeyValue.call(this, prop); + } else { + return canReflect.unwrap(this, Map); + } + }, + set: function (prop, value) { + if (typeof prop === 'object') { + if (value === true) { + updateDeep.call(this, prop); + } else { + assignDeep.call(this, prop); + } + } else { + setKeyValue.call(this, prop, value); + } + return this; + }, + assignDeep: function (prop) { + assignDeep.call(this, prop); + return this; + }, + updateDeep: function (prop) { + updateDeep.call(this, prop); + return this; + }, + assign: function (prop) { + assign.call(this, prop); + return this; + }, + update: function (prop) { + update.call(this, prop); + return this; + }, + serialize: function () { + return canReflect.serialize(this, Map); + }, + deleteKey: defineHelpers.deleteKey, + forEach: function () { + var forEach = function (list, cb, thisarg) { + return canReflect.eachKey(list, cb, thisarg); + }, noObserve = ObservationRecorder.ignore(forEach); + return function (cb, thisarg, observe) { + return observe === false ? noObserve(this, cb, thisarg) : forEach(this, cb, thisarg); + }; + }(), + '*': { type: define.types.observable } + }); + var defineMapProto = { + 'can.isMapLike': true, + 'can.isListLike': false, + 'can.isValueLike': false, + 'can.getKeyValue': getKeyValue, + 'can.setKeyValue': setKeyValue, + 'can.deleteKeyValue': defineHelpers.deleteKey, + 'can.getOwnKeys': function () { + var keys = canReflect.getOwnEnumerableKeys(this); + if (this._computed) { + var computedKeys = canReflect.getOwnKeys(this._computed); + var key; + for (var i = 0; i < computedKeys.length; i++) { + key = computedKeys[i]; + if (keys.indexOf(key) < 0) { + keys.push(key); + } + } + } + return keys; + }, + 'can.getOwnEnumerableKeys': function () { + ObservationRecorder.add(this, 'can.keys'); + ObservationRecorder.add(Object.getPrototypeOf(this), 'can.keys'); + return keysForDefinition(this._define.definitions).concat(keysForDefinition(this._instanceDefinitions)); + }, + 'can.hasOwnKey': function (key) { + return Object.hasOwnProperty.call(this._define.definitions, key) || this._instanceDefinitions !== undefined && Object.hasOwnProperty.call(this._instanceDefinitions, key); + }, + 'can.hasKey': function (key) { + return key in this._define.definitions || this._instanceDefinitions !== undefined && key in this._instanceDefinitions; + }, + 'can.assignDeep': assignDeep, + 'can.updateDeep': updateDeep, + 'can.unwrap': defineHelpers.reflectUnwrap, + 'can.serialize': defineHelpers.reflectSerialize, + 'can.keyHasDependencies': function (key) { + return !!(this._computed && this._computed[key] && this._computed[key].compute); + }, + 'can.getKeyDependencies': function (key) { + var ret; + if (this._computed && this._computed[key] && this._computed[key].compute) { + ret = {}; + ret.valueDependencies = new Set(); + ret.valueDependencies.add(this._computed[key].compute); + } + return ret; + } + }; + canReflect.assignSymbols(DefineMap.prototype, defineMapProto); + canReflect.setKeyValue(DefineMap.prototype, canSymbol.iterator, function () { + return new define.Iterator(this); + }); + for (var prop in define.eventsProto) { + DefineMap[prop] = define.eventsProto[prop]; + Object.defineProperty(DefineMap.prototype, prop, { + enumerable: false, + value: define.eventsProto[prop], + writable: true + }); + } + function getSymbolsForIE(obj) { + return Object.getOwnPropertyNames(obj).filter(function (name) { + return name.indexOf('@@symbol') === 0; + }); + } + var eventsProtoSymbols = 'getOwnPropertySymbols' in Object ? Object.getOwnPropertySymbols(define.eventsProto) : getSymbolsForIE(define.eventsProto); + eventsProtoSymbols.forEach(function (sym) { + Object.defineProperty(DefineMap.prototype, sym, { + configurable: true, + enumerable: false, + value: define.eventsProto[sym], + writable: true + }); + }); + define.DefineMap = DefineMap; + Object.defineProperty(DefineMap.prototype, 'toObject', { + enumerable: false, + writable: true, + value: function () { + canLog.warn('Use DefineMap::get instead of DefineMap::toObject'); + return this.get(); + } + }); + module.exports = ns.DefineMap = DefineMap; +}); +/*can-stache-bindings@5.0.4#test/colon/element-test*/ +define('can-stache-bindings@5.0.4#test/colon/element-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache', + 'can-stache-bindings', + 'can-simple-map', + 'can-define/list/list', + '../mock-component-simple-map', + 'can-view-model', + 'can-simple-observable', + 'can-symbol', + 'can-reflect', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-dom-events', + 'can-define/map/map' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + var stache = require('can-stache'); + var stacheBindings = require('can-stache-bindings'); + var SimpleMap = require('can-simple-map'); + var DefineList = require('can-define/list/list'); + var MockComponent = require('../mock-component-simple-map'); + var canViewModel = require('can-view-model'); + var SimpleObservable = require('can-simple-observable'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var domEvents = require('can-dom-events'); + var DefineMap = require('can-define/map/map'); + stache.addBindings(stacheBindings); + testHelpers.makeTests('can-stache-bindings - colon - element', function (name, doc, enableMO, testIfRealDocument) { + QUnit.test(' value:bind input text', function (assert) { + var template = stache(''); + var map = new SimpleMap(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + assert.equal(input.value, '', 'input value set correctly if key does not exist in map'); + map.set('age', '30'); + assert.equal(input.value, '30', 'input value set correctly'); + map.set('age', '31'); + assert.equal(input.value, '31', 'input value update correctly'); + input.value = '32'; + domEvents.dispatch(input, 'change'); + assert.equal(map.get('age'), '32', 'updated from input'); + }); + QUnit.test(' el:prop:to/:from/:bind work (#280)', function (assert) { + var template = stache('' + '' + ''); + var scope = new SimpleMap({ + scope1: 'scope1', + scope2: 'scope2', + scope3: 'scope3' + }); + var frag = template(scope); + var ta = this.fixture; + ta.appendChild(frag); + var inputTo = ta.getElementsByTagName('input')[0]; + var inputFrom = ta.getElementsByTagName('input')[1]; + var inputBind = ta.getElementsByTagName('input')[2]; + assert.equal(scope.attr('scope1'), '1', 'el:value:to - scope value set from attribute'); + inputTo.value = '4'; + domEvents.dispatch(inputTo, 'change'); + assert.equal(scope.attr('scope1'), '4', 'el:value:to - scope updated when attribute changed'); + scope.attr('scope1', 'scope4'); + assert.equal(inputTo.value, '4', 'el:value:to - attribute not updated when scope changed'); + assert.equal(inputFrom.value, 'scope2', 'el:value:from - attribute set from scope'); + inputFrom.value = 'scope5'; + domEvents.dispatch(inputFrom, 'change'); + assert.equal(scope.attr('scope2'), 'scope2', 'el:value:from - scope not updated when attribute changed'); + scope.attr('scope2', 'scope6'); + assert.equal(inputFrom.value, 'scope6', 'el:value:from - attribute updated when scope changed'); + assert.equal(inputBind.value, 'scope3', 'el:value:bind - attribute set from scope prop (parent -> child wins)'); + inputBind.value = 'scope6'; + domEvents.dispatch(inputBind, 'change'); + assert.equal(scope.attr('scope3'), 'scope6', 'el:value:bind - scope updated when attribute changed'); + scope.attr('scope3', 'scope7'); + assert.equal(inputBind.value, 'scope7', 'el:value:bind - attribute updated when scope changed'); + }); + if (System.env !== 'canjs-test') { + QUnit.test(' dynamic attribute bindings (#2016)', function (assert) { + var done = assert.async(); + var template = stache(''); + var map = new SimpleMap({ + propName: 'first', + first: 'Justin', + last: 'Meyer' + }); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + testHelpers.afterMutation(function () { + assert.equal(input.value, 'Justin', 'input value set correctly if key does not exist in map'); + map.set('propName', 'last'); + testHelpers.afterMutation(function () { + assert.equal(input.value, 'Meyer', 'input value set correctly if key does not exist in map'); + input.value = 'Lueke'; + domEvents.dispatch(input, 'change'); + testHelpers.afterMutation(function () { + assert.equal(map.get('last'), 'Lueke', 'updated from input'); + done(); + }); + }); + }); + }); + } + QUnit.test('value:bind compute rejects new value (#887)', function (assert) { + var template = stache(''); + var compute = new SimpleObservable(30); + canReflect.assignSymbols(compute, { + 'can.setValue': function (newVal) { + if (isNaN(+newVal)) { + } else { + this.set(+newVal); + } + } + }); + var frag = template({ age: compute }); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + input.value = '30f'; + domEvents.dispatch(input, 'change'); + assert.equal(compute.get(), 30, 'Still the old value'); + assert.equal(input.value, '30', 'Text input has also not changed'); + }); + QUnit.test('value:from works with camelCase and kebab-case properties', function (assert) { + var template = stache('' + ''); + var map = new SimpleMap({}); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var camelPropInput = ta.getElementsByTagName('input')[0]; + var kebabPropInput = ta.getElementsByTagName('input')[1]; + assert.equal(camelPropInput.value, '', 'input bound to camelCase prop value set correctly if camelCase key does not exist in map'); + assert.equal(kebabPropInput.value, '', 'input bound to kebab-case prop value set correctly if kebab-case key does not exist in map'); + map.attr('theProp', '30'); + assert.equal(camelPropInput.value, '30', 'input bound to camelCase prop value set correctly when camelCase prop changes'); + assert.equal(kebabPropInput.value, '', 'input bound to kebab-case prop value not updated when camelCase prop changes'); + map.attr('theProp', '31'); + assert.equal(camelPropInput.value, '31', 'input bound to camelCase prop value updated correctly when camelCase prop changes'); + assert.ok(!kebabPropInput.value, 'input bound to kebab-case prop value not updated when camelCase prop changes'); + camelPropInput.value = '32'; + domEvents.dispatch(camelPropInput, 'change'); + assert.equal(map.attr('theProp'), '31', 'camelCase prop NOT updated when input bound to camelCase prop changes'); + assert.ok(!map.attr('the-prop'), 'kebabCase prop NOT updated when input bound to camelCase prop changes'); + map.attr('the-prop', '33'); + assert.equal(kebabPropInput.value, '33', 'input bound to kebab-case prop value set correctly when kebab-case prop changes'); + assert.equal(camelPropInput.value, '32', 'input bound to camelCase prop value not updated when kebab-case prop changes'); + map.attr('the-prop', '34'); + assert.equal(kebabPropInput.value, '34', 'input bound to kebab-case prop value updated correctly when kebab-case prop changes'); + assert.equal(camelPropInput.value, '32', 'input bound to camelCase prop value not updated when kebab-case prop changes'); + kebabPropInput.value = '35'; + domEvents.dispatch(kebabPropInput, 'change'); + assert.equal(map.attr('the-prop'), '34', 'kebab-case prop NOT updated from input bound to kebab-case prop'); + assert.equal(map.attr('theProp'), '31', 'camelCase prop NOT updated from input bound to kebab-case prop'); + }); + QUnit.test('value:to works with camelCase and kebab-case properties', function (assert) { + var template = stache('' + ''); + var map = new SimpleMap({}); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var camelPropInput = ta.getElementsByTagName('input')[0]; + var kebabPropInput = ta.getElementsByTagName('input')[1]; + camelPropInput.value = '32'; + domEvents.dispatch(camelPropInput, 'change'); + assert.equal(map.attr('theProp'), '32', 'camelCaseProp updated from input bound to camelCase Prop'); + assert.ok(!map.attr('the-prop'), 'kebabCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '30'); + assert.equal(camelPropInput.value, '32', 'input bound to camelCase Prop value NOT updated when camelCase prop changes'); + assert.ok(!kebabPropInput.value, 'input bound to kebabCase Prop value NOT updated when camelCase prop changes'); + kebabPropInput.value = '33'; + domEvents.dispatch(kebabPropInput, 'change'); + assert.equal(map.attr('the-prop'), '33', 'kebabCaseProp updated from input bound to kebabCase Prop'); + assert.equal(map.attr('theProp'), '30', 'camelCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '34'); + assert.equal(kebabPropInput.value, '33', 'input bound to kebabCase Prop value NOT updated when kebabCase prop changes'); + assert.equal(camelPropInput.value, '32', 'input bound to camelCase Prop value NOT updated when kebabCase prop changes'); + }); + QUnit.test('value:bind works with camelCase and kebab-case properties', function (assert) { + var template = stache('' + ''); + var map = new SimpleMap({}); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var camelPropInput = ta.getElementsByTagName('input')[0]; + var kebabPropInput = ta.getElementsByTagName('input')[1]; + camelPropInput.value = '32'; + domEvents.dispatch(camelPropInput, 'change'); + assert.equal(map.attr('theProp'), '32', 'camelCaseProp updated from input bound to camelCase Prop'); + assert.ok(!map.attr('the-prop'), 'kebabCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '30'); + assert.equal(camelPropInput.value, '30', 'input bound to camelCase Prop value updated when camelCase prop changes'); + assert.ok(!kebabPropInput.value, 'input bound to kebabCase Prop value NOT updated when camelCase prop changes'); + kebabPropInput.value = '33'; + domEvents.dispatch(kebabPropInput, 'change'); + assert.equal(map.attr('the-prop'), '33', 'kebabCaseProp updated from input bound to kebabCase Prop'); + assert.equal(map.attr('theProp'), '30', 'camelCaseProp NOT updated from input bound to camelCase Prop'); + map.attr('theProp', '34'); + assert.equal(kebabPropInput.value, '33', 'input bound to kebabCase Prop value NOT updated when kebabCase prop changes'); + assert.equal(camelPropInput.value, '34', 'input bound to camelCase Prop value updated when kebabCase prop changes'); + }); + QUnit.test('Bracket expression with dot and no explicit root and value:bind', function (assert) { + var template; + var div = this.fixture; + template = stache(''); + var data = new SimpleMap(); + var dom = template(data); + div.appendChild(dom); + var input = div.getElementsByTagName('input')[0]; + assert.equal(input.value, '', 'input value set correctly if key does not exist in map'); + data.set('two.hops', 'slide to the left'); + assert.equal(input.value, 'slide to the left', 'input value set correctly'); + data.set('two.hops', 'slide to the right'); + assert.equal(input.value, 'slide to the right', 'input value update correctly'); + input.value = 'REVERSE REVERSE'; + domEvents.dispatch(input, 'change'); + assert.equal(data.get('two.hops'), 'REVERSE REVERSE', 'updated from input'); + }); + QUnit.test('Bracket expression with colon and no explicit root and value:bind', function (assert) { + var template; + var div = this.fixture; + template = stache(''); + var data = new SimpleMap(); + var dom = template(data); + div.appendChild(dom); + var input = div.getElementsByTagName('input')[0]; + assert.equal(input.value, '', 'input value set correctly if key does not exist in map'); + data.set('two:hops', 'slide to the left'); + assert.equal(input.value, 'slide to the left', 'input value set correctly'); + data.set('two:hops', 'slide to the right'); + assert.equal(input.value, 'slide to the right', 'input value update correctly'); + input.value = 'REVERSE REVERSE'; + domEvents.dispatch(input, 'change'); + assert.equal(data.get('two:hops'), 'REVERSE REVERSE', 'updated from input'); + }); + QUnit.test('el:prop:to/:from/:bind work (#280)', function (assert) { + var template = stache('' + '' + ''); + var scope = new SimpleMap({ + scope1: 'scope1', + scope2: 'scope2', + scope3: 'scope3' + }); + var frag = template(scope); + var ta = this.fixture; + ta.appendChild(frag); + var inputTo = ta.getElementsByTagName('input')[0]; + var inputFrom = ta.getElementsByTagName('input')[1]; + var inputBind = ta.getElementsByTagName('input')[2]; + assert.equal(scope.attr('scope1'), '1', 'el:value:to - scope value set from attribute'); + inputTo.value = '4'; + domEvents.dispatch(inputTo, 'change'); + assert.equal(scope.attr('scope1'), '4', 'el:value:to - scope updated when attribute changed'); + scope.attr('scope1', 'scope4'); + assert.equal(inputTo.value, '4', 'el:value:to - attribute not updated when scope changed'); + assert.equal(inputFrom.value, 'scope2', 'el:value:from - attribute set from scope'); + inputFrom.value = 'scope5'; + domEvents.dispatch(inputFrom, 'change'); + assert.equal(scope.attr('scope2'), 'scope2', 'el:value:from - scope not updated when attribute changed'); + scope.attr('scope2', 'scope6'); + assert.equal(inputFrom.value, 'scope6', 'el:value:from - attribute updated when scope changed'); + assert.equal(inputBind.value, 'scope3', 'el:value:bind - attribute set from scope prop (parent -> child wins)'); + inputBind.value = 'scope6'; + domEvents.dispatch(inputBind, 'change'); + assert.equal(scope.attr('scope3'), 'scope6', 'el:value:bind - scope updated when attribute changed'); + scope.attr('scope3', 'scope7'); + assert.equal(inputBind.value, 'scope7', 'el:value:bind - attribute updated when scope changed'); + }); + QUnit.test(' two-way - DOM - input text (#1700)', function (assert) { + var template = stache(''); + var map = new SimpleMap(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + assert.equal(input.value, '', 'input value set correctly if key does not exist in map'); + map.attr('age', '30'); + var done = assert.async(); + testHelpers.afterMutation(function () { + assert.equal(input.value, '30', 'input value set correctly'); + map.attr('age', '31'); + testHelpers.afterMutation(function () { + assert.equal(input.value, '31', 'input value update correctly'); + input.value = '32'; + domEvents.dispatch(input, 'change'); + testHelpers.afterMutation(function () { + done(); + assert.equal(map.attr('age'), '32', 'updated from input'); + }); + }); + }); + }); + QUnit.test('errors subproperties of undefined properties (#298)', function (assert) { + try { + stache('')(); + assert.ok(true, 'renderer was made without error'); + } catch (e) { + assert.ok(false, e.message); + } + }); + QUnit.test('updates happen on two-way even when one binding is satisfied', function (assert) { + var done = assert.async(); + var template = stache(''); + var viewModel = new SimpleMap({ firstName: 'jeffrey' }); + canReflect.assignSymbols(viewModel, { + 'can.setKeyValue': function (key, val) { + if (val) { + this.set(key, val.toLowerCase()); + } + } + }); + var frag = template(viewModel); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.firstChild; + assert.equal(input.value, 'jeffrey', 'initial value should be "jeffrey"'); + input.value = 'JEFFREY'; + domEvents.dispatch(input, 'change'); + assert.equal(input.value, 'jeffrey', 'updated value should be "jeffrey"'); + testHelpers.afterMutation(function () { + done(); + }); + }); + QUnit.test('updates happen on changed two-way even when one binding is satisfied', function (assert) { + var done = assert.async(); + var template = stache(''); + var ViewModel = DefineMap.extend({ + firstName: { + set: function (newValue) { + if (newValue) { + return newValue.toLowerCase(); + } + } + }, + lastName: { + set: function (newValue) { + if (newValue) { + return newValue.toLowerCase(); + } + } + }, + bindValue: 'string' + }); + var viewModel = new ViewModel({ + firstName: 'Jeffrey', + lastName: 'King', + bindValue: 'firstName' + }); + var frag = template(viewModel); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.firstChild; + testHelpers.afterMutation(function () { + assert.equal(input.value, 'jeffrey'); + var undo = domMutate.onNodeAttributeChange(input, function () { + undo(); + assert.equal(input.value, 'king', 'should be king'); + setTimeout(function () { + input.value = 'KING'; + domEvents.dispatch(input, 'change'); + assert.equal(input.value, 'king'); + done(); + }, 13); + }.bind(this)); + viewModel.bindValue = 'lastName'; + }.bind(this)); + }); + QUnit.test('value:bind memory leak (#2270)', function (assert) { + var template = stache('
      '); + var vm = new SimpleMap({ foo: '' }); + var frag = template(vm); + var ta = this.fixture; + domMutateNode.appendChild.call(ta, frag); + var done = assert.async(); + testHelpers.afterMutation(function () { + domMutateNode.removeChild.call(ta, ta.firstChild); + testHelpers.afterMutation(function () { + var checkCount = 0; + var checkLifecycleBindings = function () { + var meta = vm[canSymbol.for('can.meta')]; + if (meta.handlers.get([]).length === 0) { + assert.ok(true, 'no bindings'); + done(); + } else { + checkCount++; + if (checkCount > 5) { + assert.ok(false, 'lifecycle bindings still existed after timeout'); + return done(); + } + setTimeout(checkLifecycleBindings, 1000); + } + }; + checkLifecycleBindings(); + }); + }); + }); + QUnit.test('converters work (#2299)', function (assert) { + stache.registerConverter('numberToString', { + get: function (source) { + return source() + ''; + }, + set: function (newVal, source) { + source(newVal === '' ? null : +newVal); + } + }); + var template = stache(''); + var map = new SimpleMap({ age: 25 }); + var frag = template(map); + assert.equal(frag.firstChild.value, '25'); + assert.equal(map.get('age'), 25); + map.set('age', 33); + assert.equal(frag.firstChild.value, '33'); + assert.equal(map.get('age'), 33); + frag.firstChild.value = '1'; + domEvents.dispatch(frag.firstChild, 'change'); + var done = assert.async(); + testHelpers.afterMutation(function () { + done(); + assert.equal(frag.firstChild.value, '1'); + assert.equal(map.get('age'), 1); + }); + }); + testIfRealDocument(' checked:bind should trigger a radiochange event for radio buttons', function (assert) { + var template = stache([ + '{{foo}}', + '{{bar}}' + ].join('')); + var data = new SimpleMap({ + foo: false, + bar: false + }); + var fragment = template(data); + domMutateNode.appendChild.call(this.fixture, fragment); + var self = this; + function child(index) { + return self.fixture.childNodes.item(index); + } + var fooRadio = child(0); + var fooText = child(1); + var barRadio = child(2); + var barText = child(3); + function text(node) { + while (node && node.nodeType !== 3) { + node = node.firstChild; + } + return node && node.nodeValue; + } + fooRadio.checked = true; + domEvents.dispatch(fooRadio, 'change'); + barRadio.checked = true; + domEvents.dispatch(barRadio, 'change'); + assert.equal(text(fooText), 'false', 'foo text is false'); + assert.equal(text(barText), 'true', 'bar text is true'); + assert.equal(data.get('foo'), false); + assert.equal(data.get('bar'), true); + }); + QUnit.test(' change event handler set up when binding on radiochange (#206)', function (assert) { + var template = stache(''); + var map = new SimpleMap({ attending: false }); + var frag = template(map); + var input = frag.firstChild; + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.get('attending'), true, 'now it is true'); + }); + QUnit.test(' one-way - DOM - with undefined (#135)', function (assert) { + var data = new SimpleMap({ completed: undefined }), frag = stache('')(data); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.getElementsByTagName('input')[0]; + assert.equal(input.checked, false, 'checkbox value should be false for undefined'); + }); + QUnit.test(' two-way - DOM - with truthy and falsy values binds to checkbox (#1700)', function (assert) { + var data = new SimpleMap({ completed: 1 }), frag = stache('')(data); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.getElementsByTagName('input')[0]; + assert.equal(input.checked, true, 'checkbox value bound (via attr check)'); + data.attr('completed', 0); + var done = assert.async(); + testHelpers.afterMutation(function () { + done(); + assert.equal(input.checked, false, 'checkbox value bound (via attr check)'); + }); + }); + QUnit.test(' checkboxes with checked:bind bind properly (#628)', function (assert) { + var data = new SimpleMap({ completed: true }), frag = stache('')(data); + domMutateNode.appendChild.call(this.fixture, frag); + var input = this.fixture.getElementsByTagName('input')[0]; + assert.equal(input.checked, data.get('completed'), 'checkbox value bound (via attr check)'); + data.attr('completed', false); + assert.equal(input.checked, data.get('completed'), 'checkbox value bound (via attr uncheck)'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(input.checked, true, 'checkbox value bound (via check)'); + assert.equal(data.get('completed'), true, 'checkbox value bound (via check)'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(input.checked, false, 'checkbox value bound (via uncheck)'); + assert.equal(data.get('completed'), false, 'checkbox value bound (via uncheck)'); + }); + testIfRealDocument('{{#each values}}{{/each}}'); + var values = new SimpleObservable([ + '1', + '2', + '3', + '4' + ]); + var id = new SimpleObservable('2'); + var frag = template({ + values: values, + id: id + }); + var done = assert.async(); + var select = frag.firstChild; + var options = select.getElementsByTagName('option'); + testHelpers.afterMutation(function () { + assert.ok(options[1].selected, 'value is initially selected'); + values.set([ + '7', + '2', + '5', + '4' + ]); + testHelpers.afterMutation(function () { + assert.ok(options[1].selected, 'after changing options, value should still be selected'); + done(); + }); + }); + }); + testIfRealDocument(''); + var map = new SimpleMap(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var select = ta.childNodes.item(0); + assert.equal(select.selectedIndex, 0, 'Got selected index'); + }); + testIfRealDocument(''); + var map = new SimpleMap({}); + var frag = renderer(map); + assert.equal(frag.firstChild.selectedIndex, 0, 'undefined <- {($first value)}: selectedIndex = 0'); + map.attr('key', 'notfoo'); + var done = assert.async(); + testHelpers.afterMutation(function () { + assert.equal(frag.firstChild.selectedIndex, -1, 'notfoo: selectedIndex = -1'); + map.attr('key', 'foo'); + assert.strictEqual(frag.firstChild.selectedIndex, 0, 'foo: selectedIndex = 0'); + map.attr('key', 'notbar'); + testHelpers.afterMutation(function () { + done(); + assert.equal(frag.firstChild.selectedIndex, -1, 'notbar: selectedIndex = -1'); + map.attr('key', 'bar'); + assert.strictEqual(frag.firstChild.selectedIndex, 1, 'bar: selectedIndex = 1'); + map.attr('key', 'bar'); + assert.strictEqual(frag.firstChild.selectedIndex, 1, 'bar (no change): selectedIndex = 1'); + }); + }); + }); + QUnit.test(' ' + '{{#each options}} {{/each}} '); + var frag = template(data); + assert.equal(frag.firstChild.getElementsByTagName('option')[0].selected, false, 'The first empty value is not selected'); + assert.equal(frag.firstChild.getElementsByTagName('option')[2].selected, true, 'One is selected'); + }); + testIfRealDocument('' + '{{#each allColors}}{{/each}}' + ''); + var map = new SimpleMap({ + colors: new DefineList([ + 'red', + 'green' + ]), + allColors: new DefineList([ + { + value: 'red', + label: 'Red' + }, + { + value: 'green', + label: 'Green' + }, + { + value: 'blue', + label: 'Blue' + } + ]) + }); + var done = assert.async(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var select = ta.getElementsByTagName('select')[0], options = select.getElementsByTagName('option'); + testHelpers.afterMutation(function () { + assert.ok(options[0].selected, 'red should be set initially'); + assert.ok(options[1].selected, 'green should be set initially'); + assert.ok(!options[2].selected, 'blue should not be set initially'); + done(); + }); + }); + QUnit.test('' + '{{#each countries}}' + '' + '{{/each}}' + ''); + var frag = template(data); + var select = frag.firstChild; + var done = assert.async(); + testHelpers.afterMutation(function () { + data.get('countries').replace([]); + testHelpers.afterMutation(function () { + data.attr('countries').replace(countries); + assert.equal(data.attr('countryCode'), 'US', 'country kept as USA'); + testHelpers.afterMutation(function () { + assert.ok(select.getElementsByTagName('option')[1].selected, 'USA still selected'); + }); + done(); + }); + }); + }); + testIfRealDocument('' + '' + '' + ''); + var map = new SimpleMap({ color: 'red' }); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var inputs = ta.getElementsByTagName('select'); + assert.equal(inputs[0].value, 'red', 'default value set'); + map.set('color', 'green'); + assert.equal(inputs[0].value, 'green', 'alternate value set'); + canReflect.each(ta.getElementsByTagName('option'), function (opt) { + if (opt.value === 'red') { + opt.selected = 'selected'; + } + }); + assert.equal(map.get('color'), 'green', 'not yet updated from input'); + domEvents.dispatch(inputs[0], 'change'); + assert.equal(map.get('color'), 'red', 'updated from input'); + canReflect.each(ta.getElementsByTagName('option'), function (opt) { + if (opt.value === 'green') { + opt.selected = 'selected'; + } + }); + assert.equal(map.get('color'), 'red', 'not yet updated from input'); + domEvents.dispatch(inputs[0], 'change'); + assert.equal(map.get('color'), 'green', 'updated from input'); + }); + testIfRealDocument('' + '' + '' + '' + ''); + var list = new DefineList(); + var done = assert.async(); + var frag = template({ colors: list }); + var ta = this.fixture; + ta.appendChild(frag); + var select = ta.getElementsByTagName('select')[0], options = select.getElementsByTagName('option'); + setTimeout(function () { + options[0].selected = true; + domEvents.dispatch(select, 'change'); + assert.deepEqual(list.get(), ['red'], 'A DefineList value is set even if none existed'); + options[1].selected = true; + domEvents.dispatch(select, 'change'); + assert.deepEqual(list.get(), [ + 'red', + 'green' + ], 'Adds items to the list'); + options[0].selected = false; + domEvents.dispatch(select, 'change'); + assert.deepEqual(list.get(), ['green'], 'Removes items from the list'); + list.push('ultraviolet'); + options[0].selected = false; + options[1].selected = true; + options[2].selected = true; + ta.removeChild(select); + done(); + }, 1); + }); + QUnit.test('' + '{{#countries}}' + '' + '{{/countries}}' + ''); + var frag = template(data); + var select = frag.firstChild; + var done = assert.async(); + testHelpers.afterMutation(function () { + data.get('countries').replace([]); + testHelpers.afterMutation(function () { + data.get('countries').replace(countries); + assert.equal(data.get('countryCode'), 'US', 'country kept as USA'); + testHelpers.afterMutation(function () { + assert.ok(select.getElementsByTagName('option')[1].selected, 'USA still selected'); + }); + done(); + }); + }); + }); + testIfRealDocument('' + '{{#each countries}}' + '' + '{{/each}}' + ''); + template(data); + var done = assert.async(); + testHelpers.afterMutation(function () { + data.attr('countries').replace([]); + testHelpers.afterMutation(function () { + assert.equal(data.get('countryCode'), undefined, 'countryCode set to undefined'); + done(); + }); + }); + }); + testIfRealDocument('' + '' + '{{#each people}}{{/each}}' + '' + ''); + var people = new DefineList([ + 'Justin', + 'Zed', + 'Tom', + 'Paula' + ]); + var vm = new SimpleMap({ + person: 'Brian', + people: people + }); + var done = assert.async(); + vm.on('person', function (ev, newVal, oldVal) { + assert.ok(false, 'person attribute should not change'); + }); + var frag = template(vm); + assert.equal(vm.attr('person'), 'Brian', 'Person is still set'); + testHelpers.afterMutation(function () { + people.push('Brian'); + testHelpers.afterMutation(function () { + var options = frag.firstChild.getElementsByTagName('option'); + assert.ok(options[options.length - 1].selected, 'New child should be selected'); + done(); + }); + }); + }); + QUnit.test('' + '{{#each countries}}' + '' + '{{/each}}' + ''); + var data = new SimpleMap({ + countryCode: 'US', + countries: new DefineList(countries) + }); + var frag = template(data); + data.set('countryCode', 'IND'); + var done = assert.async(); + testHelpers.afterMutation(function () { + done(); + assert.equal(frag.firstChild.value, 'IND', 'got last updated value'); + }); + }); + testIfRealDocument('' + '' + '' + '' + '' + '' + ''); + var map = new SimpleMap({ + 'color-1': null, + 'color-2': undefined, + 'color-3': '' + }); + var done = assert.async(); + var frag = template(map); + domMutateNode.appendChild.call(this.fixture, frag); + var nullInput = doc.getElementById('null-select'); + var nullInputOptions = nullInput.getElementsByTagName('option'); + var undefinedInput = doc.getElementById('undefined-select'); + var undefinedInputOptions = undefinedInput.getElementsByTagName('option'); + var stringInput = doc.getElementById('string-select'); + var stringInputOptions = stringInput.getElementsByTagName('option'); + testHelpers.afterMutation(function () { + assert.ok(!nullInputOptions[0].selected, 'default (null) value set'); + assert.ok(undefinedInputOptions[0].selected, 'default (undefined) value set'); + assert.ok(stringInputOptions[0].selected, 'default (\'\') value set'); + done(); + }); + }); + testIfRealDocument(''); + var map = new SimpleMap({ key: null }); + var frag = template(map); + var select = frag.childNodes.item(0); + testHelpers.afterMutation(function () { + assert.equal(select.selectedIndex, -1, 'selectedIndex is 0 because no value exists on the map'); + assert.equal(map.get('key'), null, 'The map\'s value property is set to the select\'s value'); + done(); + }); + var done = assert.async(); + }); + testIfRealDocument(''); + var map = new SimpleMap(); + var frag = template(map); + var select = frag.childNodes.item(0); + testHelpers.afterMutation(function () { + assert.equal(select.selectedIndex, 0, 'selectedIndex is 0 because no value exists on the map'); + assert.equal(map.attr('value'), 'One', 'The map\'s value property is set to the select\'s value'); + done(); + }); + var done = assert.async(); + }); + testIfRealDocument('Bi-directional binding among sibling components, new syntax (#325)', function (assert) { + var groupCollapsed = console.groupCollapsed; + if (groupCollapsed) { + console.groupCollapsed = null; + } + var demoContext = new DefineMap({ person: '' }); + var SourceComponentVM = DefineMap.extend('SourceComponentVM', { + defaultPerson: { value: 'John' }, + person: { + set: function (val) { + return val || this.defaultPerson; + } + } + }); + var ClearComponentVM = DefineMap.extend('ClearComponentVM', { + person: 'string', + clearPerson: function () { + this.set('person', ''); + } + }); + MockComponent.extend({ + tag: 'source-component', + viewModel: SourceComponentVM, + template: stache('{{person}}') + }); + MockComponent.extend({ + tag: 'clear-button', + viewModel: ClearComponentVM, + template: stache('{{./person}}') + }); + var demoRenderer = stache('{{./person}}' + '' + ''); + var frag = demoRenderer(demoContext); + var sourceComponentVM = canViewModel(frag.childNodes[1]); + var clearButtonVM = canViewModel(frag.childNodes[2]); + assert.equal(frag.childNodes[0].childNodes[0].nodeValue, '', 'demoContext person is empty'); + assert.equal(frag.childNodes[1].childNodes[0].childNodes[0].nodeValue, 'John', 'source-component person is default'); + assert.equal(frag.childNodes[2].childNodes[1].childNodes[0].nodeValue, '', 'clear-button person is empty'); + sourceComponentVM.person = 'Bob'; + assert.equal(frag.childNodes[0].childNodes[0].nodeValue, 'Bob', 'demoContext person set correctly'); + assert.equal(frag.childNodes[1].childNodes[0].childNodes[0].nodeValue, 'Bob', 'source-component person set correctly'); + assert.equal(frag.childNodes[2].childNodes[1].childNodes[0].nodeValue, 'Bob', 'clear-button person set correctly'); + clearButtonVM.clearPerson(); + assert.equal(frag.childNodes[0].childNodes[0].nodeValue, '', 'demoContext person set correctly'); + assert.equal(frag.childNodes[1].childNodes[0].childNodes[0].nodeValue, 'John', 'source-component person set correctly'); + assert.equal(frag.childNodes[2].childNodes[1].childNodes[0].nodeValue, '', 'clear-button person set correctly'); + if (groupCollapsed) { + console.groupCollapsed = groupCollapsed; + } + }); + testIfRealDocument('Bracket Expression with :to bindings', function (assert) { + var demoContext = new DefineMap({ person: { name: 'Matt' } }); + var SourceComponentVM = DefineMap.extend('SourceComponentVM', { name: { default: 'Kevin' } }); + MockComponent.extend({ + tag: 'source-component', + viewModel: SourceComponentVM, + template: stache('{{name}}') + }); + var demoRenderer = stache(''); + demoRenderer(demoContext); + assert.equal(demoContext.person.name, 'Kevin', 'source-component has correct name set'); + }); + QUnit.test('this:to works', function (assert) { + var template = stache(''); + var map = new SimpleMap({ input: null }); + var frag = template(map); + var input = frag.firstChild; + assert.equal(input, map.get('input'), 'set the input'); + }); + }); +}); +/*can-event-dom-enter@2.2.1#can-event-dom-enter*/ +define('can-event-dom-enter@2.2.1#can-event-dom-enter', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var baseEventType = 'keyup'; + function isEnterEvent(event) { + var hasEnterKey = event.key === 'Enter'; + var hasEnterCode = event.keyCode === 13; + return hasEnterKey || hasEnterCode; + } + var enterEvent = { + defaultEventType: 'enter', + addEventListener: function (target, eventType, handler) { + var keyHandler = function (event) { + if (isEnterEvent(event)) { + return handler.apply(this, arguments); + } + }; + var handlerMap = enterEvent._eventTypeHandlerMap[eventType]; + if (!handlerMap) { + handlerMap = enterEvent._eventTypeHandlerMap[eventType] = new Map(); + } + handlerMap.set(handler, keyHandler); + this.addEventListener(target, baseEventType, keyHandler); + }, + removeEventListener: function (target, eventType, handler) { + var handlerMap = enterEvent._eventTypeHandlerMap[eventType]; + if (handlerMap) { + var keyHandler = handlerMap.get(handler); + if (keyHandler) { + handlerMap.delete(handler); + if (handlerMap.size === 0) { + delete enterEvent._eventTypeHandlerMap[eventType]; + } + this.removeEventListener(target, baseEventType, keyHandler); + } + } + }, + _eventTypeHandlerMap: {} + }; + module.exports = namespace.domEventEnter = enterEvent; +}); +/*can-stache-bindings@5.0.4#test/colon/event-test*/ +define('can-stache-bindings@5.0.4#test/colon/event-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-test-helpers', + 'can-stache-bindings', + 'can-stache', + '../mock-component-simple-map', + 'can-view-callbacks', + 'can-simple-map', + 'can-define/list/list', + 'can-simple-observable', + 'can-view-model', + 'can-reflect', + 'can-symbol', + 'can-dom-data', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-dom-events', + 'can-event-dom-enter' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + var canTestHelpers = require('can-test-helpers'); + var stacheBindings = require('can-stache-bindings'); + var stache = require('can-stache'); + var MockComponent = require('../mock-component-simple-map'); + var viewCallbacks = require('can-view-callbacks'); + var SimpleMap = require('can-simple-map'); + var DefineList = require('can-define/list/list'); + var SimpleObservable = require('can-simple-observable'); + var canViewModel = require('can-view-model'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var domData = require('can-dom-data'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var domEvents = require('can-dom-events'); + stache.addBindings(stacheBindings); + testHelpers.makeTests('can-stache-bindings - colon - event', function (name, doc, enableMO, testIfRealDocument, testIfRealDocumentInDev) { + QUnit.test('on:enter', function (assert) { + var enterEvent = require('can-event-dom-enter'); + var undo = domEvents.addEvent(enterEvent); + var template = stache(''); + var called = 0; + var frag = template({ + update: function () { + called++; + assert.equal(called, 1, 'update called once'); + } + }); + var input = frag.childNodes.item(0); + domEvents.dispatch(input, { + type: 'keyup', + keyCode: 38 + }); + domEvents.dispatch(input, { + type: 'keyup', + keyCode: 13 + }); + undo(); + }); + QUnit.test('can call intermediate functions before calling the final function (#1474)', function (assert) { + var ta = this.fixture; + var done = assert.async(); + var template = stache('
      '); + var frag = template({ + does: function () { + return { + some: function () { + return { + thing: function (context) { + assert.ok(typeof context.does === 'function'); + done(); + } + }; + } + }; + } + }); + ta.appendChild(frag); + domEvents.dispatch(doc.getElementById('click-me'), 'click'); + }); + QUnit.test('two bindings on one element call back the correct method', function (assert) { + assert.expect(2); + var template = stache(''); + var callingFirst = false, callingSecond = false; + var frag = template({ + first: function () { + assert.ok(callingFirst, 'called first'); + }, + second: function () { + assert.ok(callingSecond, 'called second'); + } + }); + var input = frag.childNodes.item(0); + callingFirst = true; + domEvents.dispatch(input, { type: 'mousemove' }); + callingFirst = false; + callingSecond = true; + domEvents.dispatch(input, { type: 'click' }); + }); + QUnit.test('event behavior event bindings should be removed when the bound element is', function (assert) { + var template = stache('
      {{#if isShowing}}{{/if}}
      '); + var viewModel = new SimpleMap({ isShowing: false }); + viewModel.onClick = function () { + }; + var bindingListenerCount = 0; + var hasAddedBindingListener = false; + var hasRemovedBindingListener = false; + var fragment = template(viewModel); + domMutateNode.appendChild.call(this.fixture, fragment); + var isInputBindingEvent = function (element, eventName) { + return element.nodeName === 'INPUT' && eventName === 'click'; + }; + var realAddEventListener = domEvents.addEventListener; + var realRemoveEventListener = domEvents.removeEventListener; + domEvents.addEventListener = function (target, eventName) { + if (isInputBindingEvent(target, eventName)) { + bindingListenerCount++; + hasAddedBindingListener = true; + } + return realAddEventListener.apply(null, arguments); + }; + domEvents.removeEventListener = function (target, eventName) { + if (isInputBindingEvent(target, eventName)) { + bindingListenerCount--; + hasRemovedBindingListener = true; + } + return realRemoveEventListener.apply(null, arguments); + }; + viewModel.set('isShowing', true); + var span = this.fixture.getElementsByTagName('span')[0]; + var done = assert.async(); + var undo = domMutate.onNodeDisconnected(span, function () { + undo(); + setTimeout(function () { + domEvents.addEventListener = realAddEventListener; + domEvents.removeEventListener = realRemoveEventListener; + assert.ok(hasAddedBindingListener, 'An event listener should have been added for the binding'); + assert.ok(hasRemovedBindingListener, 'An event listener should have been removed for the binding'); + var message = bindingListenerCount + ' event listeners were added but not removed'; + if (removeEventListener < 0) { + message = 'Event listeners were removed more than necessary'; + } + assert.equal(bindingListenerCount, 0, message); + done(); + }, 1); + }); + viewModel.set('isShowing', false); + }); + QUnit.test('on:event throws an error when inside #if block (#1182)', function (assert) { + var done = assert.async(); + var flag = new SimpleObservable(false), clickHandlerCount = 0; + var frag = stache('
      Click
      ')({ + flag: flag, + foo: function () { + clickHandlerCount++; + } + }); + var fixture = this.fixture; + var trig = function () { + var div = fixture.getElementsByTagName('div')[0]; + domEvents.dispatch(div, { type: 'click' }); + }; + domMutateNode.appendChild.call(this.fixture, frag); + trig(); + testHelpers.afterMutation(function () { + assert.equal(clickHandlerCount, 0, 'click handler not called'); + done(); + }); + }); + QUnit.test('can listen to camelCase events using on:', function (assert) { + var done = assert.async(); + assert.expect(1); + var map = new SimpleMap({ someProp: 'foo' }); + map.someMethod = function () { + done(); + assert.ok(true); + }; + var template = stache('
      '); + template(map); + map.set('someProp', 'baz'); + }); + QUnit.test('can listen to kebab-case events using on:', function (assert) { + var done = assert.async(); + assert.expect(1); + var map = new SimpleMap({ 'some-prop': 'foo' }); + map.someMethod = function () { + done(); + assert.ok(true); + }; + var template = stache('
      '); + template(map); + map.set('some-prop', 'baz'); + }); + QUnit.test('can bind to property on scope using :by:', function (assert) { + var done = assert.async(); + assert.expect(1); + MockComponent.extend({ tag: 'view-model-able' }); + var template = stache(''); + var map = new SimpleMap({ obj: new SimpleMap({ prop: 'Mercury' }) }); + map.someMethod = function (args) { + done(); + assert.equal(args[0], 'Venus', 'method called'); + }; + template(map); + map.get('obj').set('prop', 'Venus'); + }); + QUnit.test('can bind to entire scope using :by:this', function (assert) { + var done = assert.async(); + assert.expect(1); + MockComponent.extend({ tag: 'view-model-able' }); + var template = stache(''); + var map = new SimpleMap({ prop: 'Mercury' }); + map.someMethod = function (newVal) { + done(); + assert.equal(newVal, 'Venus', 'method called'); + }; + template(map); + map.set('prop', 'Venus'); + }); + QUnit.test('can bind to viewModel using on:vm:prop', function (assert) { + var done = assert.async(); + assert.expect(1); + var map = new SimpleMap({ prop: 'Mercury' }); + var MySimpleMap = SimpleMap.extend({ + someMethod: function (newVal) { + done(); + assert.equal(newVal, 'Venus', 'method called'); + } + }); + var parent = new MySimpleMap(); + MockComponent.extend({ + tag: 'view-model-able', + viewModel: map + }); + var template = stache(''); + template(parent); + map.attr('prop', 'Venus'); + }); + QUnit.test('can bind to element using on:el:prop', function (assert) { + var done = assert.async(); + assert.expect(1); + var map = new SimpleMap({ prop: 'Mercury' }); + var MySimpleMap = SimpleMap.extend({ + someMethod: function () { + done(); + assert.ok(true, 'method called'); + } + }); + var parent = new MySimpleMap(); + MockComponent.extend({ + tag: 'view-model-able', + viewModel: map + }); + var template = stache(''); + var frag = template(parent); + var element = frag.firstChild; + domEvents.dispatch(element, 'prop'); + }); + QUnit.test('call expressions work (#208)', function (assert) { + assert.expect(2); + stache.registerHelper('addTwo', function (arg) { + return arg + 2; + }); + stache.registerHelper('helperWithArgs', function (arg) { + assert.equal(arg, 3, 'got the helper'); + assert.ok(true, 'helper called'); + }); + var template = stache('

      '); + var frag = template({ arg: 1 }); + this.fixture.appendChild(frag); + var p0 = this.fixture.getElementsByTagName('p')[0]; + domEvents.dispatch(p0, 'click'); + }); + QUnit.test('events should bind when using a plain object', function (assert) { + var flip = false; + var template = stache('
      Test
      '); + var frag = template({ + flip: function () { + flip = true; + }, + test: true + }); + domEvents.dispatch(frag.firstChild, 'foo'); + assert.ok(flip, 'Plain object method successfully called'); + }); + QUnit.test('scope.arguments gives the event arguments', function (assert) { + var template = stache(''); + var MyMap = SimpleMap.extend({ + doSomething: function (ev, args) { + assert.equal(args[0], ev, 'default arg is ev'); + } + }); + var frag = template(new MyMap()); + var button = frag.firstChild; + domEvents.dispatch(button, 'click'); + }); + QUnit.test('special values get called', function (assert) { + assert.expect(2); + var done = assert.async(); + var vm = new (SimpleMap.extend('RefSyntaxVM', { + method: function () { + assert.ok(true, 'method called'); + done(); + } + }))(); + vm._refSyntaxFlag = true; + MockComponent.extend({ + tag: 'ref-syntax', + template: stache(''), + viewModel: vm + }); + var template = stache(''); + var frag = template({}); + domMutateNode.appendChild.call(this.fixture, frag); + testHelpers.afterMutation(function () { + var input = doc.getElementsByTagName('input')[0]; + input.value = 'bar'; + domEvents.dispatch(input, 'change'); + var scope = domData.get(this.fixture.firstChild).shadowScope; + assert.equal(scope.get('*foo'), 'bar', 'Reference attribute set'); + var refElement = doc.getElementsByTagName('ref-syntax')[0]; + domEvents.dispatch(refElement, 'baz-event'); + }.bind(this)); + }); + QUnit.test('viewModel binding', function (assert) { + MockComponent.extend({ + tag: 'viewmodel-binding', + viewModel: { + makeMyEvent: function () { + this.dispatch('myevent'); + } + } + }); + var frag = stache('')({ + doSomething: function () { + assert.ok(true, 'called!'); + } + }); + canViewModel(frag.firstChild).makeMyEvent(); + }); + QUnit.test('event handlers should run in mutateQueue (#444)', function (assert) { + var list = new DefineList([ + { name: 'A' }, + { name: 'B' }, + { name: 'C' } + ]); + var data = new SimpleMap({ + list: list, + item: list[1], + clearStuff: function () { + this.set('item', null); + this.get('list').splice(1, 1); + } + }); + var template = stache('
      ' + '{{#each list}} ' + '{{^is(., ../item)}}' + '
      {{name}}
      ' + '{{/is}}' + '{{/each}}' + '
      '); + var frag = template(data); + domEvents.dispatch(frag.firstChild, 'click'); + assert.ok(true, 'no errors'); + }); + QUnit.test('support simple setters', function (assert) { + var template = stache(''); + var map = new SimpleMap({ + prop: null, + value: 'Value' + }); + var frag = template(map); + var input = frag.childNodes.item(0); + domEvents.dispatch(input, { type: 'click' }); + assert.equal(map.get('prop'), 'Value'); + template = stache(''); + map = new SimpleMap({ + prop: null, + value: 'Value' + }); + frag = template(map); + input = frag.childNodes.item(0); + input.value = 'ELEMENT-VALUE'; + domEvents.dispatch(input, { type: 'click' }); + assert.equal(map.get('prop'), 'ELEMENT-VALUE'); + template = stache(''); + map = new SimpleMap({ + prop: null, + value: 'Value' + }); + frag = template(map); + input = frag.childNodes.item(0); + domEvents.dispatch(input, { type: 'click' }); + assert.equal(map.get('prop'), 3, 'primitives'); + template = stache(''); + map = new SimpleMap({ + prop: null, + returnEight: function () { + return 8; + } + }); + frag = template(map); + input = frag.childNodes.item(0); + domEvents.dispatch(input, { type: 'click' }); + assert.equal(map.get('prop'), 8, 'can set to result of calling a function'); + MockComponent.extend({ + tag: 'my-button', + template: stache(''), + viewModel: { clicked: null } + }); + map = new SimpleMap({ clickCount: 0 }); + template = stache(''); + frag = template(map); + var button = frag.firstChild; + var myButton = button.firstChild; + assert.equal(typeof button.viewModel.get('clicked'), 'function', 'has function'); + domEvents.dispatch(myButton, { type: 'click' }); + assert.equal(map.get('clickCount'), 1, 'function got called'); + }); + testIfRealDocument('on:click:value:to on button (#484)', function (assert) { + var template = stache(''); + var map = new SimpleMap({ myProp: 1 }); + var frag = template(map); + var button = frag.firstChild; + assert.equal(map.get('myProp'), 1, 'initial value'); + domEvents.dispatch(button, 'click'); + assert.equal(map.get('myProp'), 2, 'set from value'); + }); + QUnit.test('Registering events on nullish context with :by should register an observation on the scope and properly teardown all listeners on removal', function (assert) { + var map = new SimpleMap({ + user: null, + doSomething: function () { + assert.ok(true); + } + }); + var user = new SimpleMap({ name: 'Michael' }); + var fragment = stache('
      ')(map); + var div = fragment.firstChild; + domMutateNode.appendChild.call(this.fixture, fragment); + assert.equal(canReflect.isBound(map), true); + map.set('user', user); + assert.equal(canReflect.isBound(user), true); + domMutateNode.removeChild.call(this.fixture, div); + testHelpers.afterMutation(function () { + assert.equal(canReflect.isBound(map), false); + assert.equal(canReflect.isBound(user), false); + }); + }); + QUnit.test('Registering events on nullish context with :by should switch bindings when the context is defined and teardiwn old listener', function (assert) { + var map = new SimpleMap({ + user: null, + doSomething: function () { + assert.ok(true); + } + }); + var user1 = new SimpleMap({ name: 'Michael' }); + var user2 = new SimpleMap({ name: 'Justin' }); + stache('
      ')(map); + assert.equal(canReflect.isBound(map), true); + map.set('user', user1); + assert.equal(canReflect.isBound(user1), true); + assert.equal(canReflect.isBound(user2), false); + map.set('user', user2); + assert.equal(canReflect.isBound(user1), false); + assert.equal(canReflect.isBound(user2), true); + }); + QUnit.test('Registering events on nullish context with :by should be supported', function (assert) { + assert.expect(3); + var map = new SimpleMap({ + user: null, + doSomething: function () { + assert.ok(true); + } + }); + var user1 = new SimpleMap({ name: 'Michael' }); + var user2 = new SimpleMap({ name: 'Justin' }); + stache('
      ')(map); + map.set('user', user1); + map.get('user').set('name', 'Greg'); + map.get('user').set('name', 'Jim'); + map.set('user', user2); + map.get('user').set('name', 'Todd'); + }); + QUnit.test('Registering events on nullish context with :by should be supported on :vm bindings', function (assert) { + assert.expect(2); + var map = new SimpleMap({ user: null }); + var ParentScope = SimpleMap.extend({ + doSomething: function () { + assert.ok(true); + } + }); + var parent = new ParentScope(); + var user1 = new SimpleMap({ name: 'Michael' }); + var user2 = new SimpleMap({ name: 'Justin' }); + MockComponent.extend({ + tag: 'view-model-able', + viewModel: map + }); + stache('')(parent); + map.set('user', user1); + map.get('user').set('name', 'Greg'); + map.set('user', user2); + map.get('user').set('name', 'Todd'); + }); + testIfRealDocumentInDev('warning when binding known DOM event name to view model', function (assert) { + var teardown = canTestHelpers.dev.willWarn('The focus event is bound the view model for . Use on:el:focus to bind to the element instead.'); + viewCallbacks.tag('warning-el', function (el) { + el[canSymbol.for('can.viewModel')] = new SimpleMap({}); + }); + var template = stache(''); + var map = new SimpleMap({}); + template(map); + assert.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('events should not create viewmodels (#540)', function (assert) { + var ta = this.fixture; + var template = stache('
      '); + var frag = template({ + func: function () { + assert.ok(true, 'func ran'); + } + }); + ta.appendChild(frag); + var el = doc.getElementById('click-me'); + domEvents.dispatch(el, 'click'); + assert.equal(el[canSymbol.for('can.viewModel')], undefined, 'el does not have a viewmodel'); + }); + QUnit.test('events should not create viewmodels (#540)', function (assert) { + var ta = this.fixture; + var template = stache('
      '); + var frag = template({ + func: function () { + assert.ok(true, 'func ran'); + } + }); + ta.appendChild(frag); + var el = doc.getElementById('click-me'); + domEvents.dispatch(el, 'click'); + assert.equal(el[canSymbol.for('can.viewModel')], undefined, 'el does not have a viewmodel'); + }); + QUnit.test('Improve error message when unable to bind', function (assert) { + var vm = new SimpleMap({ todo: { complete: false } }); + vm.handle = function () { + }; + var template = stache('
      '); + try { + template(vm); + } catch (error) { + assert.equal(error.message, 'can-stache-bindings - Unable to bind "complete": "complete" is a property on a plain object "{"complete":false}". Binding is available with observable objects only. For more details check https://canjs.com/doc/can-stache-bindings.html#Callafunctionwhenaneventhappensonavalueinthescope_animation_'); + } + }); + }); +}); +/*can-stache-bindings@5.0.4#test/colon/view-model-test*/ +define('can-stache-bindings@5.0.4#test/colon/view-model-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache-bindings', + 'can-stache', + 'can-simple-map', + '../mock-component-simple-map', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-define/map/map', + 'can-view-callbacks', + 'can-view-model', + 'can-symbol', + 'can-reflect', + 'can-queues', + 'can-test-helpers', + 'can-stache-bindings', + 'can-view-scope' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + var stacheBindings = require('can-stache-bindings'); + var stache = require('can-stache'); + var SimpleMap = require('can-simple-map'); + var MockComponent = require('../mock-component-simple-map'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var DefineMap = require('can-define/map/map'); + var viewCallbacks = require('can-view-callbacks'); + var canViewModel = require('can-view-model'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var canTestHelpers = require('can-test-helpers'); + var stacheBindings = require('can-stache-bindings'); + var Scope = require('can-view-scope'); + stache.addBindings(stacheBindings); + testHelpers.makeTests('can-stache-bindings - colon - ViewModel', function (name, doc, enableMO) { + QUnit.test('on:el:click works inside {{#if}} on element with a viewModel (#279)', function (assert) { + var map = new SimpleMap({}); + var MySimpleMap = SimpleMap.extend({ + show: true, + method: function () { + assert.ok(true, 'method called'); + } + }); + var parent = new MySimpleMap(); + MockComponent.extend({ + tag: 'view-model-able', + viewModel: map + }); + var template = stache(''); + var frag = template(parent); + var el = frag.firstChild; + domEvents.dispatch(el, 'click'); + }); + QUnit.test('vm:prop:to/:from/:bind work (#280)', function (assert) { + var vm1 = new SimpleMap({ value: 'vm1' }); + var vm2 = new SimpleMap({ value: 'vm2' }); + var vm3 = new SimpleMap({ value: 'vm3' }); + MockComponent.extend({ + tag: 'comp-1', + viewModel: vm1 + }); + MockComponent.extend({ + tag: 'comp-2', + viewModel: vm2 + }); + MockComponent.extend({ + tag: 'comp-3', + viewModel: vm3 + }); + var template = stache('' + '' + ''); + var scope = new SimpleMap({ + scope1: 'scope1', + scope2: 'scope2', + scope3: 'scope3' + }); + template(scope); + assert.equal(scope.attr('scope1'), 'vm1', 'vm:value:to - scope value set from vm'); + vm1.attr('value', 'vm4'); + assert.equal(scope.attr('scope1'), 'vm4', 'vm:value:to - scope updated when vm changes'); + scope.attr('scope1', 'scope4'); + assert.equal(vm1.attr('value'), 'vm4', 'vm:value:to - vm not updated when scope changes'); + assert.equal(vm2.attr('value'), 'scope2', 'vm:value:from - vm value set from scope'); + scope.attr('scope2', 'scope5'); + assert.equal(vm2.attr('value'), 'scope5', 'vm:value:from - vm updated when scope changes'); + vm2.attr('value', 'vm5'); + assert.equal(scope.attr('scope2'), 'scope5', 'vm:value:from - scope not updated when vm changes'); + assert.equal(vm3.attr('value'), 'scope3', 'vm:value:bind - vm value set from scope'); + scope.attr('scope3', 'scope6'); + assert.equal(vm3.attr('value'), 'scope6', 'vm:value:bind - vm updated when scope changes'); + vm3.attr('value', 'vm6'); + assert.equal(scope.attr('scope3'), 'vm6', 'vm:value:bind - scope updated when vm changes'); + }); + canTestHelpers.dev.devOnlyTest('Warning happens when changing the map that a to-parent binding points to.', function (assert) { + var tagName = 'merge-warn-test'; + delete viewCallbacks._tags[tagName]; + assert.expect(2); + var step1 = { 'baz': 'quux' }; + var overwrite = { 'plonk': 'waldo' }; + var teardown = canTestHelpers.dev.willWarn('can-stache-key: Merging data into "bar" because its parent is non-observable'); + var viewModel; + MockComponent.extend({ + tag: tagName, + viewModel: function () { + return viewModel = new SimpleMap({ 'foo': new SimpleMap({}) }); + } + }); + var template = stache(''); + var data = { bar: new SimpleMap(step1) }; + this.fixture.appendChild(template(data)); + viewModel.set('foo', overwrite); + assert.deepEqual(data.bar.get(), { 'plonk': 'waldo' }, 'sanity check: parent binding set (default map -> default map)'); + assert.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('changing a scope property calls registered stache helper\'s returned function', function (assert) { + assert.expect(1); + var done = assert.async(); + var scope = new SimpleMap({ test: 'testval' }); + MockComponent.extend({ + tag: 'test-component', + viewModel: scope, + template: stache('Hello world') + }); + stache.registerHelper('propChangeEventStacheHelper', function () { + return function () { + done(); + assert.ok(true, 'helper\'s returned function called'); + }; + }); + var template = stache(''); + template({}); + scope.set('test', 'changed'); + }); + QUnit.test('one-way pass computes to components with ~', function (assert) { + assert.expect(6); + MockComponent.extend({ tag: 'foo-bar' }); + var baseVm = new SimpleMap({ foo: 'bar' }); + this.fixture.appendChild(stache('')(baseVm)); + var vm = canViewModel(this.fixture.firstChild); + assert.ok(vm.get('compute')[canSymbol.for('can.getValue')], 'observable returned'); + assert.equal(vm.get('compute')(), 'bar', 'Compute has correct value'); + canReflect.onValue(vm.get('compute'), function () { + assert.ok(true, 'Change handler called'); + }); + baseVm.set('foo', 'quux'); + assert.equal(vm.get('compute')(), 'quux', 'Compute updates'); + vm.get('compute')('xyzzy'); + assert.equal(baseVm.get('foo'), 'xyzzy', 'Compute does update the other direction'); + }); + QUnit.test('Child bindings updated before parent (#2252)', function (assert) { + var template = stache('{{#eq page \'view\'}}{{/eq}}'); + MockComponent.extend({ + tag: 'child-binder', + template: stache(''), + viewModel: function (props) { + var map = new SimpleMap(props); + canReflect.assignSymbols(map, { + 'can.setKeyValue': function (key, value) { + if (key === 'page') { + assert.equal(value, 'view', 'value should not be edit'); + } else { + assert.equal(key, 'title', 'title was set, we are trapping right'); + } + this.set(key, value); + } + }); + return map; + } + }); + var data = new SimpleMap({ page: 'view' }); + template(data); + data.set('title', 'foo'); + queues.batch.start(); + data.set('page', 'edit'); + queues.batch.stop(); + }); + QUnit.test('backtrack path in to-parent bindings (#2132)', function (assert) { + MockComponent.extend({ + tag: 'parent-export', + viewModel: { value: 'VALUE' } + }); + var template = stache('{{#innerMap}}{{/innerMap}}'); + var data = new SimpleMap({ innerMap: new SimpleMap({}) }); + template(data); + assert.equal(data.get('parentValue'), 'VALUE', 'set on correct context'); + assert.equal(data.get('innerMap').get('parentValue'), undefined, 'nothing on innerMap'); + }); + QUnit.test('function reference to child binding (#2116)', function (assert) { + assert.expect(2); + var template = stache(''); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: {} + }); + var VM = SimpleMap.extend({}); + var vm = new VM({}); + var frag = template(vm); + vm.attr('parent', function () { + assert.ok(false, 'should not be called'); + }); + assert.equal(typeof canViewModel(frag.firstChild).attr('child'), 'function', 'to child binding'); + template = stache(''); + vm = new VM({}); + frag = template(vm); + canViewModel(frag.firstChild).attr('method', function () { + assert.ok(false, 'method should not be called'); + }); + assert.equal(typeof vm.get('vmMethod'), 'function', 'parent export function'); + }); + QUnit.test('setter only gets called once (#2117)', function (assert) { + assert.expect(1); + var VM = SimpleMap.extend({ + attr: function (prop, val) { + if (arguments.length > 1 && prop === 'bar') { + assert.equal(val, 'BAR'); + } + return SimpleMap.prototype.attr.apply(this, arguments); + } + }); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: VM + }); + var template = stache(''); + template(new SimpleMap({ bar: 'BAR' })); + }); + QUnit.test('function reference to child (#2116)', function (assert) { + assert.expect(2); + var template = stache(''); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: { + method: function () { + assert.ok(false, 'should not be called'); + } + } + }); + var VM = SimpleMap.extend({ + parent: function () { + assert.ok(false, 'should not be called'); + } + }); + var vm = new VM({}); + var frag = template(vm); + assert.equal(typeof canViewModel(frag.firstChild).attr('child'), 'function', 'to child binding'); + template = stache(''); + vm = new VM({}); + template(vm); + assert.ok(typeof vm.attr('vmMethod') === 'function', 'parent export function'); + }); + QUnit.test('exporting methods (#2051)', function (assert) { + assert.expect(2); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: { + method: function () { + assert.ok(true, 'foo called'); + return 5; + } + } + }); + var template = stache('{{scope.vars.refKey()}}'); + var frag = template({}); + assert.equal(frag.lastChild.nodeValue, '5'); + }); + QUnit.test('one way - child to parent - importing viewModel hyphenatedProp:to="test"', function (assert) { + MockComponent.extend({ + tag: 'import-prop-scope', + template: stache('Hello {{userName}}'), + viewModel: { + userName: 'David', + age: 7, + updateName: function () { + this.set('userName', 'Justin'); + } + } + }); + MockComponent.extend({ + tag: 'import-prop-parent', + template: stache('' + '
      Imported: {{test}}
      ') + }); + var template = stache(''); + var frag = template({}); + var importPropParent = frag.firstChild; + var importPropScope = importPropParent.getElementsByTagName('import-prop-scope')[0]; + canViewModel(importPropScope).updateName(); + var importPropParentViewModel = canViewModel(importPropParent); + assert.equal(importPropParentViewModel.get('test'), 'Justin', 'got hyphenated prop'); + assert.equal(importPropParentViewModel.get('childComponent'), canViewModel(importPropScope), 'got view model'); + }); + QUnit.test('one way - child to parent - importing viewModel prop:to="test"', function (assert) { + MockComponent.extend({ + tag: 'import-prop-scope', + template: stache('Hello {{name}}'), + viewModel: { + name: 'David', + age: 7 + } + }); + MockComponent.extend({ + tag: 'import-prop-parent', + template: stache('' + '
      Imported: {{test}}
      ') + }); + var template = stache(''); + var frag = template({}); + assert.equal(frag.childNodes.item(0).childNodes.item(1).innerHTML, 'Imported: David', '{name} component scope imported into variable'); + }); + QUnit.test('one-way - child to parent - viewModel', function (assert) { + MockComponent.extend({ + tag: 'view-model-able', + viewModel: function () { + return new SimpleMap({ viewModelProp: 'Mercury' }); + } + }); + var template = stache(''); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var frag = template(map); + var viewModel = canViewModel(frag.firstChild); + assert.equal(viewModel.get('viewModelProp'), 'Mercury', 'initial value kept'); + assert.equal(map.get('scopeProp'), 'Mercury', 'initial value set on parent'); + viewModel.set('viewModelProp', 'Earth'); + assert.equal(map.get('scopeProp'), 'Earth', 'binding from child to parent'); + map.set('scopeProp', 'Mars'); + assert.equal(viewModel.get('viewModelProp'), 'Earth', 'no binding from parent to child'); + }); + QUnit.test('one-way - child to parent - viewModel - with converters', function (assert) { + MockComponent.extend({ + tag: 'view-model-able', + viewModel: function () { + return new SimpleMap({ viewModelProp: 'Mercury' }); + } + }); + stache.addConverter('upper-case', { + get: function (fooCompute) { + return ('' + canReflect.getValue(fooCompute)).toUpperCase(); + }, + set: function (newVal, fooCompute) { + canReflect.setValue(fooCompute, ('' + newVal).toUpperCase()); + } + }); + var template = stache(''); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var frag = template(map); + var viewModel = canViewModel(frag.firstChild); + assert.equal(viewModel.get('viewModelProp'), 'Mercury', 'initial value kept'); + assert.equal(map.get('scopeProp'), 'MERCURY', 'initial value set on parent, but upper cased'); + viewModel.set('viewModelProp', 'Earth'); + assert.equal(map.get('scopeProp'), 'EARTH', 'binding from child to parent updated'); + map.set('scopeProp', 'Mars'); + assert.equal(viewModel.get('viewModelProp'), 'Earth', 'no binding from parent to child'); + }); + QUnit.test('one-way - parent to child - viewModel', function (assert) { + var template = stache('
      '); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var frag = template(map); + var viewModel = canViewModel(frag.firstChild); + assert.equal(viewModel.attr('viewModelProp'), 'Venus', 'initial value set'); + viewModel.attr('viewModelProp', 'Earth'); + assert.equal(map.attr('scopeProp'), 'Venus', 'no binding from child to parent'); + map.attr('scopeProp', 'Mars'); + assert.equal(viewModel.attr('viewModelProp'), 'Mars', 'binding from parent to child'); + }); + QUnit.test('two-way - reference - child:bind="scope.vars.ref" (#1700)', function (assert) { + var data = new SimpleMap({ person: new SimpleMap({ name: new SimpleMap({}) }) }); + MockComponent.extend({ + tag: 'reference-export', + viewModel: function () { + return new SimpleMap({ tag: 'reference-export' }); + } + }); + MockComponent.extend({ + tag: 'ref-import', + viewModel: function () { + return new SimpleMap({ tag: 'ref-import' }); + } + }); + var template = stache('' + ' {{helperToGetScope()}}'); + var scope; + var frag = template(data, { + helperToGetScope: function (options) { + scope = options.scope; + } + }); + var refExport = canViewModel(frag.firstChild); + var refImport = canViewModel(frag.firstChild.nextSibling); + refExport.set('name', 'v1'); + assert.equal(scope.peek('scope.vars.refName'), 'v1', 'reference scope updated'); + assert.equal(refImport.get('name'), 'v1', 'updated ref-import'); + refImport.set('name', 'v2'); + assert.equal(refExport.get('name'), 'v2', 'updated ref-export'); + assert.equal(scope.peek('scope.vars.refName'), 'v2', 'actually put in refs scope'); + }); + QUnit.test('one-way - DOM - parent value undefined (#189)', function (assert) { + MockComponent.extend({ + tag: 'toggle-button', + viewModel: function () { + var vm = new SimpleMap({ value: false }); + vm.toggle = function () { + this.set('value', !this.get('value')); + }; + return vm; + }, + template: stache('') + }); + var template = stache(''); + var fragment = template({}); + domMutateNode.appendChild.call(this.fixture, fragment); + var button = this.fixture.getElementsByTagName('button')[0]; + function text(node) { + while (node && node.nodeType !== 3) { + node = node.firstChild; + } + return node && node.nodeValue; + } + assert.equal(text(button), 'false', 'Initial value is "false"'); + domEvents.dispatch(button, 'click'); + assert.equal(text(button), 'true', 'Value is "true" after first click'); + domEvents.dispatch(button, 'click'); + assert.equal(text(button), 'false', 'Value is "false" after second click'); + }); + QUnit.test('two way - viewModel (#1700)', function (assert) { + var template = stache('
      '); + var map = new SimpleMap({ scopeProp: 'Hello' }); + var scopeMapSetCalled = 0; + var origMapSetKeyValue = map[canSymbol.for('can.setKeyValue')]; + map[canSymbol.for('can.setKeyValue')] = function (attrName, value) { + if (typeof attrName === 'string' && arguments.length > 1) { + scopeMapSetCalled++; + } + return origMapSetKeyValue.apply(this, arguments); + }; + var frag = template(map); + var viewModel = canViewModel(frag.firstChild); + assert.equal(scopeMapSetCalled, 0, 'set is not called on scope map'); + assert.equal(viewModel.get('viewModelProp'), 'Hello', 'initial value set'); + viewModel = canViewModel(frag.firstChild); + var viewModelSetCalled = 1; + var origViewModelSet = viewModel[canSymbol.for('can.setKeyValue')]; + viewModel[canSymbol.for('can.setKeyValue')] = function (attrName) { + if (typeof attrName === 'string' && arguments.length > 1) { + viewModelSetCalled++; + } + return origViewModelSet.apply(this, arguments); + }; + viewModel.set('viewModelProp', 'HELLO'); + assert.equal(map.get('scopeProp'), 'HELLO', 'binding from child to parent'); + assert.equal(scopeMapSetCalled, 1, 'set is called on scope map'); + assert.equal(viewModelSetCalled, 2, 'set is called viewModel'); + map.set('scopeProp', 'WORLD'); + assert.equal(viewModel.get('viewModelProp'), 'WORLD', 'binding from parent to child'); + assert.equal(scopeMapSetCalled, 1, 'can.setKey is not called again on scope map'); + assert.equal(viewModelSetCalled, 3, 'set is called again on viewModel'); + }); + QUnit.test('standard attributes should not set viewModel props', function (assert) { + MockComponent.extend({ + tag: 'test-elem', + viewModel: SimpleMap + }); + var template = stache(''); + var frag = template(new SimpleMap({ bar: true })); + var vm = canViewModel(frag.firstChild); + assert.equal(vm.get('foo'), undefined); + }); + QUnit.test('set string on the viewModel', function (assert) { + assert.expect(2); + var ViewModel = DefineMap.extend({ + foo: { + type: 'string', + set: function (val) { + assert.equal(val, 'bar'); + } + }, + baz: { + type: 'string', + set: function (val) { + assert.equal(val, 'qux'); + } + } + }); + MockComponent.extend({ + tag: 'test-elem', + viewModel: ViewModel + }); + var template = stache(''); + template(); + }); + QUnit.test('viewModel behavior event bindings should be removed when the bound element is', function (assert) { + MockComponent.extend({ + tag: 'view-model-binder', + viewModel: {}, + template: stache('') + }); + var done = assert.async(); + var onNodeAttributeChange = domMutate.onNodeAttributeChange; + var attributeChangeCount = 0; + var isAttributeChangeTracked = false; + var isTarget = function (target) { + return target.nodeName === 'VIEW-MODEL-BINDER'; + }; + domMutate.onNodeAttributeChange = function (node) { + if (!isTarget(node)) { + return onNodeAttributeChange.apply(null, arguments); + } + attributeChangeCount++; + isAttributeChangeTracked = true; + var disposal = onNodeAttributeChange.apply(null, arguments); + return function () { + attributeChangeCount--; + return disposal(); + }; + }; + var viewModel = new SimpleMap({ + isShowing: true, + bar: 'baz' + }); + var template = stache('
      {{#if isShowing}}
      {{/if}}
      '); + var fragment = template(viewModel); + domMutateNode.appendChild.call(this.fixture, fragment); + var hr = this.fixture.getElementsByTagName('hr')[0]; + var removalDisposal = domMutate.onNodeDisconnected(hr, function () { + removalDisposal(); + domMutate.onNodeAttributeChange = onNodeAttributeChange; + setTimeout(function () { + assert.ok(isAttributeChangeTracked, 'Attribute foo:bind="bar" should be tracked'); + assert.equal(attributeChangeCount, 0, 'all attribute listeners should be disposed'); + done(); + }, 10); + }); + viewModel.attr('isShowing', false); + }); + canTestHelpers.dev.devOnlyTest('warning displayed when using @', function (assert) { + assert.expect(3); + var teardown = canTestHelpers.dev.willWarn('myTemplate.stache:1: functions are no longer called by default so @ is unnecessary in \'@scope.vars.refKey\'.'); + MockComponent.extend({ + tag: 'foo-bar', + viewModel: { + method: function () { + assert.ok(true, 'foo called'); + return 5; + } + } + }); + var template = stache('myTemplate.stache', '{{scope.vars.refKey()}}'); + var frag = template({}); + assert.equal(frag.lastChild.nodeValue, '5'); + assert.equal(teardown(), 2, 'warnings displayed for read and write'); + }); + QUnit.test('bindings.viewModel makeViewModel gets passed the binding state', function (assert) { + var element = document.createElement('bindings-viewmodel'); + element.setAttribute('age:from', 'years'); + stacheBindings.behaviors.viewModel(element, { scope: new Scope({ years: 22 }) }, function (data, hasDataBinding, bindingState) { + assert.equal(bindingState.isSettingOnViewModel, true, 'isSettingOnViewModel called with correct value'); + assert.ok(!bindingState.isSettingViewModel, 'isSettingOnViewModel called with correct value'); + }, {}); + var element2 = document.createElement('bindings-viewmodel'); + element2.setAttribute('this:from', 'user'); + stacheBindings.behaviors.viewModel(element2, { scope: new Scope({ user: { name: 'me' } }) }, function (data, hasDataBinding, bindingState) { + assert.ok(!bindingState.isSettingOnViewModel, 'isSettingOnViewModel called with correct value'); + assert.ok(bindingState.isSettingViewModel, 'isSettingOnViewModel called with correct value'); + }, {}); + }); + QUnit.test('double parent update', function (assert) { + var parentVM = new SimpleMap({ parentValue: '' }); + MockComponent.extend({ + tag: 'parent-that-gets', + viewModel: parentVM, + template: stache('') + }); + MockComponent.extend({ + tag: 'child-that-updates', + viewModel: new SimpleMap({ child: 'CHILD1' }), + template: stache('') + }); + MockComponent.extend({ + tag: 'gc-that-updates', + viewModel: new SimpleMap({ gc: 'gc' }) + }); + var template = stache('{{# if(this.show) }}{{/if}}'); + var root = new SimpleMap({ show: false }); + template(root); + root.set('show', true); + assert.equal(parentVM.get('parentValue'), 'gc'); + }); + QUnit.test('scope.event should be available', function (assert) { + var vm = new SimpleMap({}); + MockComponent.extend({ + tag: 'event-producer', + viewModel: vm, + template: stache('') + }); + var template = stache(''); + template({ + doSomething: function (events, argums, args) { + assert.equal(events.type, 'event', 'got an event'); + assert.equal(argums.length, 2, 'two arguments'); + assert.equal(args.length, 3, '3 args'); + } + }); + vm.dispatch({ type: 'event' }, [ + 1, + 2 + ]); + }); + QUnit.test('nested props with two way binding', function (assert) { + var nestedValue = new SimpleMap({ first: 'Matt' }); + var childVM = new SimpleMap({ name: nestedValue }); + MockComponent.extend({ + tag: 'my-child', + viewModel: childVM, + template: stache('') + }); + var parentVM = new SimpleMap({ name: 'Justin' }); + MockComponent.extend({ + tag: 'my-parent', + viewModel: parentVM, + template: stache('') + }); + var template = stache('')(); + var parentInput = template.childNodes.item(0).childNodes.item(1); + var childInput = template.childNodes.item(0).childNodes.item(0).childNodes.item(0); + parentInput.value = 'updated'; + domEvents.dispatch(parentInput, 'change'); + assert.equal(parentVM.get('name'), 'updated', 'parent vm has correct value'); + assert.equal(nestedValue.get('first'), 'updated', 'child vm has correct value'); + childInput.value = 'child-updated'; + domEvents.dispatch(childInput, 'change'); + assert.equal(parentVM.get('name'), 'child-updated', 'parent vm has correct value'); + assert.equal(nestedValue.get('first'), 'child-updated', 'child vm has correct value'); + }); + canTestHelpers.dev.devOnlyTest('warn when changing the value of a sticky binding child-side (initializing view model)', function (assert) { + assert.expect(2); + var teardown = canTestHelpers.dev.willWarn('can-bind: The child of the sticky two-way binding is changing or converting its value when set. ' + 'Conversions should only be done on the binding parent to preserve synchronization. ' + 'See https://canjs.com/doc/can-stache-bindings.html#StickyBindings for more about sticky bindings', function (text, match) { + if (match) { + assert.ok(true, 'Correct warning generated'); + } + }); + var childVM = new SimpleMap({ name: { first: 'Matt' } }); + MockComponent.extend({ + tag: 'my-child', + viewModel: childVM, + template: stache('') + }); + var parentVM = new SimpleMap({ name: 'Justin' }); + stache('')(parentVM); + assert.equal(teardown(), 1, 'Warning generated only once'); + }); + }); +}); +/*can-stache-bindings@5.0.4#test/colon/hybrid-test*/ +define('can-stache-bindings@5.0.4#test/colon/hybrid-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache-bindings', + 'can-stache', + 'can-simple-map', + 'can-dom-events' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + var stacheBindings = require('can-stache-bindings'); + var stache = require('can-stache'); + var SimpleMap = require('can-simple-map'); + var domEvents = require('can-dom-events'); + stache.addBindings(stacheBindings); + testHelpers.makeTests('can-stache-bindings - colon - hybrids', function (name, doc, enableMO) { + QUnit.test('value:to:on:click and on:click:value:to work (#269)', function (assert) { + var template = stache('' + ''); + var map = new SimpleMap({}); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var bindFirstInput = ta.getElementsByTagName('input')[0]; + bindFirstInput.value = '22'; + domEvents.dispatch(bindFirstInput, 'click'); + assert.equal(map.get('theProp'), '22'); + var eventFirstInput = ta.getElementsByTagName('input')[1]; + eventFirstInput.value = '23'; + domEvents.dispatch(eventFirstInput, 'click'); + assert.equal(map.get('theProp'), '23'); + }); + QUnit.test('on:input:value:to works (#289)', function (assert) { + var scope = new SimpleMap({ myProp: '' }); + var renderer = stache(''); + var view = renderer(scope); + var ta = this.fixture; + ta.appendChild(view); + var inputTo = ta.getElementsByTagName('input')[0]; + inputTo.value = 'wurld'; + domEvents.dispatch(inputTo, 'input'); + assert.equal(scope.get('myProp'), 'wurld', 'Got the value on the scope'); + }); + QUnit.test('on:input:value:to does not initialize values (#289)', function (assert) { + try { + stache('')(); + assert.ok(true, 'renderer was made without error'); + } catch (e) { + assert.ok(false, e.message); + } + }); + QUnit.test('on:input:value:bind should initialize values (#457)', function (assert) { + var frag = stache('')({ foo: 'bar' }); + var input = frag.firstChild; + assert.equal(input.value, 'bar', 'initialized to the parent value'); + }); + }); +}); +/*can-stache-bindings@5.0.4#test/colon/dependencies-test*/ +define('can-stache-bindings@5.0.4#test/colon/dependencies-test', [ + 'require', + 'exports', + 'module', + '@steal', + 'steal-qunit', + 'can-simple-map', + 'can-view-model', + 'can-reflect-dependencies', + 'can-reflect', + 'can-stache', + 'can-stache-bindings' +], function (require, exports, module) { + var steal = require('@steal'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var canViewModel = require('can-view-model'); + var canReflectDeps = require('can-reflect-dependencies'); + var canReflect = require('can-reflect'); + var stache = require('can-stache'); + var stacheBindings = require('can-stache-bindings'); + stache.addBindings(stacheBindings); + var browserSupportsAutomaticallyNamedConstructors = function () { + var C = function C() { + }; + var c = new C(); + return c.constructor.name === 'C'; + }(); + QUnit.module('can-stache-bindings bindings dependencies', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + }, + afterEach: function () { + document.getElementById('qunit-fixture').innerHTML = ''; + } + }); + var devOnlyTest = steal.isEnv('production') ? QUnit.skip : QUnit.test; + devOnlyTest('parent to child dependencies', function (assert) { + var template = stache(''); + var map = new SimpleMap(); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + var inputDeps = canReflectDeps.getDependencyDataOf(input, 'value').whatChangesMe; + assert.ok(inputDeps.mutate.valueDependencies.size, 'the input should have mutation dependencies'); + var attributeObservation = canReflect.toArray(inputDeps.mutate.valueDependencies)[0]; + var attributeObservationDeps = canReflectDeps.getDependencyDataOf(attributeObservation).whatChangesMe; + assert.ok(attributeObservationDeps.derive.keyDependencies.get(input).has('value'), 'the input\'s \'value\' attribute should be a dependency of the attribute observation'); + assert.ok(attributeObservationDeps.mutate.valueDependencies.size, 'the attribute observation should have mutation dependencies'); + var scopeKeyData = canReflect.toArray(attributeObservationDeps.mutate.valueDependencies)[0]; + var scopeKeyDataDeps = canReflectDeps.getDependencyDataOf(scopeKeyData).whatChangesMe; + assert.ok(!scopeKeyDataDeps.mutate, 'the attribute observation should NOT be a dependency of scopeKeyData'); + }); + devOnlyTest('parent to child - map', function (assert) { + var template = stache(''); + var map = new SimpleMap({ age: 10 }); + var frag = template(map); + var ta = this.fixture; + ta.appendChild(frag); + var ageDeps = canReflectDeps.getDependencyDataOf(map, 'age').whatChangesMe; + assert.ok(ageDeps.mutate.valueDependencies.size, 'map.age should have mutation dependencies'); + var scopeKeyData = canReflect.toArray(ageDeps.mutate.valueDependencies)[0]; + var scopeKeyDataDeps = canReflectDeps.getDependencyDataOf(scopeKeyData).whatIChange; + assert.ok(scopeKeyDataDeps.mutate.valueDependencies.size, 'the scopeKeyData should have [whatIChange] mutation dependencies'); + var attributeObservable = canReflect.toArray(scopeKeyDataDeps.mutate.valueDependencies)[0]; + if (browserSupportsAutomaticallyNamedConstructors) { + assert.equal(attributeObservable.constructor.name, 'AttributeObservable', 'scopeKeyData affects the AttributeObservable instance'); + } + }); + devOnlyTest('child to parent dependencies', function (assert) { + var template = stache(''); + var scope = new SimpleMap({ age: 10 }); + var frag = template(scope); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + var inputDeps = canReflectDeps.getDependencyDataOf(input, 'value').whatChangesMe; + assert.ok(inputDeps.mutate.valueDependencies.size, 'the input should have mutation dependencies'); + var attributeObservation = canReflect.toArray(inputDeps.mutate.valueDependencies)[0]; + var attributeObservationDeps = canReflectDeps.getDependencyDataOf(attributeObservation); + assert.ok(attributeObservationDeps.whatChangesMe.derive.keyDependencies.get(input).has('value'), 'the input\'s \'value\' attribute should be a dependency of the attribute observation'); + assert.ok(attributeObservationDeps.whatIChange.mutate.valueDependencies.size, 'The attribute observable changes ScopeObservable'); + var scopeObservable = canReflect.toArray(attributeObservationDeps.whatIChange.mutate.valueDependencies)[0]; + var scopeObservableDeps = canReflectDeps.getDependencyDataOf(scopeObservable).whatIChange.mutate; + assert.ok(scopeObservableDeps.keyDependencies.get(scope).has('age'), 'The scope observable changes the scope\'s \'age\' property'); + }); + devOnlyTest('attribute cross binding dependencies', function (assert) { + var template = stache(''); + var scope = new SimpleMap({ age: 8 }); + var frag = template(scope); + var ta = this.fixture; + ta.appendChild(frag); + var input = ta.getElementsByTagName('input')[0]; + var inputDeps = canReflectDeps.getDependencyDataOf(input, 'value').whatChangesMe; + assert.ok(inputDeps.mutate.valueDependencies.size, 'the input should have mutation dependencies'); + var attributeObservation = canReflect.toArray(inputDeps.mutate.valueDependencies)[0]; + var attributeObservationDeps = canReflectDeps.getDependencyDataOf(attributeObservation).whatChangesMe; + assert.ok(attributeObservationDeps.derive.keyDependencies.get(input).has('value'), 'the input\'s \'value\' attribute should be a dependency of the attribute observation'); + assert.ok(attributeObservationDeps.mutate.valueDependencies.size, 'the attribute observation should have mutation dependencies'); + var scopeKeyData = canReflect.toArray(attributeObservationDeps.mutate.valueDependencies)[0]; + var scopeKeyDataDeps = canReflectDeps.getDependencyDataOf(scopeKeyData).whatChangesMe; + assert.ok(scopeKeyDataDeps.mutate.valueDependencies.has(attributeObservation), 'the attribute observation should be a dependency of scopeKeyData'); + }); + devOnlyTest('view model parent to child binding', function (assert) { + var template = stache('
      '); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var ta = this.fixture; + ta.appendChild(template(map)); + var vm = canViewModel(ta.getElementsByTagName('div')[0]); + var vmDeps = canReflectDeps.getDependencyDataOf(vm, 'viewModelProp').whatChangesMe; + assert.ok(vmDeps.mutate.valueDependencies.size, 'The viewmodel property should have value dependencies'); + var settableObservable = canReflect.toArray(vmDeps.mutate.valueDependencies)[0]; + var settableObservableDeps = canReflectDeps.getDependencyDataOf(settableObservable).whatChangesMe; + assert.ok(settableObservableDeps.mutate.valueDependencies.size, 'The settable observable should have value dependencies'); + var scopeKeyData = canReflect.toArray(settableObservableDeps.mutate.valueDependencies)[0]; + var scopeKeyDataObservationDeps = canReflectDeps.getDependencyDataOf(scopeKeyData.observation).whatChangesMe; + var scopeKeyDataDeps = canReflectDeps.getDependencyDataOf(scopeKeyData).whatChangesMe; + assert.ok(scopeKeyDataObservationDeps.derive.keyDependencies.get(map).has('scopeProp'), 'The ScopeKeyData\'s internal observation is bound to map.scopeProp'); + assert.ok(scopeKeyDataDeps.derive.valueDependencies.has(scopeKeyData.observation), 'The ScopeKeyData is bound to its internal observation'); + }); + devOnlyTest('view model child to parent binding', function (assert) { + var template = stache('
      '); + var map = new SimpleMap({ scopeProp: 'Venus' }); + var ta = this.fixture; + ta.appendChild(template(map)); + var vm = canViewModel(ta.getElementsByTagName('div')[0]); + var vmDeps = canReflectDeps.getDependencyDataOf(vm, 'viewModelProp').whatChangesMe; + assert.ok(vmDeps.mutate.valueDependencies.size, 'The viewmodel property should have value dependencies'); + var settableObservable = canReflect.toArray(vmDeps.mutate.valueDependencies)[0]; + var settableObservableDeps = canReflectDeps.getDependencyDataOf(settableObservable).whatIChange; + assert.ok(settableObservableDeps.mutate.valueDependencies.size, 'The settable observable should have value dependencies'); + var scopeObs = canReflect.toArray(settableObservableDeps.mutate.valueDependencies)[0]; + var scopeObsDeps = canReflectDeps.getDependencyDataOf(scopeObs).whatIChange; + assert.ok(scopeObsDeps.mutate.keyDependencies.get(map).has('scopeProp'), 'The ObservableFromScope is bound to map.scopeProp'); + }); +}); +/*can-stache-bindings@5.0.4#test/colon/tests*/ +define('can-stache-bindings@5.0.4#test/colon/tests', [ + 'require', + 'exports', + 'module', + './basics-test', + './element-test', + './event-test', + './view-model-test', + './hybrid-test', + './dependencies-test' +], function (require, exports, module) { + require('./basics-test'); + require('./element-test'); + require('./event-test'); + require('./view-model-test'); + require('./hybrid-test'); + require('./dependencies-test'); +}); +/*can-stache-bindings@5.0.4#test/data/tests*/ +define('can-stache-bindings@5.0.4#test/data/tests', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../helpers', + 'can-stache-bindings', + 'can-stache', + 'can-simple-map', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-globals', + 'can-observable-object' +], function (require, exports, module) { + (function (global, require, exports, module) { + var QUnit = require('steal-qunit'); + var testHelpers = require('../helpers'); + var stacheBindings = require('can-stache-bindings'); + var stache = require('can-stache'); + var SimpleMap = require('can-simple-map'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var globals = require('can-globals'); + var ObservableObject = require('can-observable-object'); + stache.addBindings(stacheBindings); + testHelpers.makeTests('can-stache-bindings - data', function (name, doc, enableMO, testIfRealDocument, devOnlyTest) { + QUnit.test('event bindings should be removed when the bound element is', function (assert) { + var done = assert.async(); + var template = stache('
      {{#if isShowing}}
      {{/if}}
      '); + var viewModel = new SimpleMap({ + isShowing: true, + bar: 'baz' + }); + var isTarget = function (target) { + return target.nodeName === 'SPAN'; + }; + var attributeChangeCount = 0; + var isAttributeChangeTracked = false; + var onNodeAttributeChange = domMutate.onNodeAttributeChange; + domMutate.onNodeAttributeChange = function (node) { + if (!isTarget(node)) { + return onNodeAttributeChange.apply(null, arguments); + } + attributeChangeCount++; + isAttributeChangeTracked = true; + var disposal = onNodeAttributeChange.apply(null, arguments); + return function () { + attributeChangeCount--; + return disposal(); + }; + }; + var removalCount = 0; + var isRemovalTracked = false; + var onNodeDisconnected = domMutate.onNodeDisconnected; + domMutate.onNodeDisconnected = function (node) { + if (!isTarget(node)) { + return onNodeDisconnected.apply(null, arguments); + } + removalCount++; + isRemovalTracked = true; + var disposal = onNodeDisconnected.apply(null, arguments); + return function () { + removalCount--; + return disposal(); + }; + }; + var fragment = template(viewModel); + domMutateNode.appendChild.call(this.fixture, fragment); + var hr = this.fixture.getElementsByTagName('hr')[0]; + var removalDisposal = domMutate.onNodeDisconnected(hr, function () { + removalDisposal(); + setTimeout(function () { + domMutate.onNodeAttributeChange = onNodeAttributeChange; + assert.ok(isAttributeChangeTracked, 'Attribute foo:from="bar" should be tracked'); + assert.equal(attributeChangeCount, 0, 'all attribute listeners should be disposed'); + domMutate.onNodeDisconnected = onNodeDisconnected; + assert.ok(isRemovalTracked, 'Element span should be tracked'); + assert.equal(removalCount, 0, 'all removal listeners should be disposed'); + done(); + }, 10); + }); + viewModel.attr('isShowing', false); + }); + QUnit.test('raw bindings using :raw', function (assert) { + var template = stache(''); + var frag = template(); + assert.equal(frag.firstChild.getAttribute('foo'), 'bar', 'bound raw'); + }); + testIfRealDocument('Bindings are removed when the node\'s documentElement is', function (assert) { + var done = assert.async(); + var realDoc = globals.getKeyValue('document'); + var d = doc.implementation.createHTMLDocument('Test'); + globals.setKeyValue('document', d); + var template = stache('
      Test
      '); + d.body.appendChild(template({ + doStuff: function () { + } + })); + var el = d.body.firstChild; + var removalDisposal = domMutate.onNodeDisconnected(el, function () { + removalDisposal(); + globals.setKeyValue('document', realDoc); + assert.ok(true, 'Tore down bindings correctly'); + done(); + }); + domMutateNode.removeChild.call(d, d.documentElement); + }); + devOnlyTest('Explain that elements always set properties to Strings', function (assert) { + assert.expect(1); + class Foo extends ObservableObject { + static get props() { + return { num: Number }; + } + } + try { + stache('')(new Foo()); + assert.ok(true); + } catch (e) { + assert.equal(e.message, '"" (string) is not of type Number. Property num is using "type: Number". Use "num: type.convert(Number)" to automatically convert values to Numbers when setting the "num" property. elements always set properties to Strings.'); + } finally { + testHelpers.cleanupQueues(); + } + }); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-bindings@5.0.4#test/tests*/ +define('can-stache-bindings@5.0.4#test/tests', [ + 'require', + 'exports', + 'module', + './colon/tests', + './data/tests' +], function (require, exports, module) { + require('./colon/tests'); + require('./data/tests'); +}); +/*can-query-logic@1.2.2#src/set-test*/ +define('can-query-logic@1.2.2#src/set-test', [ + 'require', + 'exports', + 'module', + './set', + 'steal-qunit' +], function (require, exports, module) { + var set = require('./set'); + var QUnit = require('steal-qunit'); + QUnit.module('can-query-logic/set'); + QUnit.test('.ownAndMemberValue', function (assert) { + assert.deepEqual(set.ownAndMemberValue(1, '1'), { + own: 1, + member: 1 + }, '1 and \'1\''); + assert.deepEqual(set.ownAndMemberValue({ + valueOf: function () { + return null; + } + }, '1'), { + own: null, + member: '1' + }, '{null} and \'1\''); + }); + QUnit.test('.isDefinedAndHasMembers', function (assert) { + assert.equal(set.isDefinedAndHasMembers({}), true); + assert.equal(set.isDefinedAndHasMembers(set.UNIVERSAL), true); + assert.equal(set.isDefinedAndHasMembers(set.UNDEFINABLE), false); + }); +}); +/*can-query-logic@1.2.2#src/helpers-test*/ +define('can-query-logic@1.2.2#src/helpers-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var canReflect = require('can-reflect'); + QUnit.module('can-query-logic/helpers'); + QUnit.test('.getIdentityIndex', function (assert) { + var items = [ + { + id: 1, + name: 'Item 0' + }, + { + id: 2, + name: 'Item 1' + }, + { + id: 3, + name: 'Item 1' + }, + { + id: 4, + name: 'Item 1' + }, + { + id: 5, + name: 'Item 2' + } + ]; + canReflect.eachIndex(items, function (item) { + canReflect.assignSymbols(item, { + 'can.getSchema': function () { + return { + type: 'map', + identity: ['id'], + keys: { + id: Number, + name: String + } + }; + } + }); + }); + var props = { + id: 2, + name: 'Item 1' + }; + canReflect.assignSymbols(props, { + 'can.getSchema': function () { + return { + type: 'map', + identity: ['id'], + keys: { + id: Number, + name: String + } + }; + } + }); + var compare = helpers.sorter('name', {}); + var res = helpers.getIdentityIndex(compare, items, props, 1); + assert.deepEqual(res, 1); + }); + QUnit.test('.getIndex should not sort unchanged items #33', function (assert) { + var items = [ + { + id: 1, + name: 'Item 0' + }, + { + id: 2, + name: 'Item 1' + }, + { + id: 3, + name: 'Item 1' + }, + { + id: 4, + name: 'Item 1' + }, + { + id: 5, + name: 'Item 2' + } + ]; + canReflect.eachIndex(items, function (item) { + canReflect.assignSymbols(item, { + 'can.getSchema': function () { + return { + type: 'map', + identity: ['id'], + keys: { + id: Number, + name: String + } + }; + } + }); + }); + var compare = helpers.sorter('name', {}); + var res1 = helpers.getIndex(compare, items, items[0]); + var res2 = helpers.getIndex(compare, items, items[1]); + var res3 = helpers.getIndex(compare, items, items[2]); + var res4 = helpers.getIndex(compare, items, items[3]); + assert.equal(res1, 0); + assert.equal(res2, 1); + assert.equal(res3, 2); + assert.equal(res4, 3); + }); + QUnit.test('Missed schema on helper.getIndex #45', function (assert) { + var items = [ + { + id: 1, + name: 'Item 0' + }, + { + id: 2, + name: 'Item 1' + }, + { + id: 3, + name: 'Item 2' + }, + { + id: 4, + name: 'Item 3' + }, + { + id: 5, + name: 'Item 4' + } + ]; + var compare = helpers.sorter('name', {}); + var schema = { + keys: {}, + identity: ['id'] + }; + assert.equal(helpers.getIndex(compare, items, { + id: 2, + name: 'Item 1' + }, schema), 1); + }); +}); +/*can-query-logic@1.2.2#src/types/make-real-number-range-inclusive-test*/ +define('can-query-logic@1.2.2#src/types/make-real-number-range-inclusive-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../set', + './make-real-number-range-inclusive' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../set'); + var RealNumberRangeInclusive = require('./make-real-number-range-inclusive')(-Infinity, Infinity); + QUnit.module('can-query-logic/types/make-real-number-range-inclusive'); + QUnit.test('isSubset', function (assert) { + assert.equal(set.isSubset(new RealNumberRangeInclusive(1, 4), new RealNumberRangeInclusive(0, 5)), true, '1-4 subset of 0-5'); + assert.equal(set.isSubset(new RealNumberRangeInclusive(0, 5), new RealNumberRangeInclusive(1, 4)), false, '0-5 subset of 1-4 subset'); + }); + QUnit.test('isEqual with universal', function (assert) { + assert.equal(set.isEqual(new RealNumberRangeInclusive(1, 4), set.UNIVERSAL), false, 'universal second'); + assert.equal(set.isEqual(set.UNIVERSAL, new RealNumberRangeInclusive(1, 4)), false, 'universal first'); + assert.equal(set.isEqual(new RealNumberRangeInclusive(-Infinity, Infinity), set.UNIVERSAL), true, 'eq universal second'); + assert.equal(set.isEqual(set.UNIVERSAL, new RealNumberRangeInclusive(-Infinity, Infinity)), true, 'eq universal second'); + }); +}); +/*can-query-logic@1.2.2#src/types/comparisons-test*/ +define('can-query-logic@1.2.2#src/types/comparisons-test', [ + 'require', + 'exports', + 'module', + './comparisons', + '../set', + './values-not' +], function (require, exports, module) { + var compare = require('./comparisons'); + var set = require('../set'); + var is = compare; + var ValuesNot = require('./values-not'); + QUnit.module('can-query-logic/types/comparisons'); + var tests = { + In_In: { + union: function (assert) { + var isIn5 = new is.In([5]), isIn6 = new is.In([6]); + assert.deepEqual(set.union(isIn5, isIn6), new is.In([ + 5, + 6 + ])); + }, + intersection: function (assert) { + var isIn5 = new is.In([5]), isIn6 = new is.In([6]); + assert.deepEqual(set.intersection(isIn5, isIn6), set.EMPTY); + var in13 = new is.In([ + 1, + 2, + 3 + ]), in24 = new is.In([ + 2, + 3, + 4 + ]); + assert.deepEqual(set.intersection(in13, in24), new is.In([ + 2, + 3 + ])); + }, + difference: function (assert) { + var isIn5 = new is.In([5]), isIn6 = new is.In([6]); + assert.deepEqual(set.difference(isIn5, isIn6), isIn5); + var in13 = new is.In([ + 1, + 2, + 3 + ]), in24 = new is.In([ + 2, + 3, + 4 + ]); + assert.deepEqual(set.difference(in13, in24), new is.In([1])); + } + }, + In_isMember: function (assert) { + assert.ok(new is.In([5]).isMember(5)); + assert.notOk(new is.In([5]).isMember(6)); + assert.ok(new is.In([ + 5, + -1 + ]).isMember(-1)); + }, + UNIVERSAL_In: { + difference: function (assert) { + var isIn5 = new is.In([5]); + assert.deepEqual(set.difference(set.UNIVERSAL, isIn5), new is.NotIn([5])); + var in13 = new is.In([ + 1, + 2, + 3 + ]); + assert.deepEqual(set.difference(set.UNIVERSAL, in13), new is.NotIn([ + 1, + 2, + 3 + ])); + } + }, + In_NotIn: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.NotIn([ + 6, + 7 + ]); + assert.deepEqual(set.union(a, b), new is.NotIn([7])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.NotIn([ + 6, + 7 + ]); + assert.deepEqual(set.intersection(a, b), new is.In([5])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.NotIn([ + 6, + 7 + ]); + assert.deepEqual(set.difference(a, b), new is.In([6])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.difference(a, b), new is.In([ + 5, + 6 + ])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 8, + 9 + ]); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + NotIn_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.NotIn([ + 6, + 7 + ]); + assert.deepEqual(set.difference(b, a), new is.NotIn([ + 6, + 7, + 5 + ])); + a = new is.In([ + 5, + 6 + ]); + b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.difference(b, a), new is.NotIn([ + 5, + 6 + ])); + } + }, + In_GreaterThan: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), b); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([2]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(2); + assert.deepEqual(set.union(a, b), new is.GreaterThanEqual(2)); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.intersection(a, b), a); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.intersection(a, b), new is.In([4])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.In([2])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(a, b), new is.In([ + 2, + 4 + ])); + a = new is.In([ + null, + undefined + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(a, b), new is.In([ + null, + undefined + ]), 'handles weird types'); + } + }, + GreaterThan_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + var difference = set.difference(b, a); + assert.deepEqual(difference, new is.And([ + new is.NotIn([ + 5, + 6 + ]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.NotIn([4]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(b, a), b); + } + }, + In_GreaterThanEqual: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), b); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([2]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(2); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.intersection(a, b), a); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.intersection(a, b), new is.In([4])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.In([2])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(a, b), new is.In([ + 2, + 4 + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(2); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + GreaterThanEqual_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + var difference = set.difference(b, a); + assert.deepEqual(difference, new is.And([ + new is.NotIn([ + 5, + 6 + ]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.NotIn([4]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(b, a), b); + } + }, + In_LessThan: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThan(7); + assert.deepEqual(set.union(a, b), b); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(3); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([4]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(4); + assert.deepEqual(set.union(a, b), new is.LessThanEqual(4)); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThan(7); + assert.deepEqual(set.intersection(a, b), a); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(3); + assert.deepEqual(set.intersection(a, b), new is.In([2])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThan(7); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 5, + 6 + ]); + b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), new is.In([6])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(3); + assert.deepEqual(set.difference(a, b), new is.In([4])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(1); + assert.deepEqual(set.difference(a, b), new is.In([ + 2, + 4 + ])); + } + }, + LessThan_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThan(7); + var difference = set.difference(b, a); + assert.deepEqual(difference, new is.And([ + new is.NotIn([ + 5, + 6 + ]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(3); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.NotIn([2]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThan(1); + assert.deepEqual(set.difference(b, a), b); + } + }, + In_LessThanEqual: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + assert.deepEqual(set.union(a, b), b); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([4]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(4); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + assert.deepEqual(set.intersection(a, b), a); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.intersection(a, b), new is.In([2])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 5, + 6 + ]); + b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.In([4])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(1); + assert.deepEqual(set.difference(a, b), new is.In([ + 2, + 4 + ])); + } + }, + LessThanEqual_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + var difference = set.difference(b, a); + assert.deepEqual(difference, new is.And([ + new is.NotIn([ + 5, + 6 + ]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.NotIn([2]), + b + ])); + a = new is.In([ + 2, + 4 + ]); + b = new is.LessThanEqual(1); + assert.deepEqual(set.difference(b, a), b); + } + }, + In_And: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.In([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.In([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a); + a = new is.In([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + And_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), b); + a = new is.In([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + var res = set.difference(b, a); + assert.deepEqual(res, new is.And([ + new is.NotIn([ + 15, + 16 + ]), + b + ])); + } + }, + In_Or: { + union: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(1) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.In([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.union(a, b), b); + var gt1 = new is.GreaterThan(1), lt1 = new is.LessThan(1), eq1 = new is.In([1]); + var intermediate = set.union(gt1, lt1); + var result = set.union(intermediate, eq1); + assert.equal(result, set.UNIVERSAL, 'foo > 1 || foo < 1 || foo === 1 => UNIVERSAL'); + }, + intersection: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(1) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.In([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(a, b), a); + a = new is.In([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + Or_In: { + difference: function (assert) { + var a = new is.In([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(b, a), b); + a = new is.In([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + var res = set.difference(b, a); + assert.deepEqual(res, new is.And([ + new is.NotIn([ + 15, + 16 + ]), + b + ])); + } + }, + NotIn_NotIn: { + union: function (assert) { + var isNotIn5 = new is.NotIn([5]), isNotIn6 = new is.NotIn([6]); + assert.deepEqual(set.union(isNotIn5, isNotIn6), set.UNIVERSAL); + var a = new is.NotIn([ + 4, + 5 + ]), b = new is.NotIn([ + 5, + 6 + ]); + assert.deepEqual(set.union(a, b), new is.NotIn([5])); + }, + intersection: function (assert) { + var isNotIn5 = new is.NotIn([5]), isNotIn6 = new is.NotIn([6]); + assert.deepEqual(set.intersection(isNotIn5, isNotIn6), new is.NotIn([ + 5, + 6 + ])); + var in13 = new is.NotIn([ + 1, + 2, + 3 + ]), in24 = new is.NotIn([ + 2, + 3, + 4 + ]); + assert.deepEqual(set.intersection(in13, in24), new is.NotIn([ + 1, + 2, + 3, + 4 + ])); + }, + difference: function (assert) { + var isNotIn5 = new is.NotIn([5]), isNotIn6 = new is.NotIn([6]); + assert.deepEqual(set.difference(isNotIn5, isNotIn6), new is.In([5])); + var a = new is.NotIn([ + 2, + 3 + ]), b = new is.NotIn([ + 3, + 4 + ]); + assert.deepEqual(set.difference(a, b), new is.In([2])); + } + }, + UNIVERSAL_NotIn: { + difference: function (assert) { + var a = new is.NotIn([5]); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.In([5])); + var b = new is.NotIn([ + 1, + 2, + 3 + ]); + assert.deepEqual(set.difference(set.UNIVERSAL, b), new is.In([ + 1, + 2, + 3 + ])); + } + }, + NotIn_isMember: function (assert) { + assert.notOk(new is.NotIn([5]).isMember(5)); + assert.ok(new is.NotIn([5]).isMember(6)); + assert.notOk(new is.NotIn([ + 5, + -1 + ]).isMember(-1)); + }, + NotIn_GreaterThan: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), new is.NotIn([2])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(2); + assert.deepEqual(set.union(a, b), new is.NotIn([2])); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThan(3), res; + res = set.intersection(a, b); + assert.deepEqual(res, new is.And([ + a, + b + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.NotIn([4]), + b + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.LessThanEqual(3)); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([2]), + new is.LessThanEqual(3) + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + 2, + 4 + ]), + new is.LessThanEqual(8) + ])); + a = new is.NotIn([ + null, + undefined + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + null, + undefined + ]), + new is.LessThanEqual(8) + ]), 'handles weird types'); + } + }, + GreaterThan_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThan(3); + assert.deepEqual(set.difference(b, a), new is.In([ + 5, + 6 + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(3); + assert.deepEqual(set.difference(b, a), new is.In([4])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(b, a), set.EMPTY); + a = new is.NotIn([ + null, + undefined + ]); + b = new is.GreaterThan(8); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'handles weird types'); + } + }, + NotIn_GreaterThanEqual: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), new is.NotIn([2])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(2); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3), res; + res = set.intersection(a, b); + assert.deepEqual(res, new is.And([ + a, + b + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.NotIn([4]), + b + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.LessThan(3)); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([2]), + new is.LessThan(3) + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + 2, + 4 + ]), + new is.LessThan(8) + ])); + a = new is.NotIn([ + null, + undefined + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + null, + undefined + ]), + new is.LessThan(8) + ]), 'handles weird types'); + } + }, + GreaterThanEqual_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.In([ + 5, + 6 + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.In([4])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(b, a), set.EMPTY); + a = new is.NotIn([2]); + b = new is.GreaterThanEqual(2); + assert.deepEqual(set.difference(b, a), new is.In([2])); + a = new is.NotIn([ + null, + undefined + ]); + b = new is.GreaterThanEqual(8); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'handles weird types'); + } + }, + NotIn_LessThan: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 7 + ]); + var b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), new is.NotIn([7])); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.LessThan(7), res; + res = set.intersection(a, b); + assert.deepEqual(res, new is.And([ + a, + b + ])); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.LessThan(7); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(7)); + } + }, + LessThan_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 7 + ]); + var b = new is.LessThan(6); + assert.deepEqual(set.difference(b, a), new is.In([5])); + } + }, + NotIn_LessThanEqual: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 7 + ]); + var b = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), new is.NotIn([7])); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7), res; + res = set.intersection(a, b); + assert.deepEqual(res, new is.And([ + a, + b + ])); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.LessThanEqual(7); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(7)); + a = new is.NotIn([ + 5, + 6 + ]); + b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(6)); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([4]), + new is.GreaterThan(3) + ])); + a = new is.NotIn([ + 2, + 4 + ]); + b = new is.LessThanEqual(1); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([ + 2, + 4 + ]), + new is.GreaterThan(1) + ])); + a = new is.NotIn([undefined]); + b = new is.LessThanEqual(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.NotIn([undefined]), + new is.GreaterThan(3) + ])); + } + }, + LessThanEqual_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 7 + ]); + var b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(b, a), new is.In([5])); + } + }, + NotIn_And: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ]), 'not in within range'); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.And([ + a, + new is.Or([ + new is.GreaterThanEqual(20), + new is.LessThanEqual(7) + ]) + ])); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThanEqual(20), + new is.LessThanEqual(7) + ])); + } + }, + And_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + var res = set.difference(b, a); + assert.deepEqual(res, new is.In([ + 15, + 16 + ])); + } + }, + NotIn_Or: { + union: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(1) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.NotIn([ + 5, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.union(a, b), new is.NotIn([5])); + }, + intersection: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(1) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.NotIn([8]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ])); + }, + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.And([ + a, + new is.And([ + new is.GreaterThanEqual(2), + new is.LessThanEqual(7) + ]) + ])); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(2), + new is.LessThanEqual(7) + ])); + } + }, + Or_NotIn: { + difference: function (assert) { + var a = new is.NotIn([ + 5, + 6 + ]); + var b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'between'); + a = new is.NotIn([ + 15, + 16 + ]); + b = new is.Or([ + new is.GreaterThan(7), + new is.LessThan(2) + ]); + var res = set.difference(b, a); + assert.deepEqual(res, new is.In([ + 15, + 16 + ]), 'within'); + } + }, + GreaterThan_GreaterThan: { + union: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThan(6); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThan('foo'); + b = new is.GreaterThan('bar'); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThan(6); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThan('foo'); + b = new is.GreaterThan('bar'); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThan(6); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThanEqual(6) + ])); + a = new is.GreaterThan(5); + b = new is.GreaterThan(6); + assert.deepEqual(set.difference(b, a), set.EMPTY); + } + }, + GreaterThan_isMember: function (assert) { + assert.notOk(new is.GreaterThan(5).isMember(5)); + assert.ok(new is.GreaterThan(5).isMember(6)); + }, + UNIVERSAL_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(5); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.LessThanEqual(5)); + } + }, + GreaterThan_GreaterThanEqual: { + union: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThan('foo'); + b = new is.GreaterThanEqual('bar'); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThan('foo'); + b = new is.GreaterThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThan(6) + ])); + a = new is.GreaterThan(6); + b = new is.GreaterThanEqual(5); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.GreaterThan(5); + b = new is.GreaterThanEqual(5); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + GreaterThanEqual_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.GreaterThan(6); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThanEqual(6) + ])); + a = new is.GreaterThanEqual(6); + b = new is.GreaterThan(5); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.GreaterThanEqual(5); + b = new is.GreaterThan(5); + assert.deepEqual(set.difference(a, b), new is.In([5])); + } + }, + GreaterThan_LessThan: { + union: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThan('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.GreaterThan(5); + b = new is.LessThan(5); + assert.deepEqual(set.union(a, b), new is.NotIn([5])); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ]), 'anded'); + a = new is.GreaterThan('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThan(20); + b = new is.LessThan(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(6)); + a = new is.GreaterThan(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), a); + a = new is.GreaterThan(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), a); + } + }, + LessThan_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThan(6); + var res = set.difference(b, a); + assert.deepEqual(res, new is.LessThanEqual(5)); + a = new is.GreaterThan(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(b, a), b); + a = new is.GreaterThan(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(b, a), b); + } + }, + GreaterThan_LessThanEqual: { + union: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThanEqual(5); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThan('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ])); + a = new is.GreaterThan('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThan(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(6)); + a = new is.GreaterThan(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), a); + a = new is.GreaterThan(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), a); + } + }, + LessThanEqual_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(b, a), new is.LessThanEqual(5)); + a = new is.GreaterThan(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(b, a), b); + a = new is.GreaterThan(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(b, a), b); + } + }, + GreaterThan_And: { + union: function (assert) { + var a = new is.GreaterThan([10]); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.GreaterThan(7)); + a = new is.GreaterThan(3); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThan(21); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.GreaterThan(5); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(10), + new is.LessThan(20) + ])); + a = new is.GreaterThan(25); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'should be empty'); + }, + difference: function (assert) { + var a = new is.GreaterThan(5); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.And([ + a, + new is.LessThanEqual(7) + ]), + new is.GreaterThanEqual(20) + ]), 'wraps'); + a = new is.GreaterThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(20), 'in between'); + a = new is.GreaterThan(25); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a, 'outside'); + } + }, + And_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(5); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'within'); + a = new is.GreaterThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(7), + new is.LessThanEqual(10) + ]), 'in between'); + a = new is.GreaterThan(25); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), b, 'outside'); + } + }, + GreaterThan_Or: { + union: function (assert) { + var a = new is.GreaterThan(10); + var b = new is.Or([ + new is.GreaterThan(20), + new is.LessThan(7) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThan(10), + new is.LessThan(7) + ])); + a = new is.GreaterThan(3); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThan(21); + assert.deepEqual(set.union(a, b), b); + a = new is.GreaterThan(0); + b = new is.Or([ + new is.GreaterThan(7), + new is.In([null]) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([null]), + a + ]), 'union with a null'); + }, + intersection: function (assert) { + var a = new is.GreaterThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.GreaterThan(20)); + a = new is.GreaterThan(3); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.GreaterThan(20), + new is.And([ + a, + new is.LessThan(7) + ]) + ])); + a = new is.GreaterThan(21); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThanEqual(20) + ]), 'inside'); + a = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThanEqual(20) + ]), 'left'); + a = new is.GreaterThan(21); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'right'); + } + }, + Or_GreaterThan: { + difference: function (assert) { + var a = new is.GreaterThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.LessThan(7), 'inside'); + a = new is.GreaterThan(3); + assert.deepEqual(set.difference(b, a), new is.LessThanEqual(3), 'left'); + a = new is.GreaterThan(21); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.LessThan(7), + new is.And([ + new is.GreaterThan(20), + new is.LessThanEqual(21) + ]) + ]), 'right'); + } + }, + GreaterThanEqual_GreaterThanEqual: { + union: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThanEqual('foo'); + b = new is.GreaterThanEqual('bar'); + assert.deepEqual(set.union(a, b), b); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThanEqual('foo'); + b = new is.GreaterThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.GreaterThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.LessThan(6) + ])); + a = new is.GreaterThanEqual(5); + b = new is.GreaterThanEqual(6); + assert.deepEqual(set.difference(b, a), set.EMPTY); + } + }, + GreaterThanEqual_isMember: function (assert) { + assert.notOk(new is.GreaterThanEqual(5).isMember(4)); + assert.ok(new is.GreaterThanEqual(5).isMember(5)); + assert.ok(new is.GreaterThan(5).isMember(6)); + }, + UNIVERSAL_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.LessThan(5)); + } + }, + GreaterThanEqual_LessThan: { + union: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.GreaterThanEqual(5); + b = new is.LessThan(5); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ]), 'anded'); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThanEqual(20); + b = new is.LessThan(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThanEqual(20); + b = new is.LessThan(20); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + }, + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(6)); + a = new is.GreaterThanEqual(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), a); + a = new is.GreaterThanEqual(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), a); + } + }, + LessThan_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(b, a), new is.LessThan(5)); + a = new is.GreaterThanEqual(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(b, a), b); + a = new is.GreaterThanEqual(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(b, a), b); + } + }, + GreaterThanEqual_LessThanEqual: { + union: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + a = new is.GreaterThanEqual(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), new is.And([ + a, + b + ]), 'anded'); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThanEqual(20); + b = new is.LessThanEqual(1); + assert.deepEqual(set.intersection(a, b), set.EMPTY); + a = new is.GreaterThanEqual(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.intersection(a, b), new is.In([5])); + a = new is.GreaterThanEqual('foo'); + b = new is.LessThanEqual('foo'); + assert.deepEqual(set.intersection(a, b), new is.In(['foo'])); + }, + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(6)); + a = new is.GreaterThanEqual(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), a); + a = new is.GreaterThanEqual(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), new is.GreaterThan(5)); + } + }, + LessThanEqual_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(b, a), new is.LessThan(5)); + a = new is.GreaterThanEqual(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(b, a), b); + a = new is.GreaterThanEqual(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(b, a), new is.LessThan(5)); + } + }, + GreaterThanEqual_And: { + union: function (assert) { + var a = new is.GreaterThanEqual([10]); + var b = new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.GreaterThanEqual(7)); + a = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), a); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(5); + var b = new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.GreaterThanEqual(10); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(20) + ])); + a = new is.GreaterThanEqual(25); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'should be empty'); + }, + difference: function (assert) { + var a = new is.GreaterThan(5); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.And([ + a, + new is.LessThanEqual(7) + ]), + new is.GreaterThanEqual(20) + ]), 'wraps'); + a = new is.GreaterThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.GreaterThanEqual(20), 'in between'); + a = new is.GreaterThan(25); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a, 'outside'); + } + }, + And_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(5); + var b = new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'within'); + a = new is.GreaterThanEqual(10); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(10) + ]), 'in between'); + a = new is.GreaterThanEqual(25); + assert.deepEqual(set.difference(b, a), b, 'outside'); + } + }, + GreaterThanEqual_Or: { + union: function (assert) { + var a = new is.GreaterThanEqual(10); + var b = new is.Or([ + new is.GreaterThanEqual(20), + new is.LessThan(7) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(10), + new is.LessThan(7) + ])); + a = new is.GreaterThanEqual(3); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.union(a, b), b); + a = new is.GreaterThanEqual(0); + b = new is.Or([ + new is.GreaterThanEqual(7), + new is.In([null]) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([null]), + a + ]), 'union with a null'); + }, + intersection: function (assert) { + var a = new is.GreaterThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.GreaterThanEqual(20)); + a = new is.GreaterThanEqual(3); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.GreaterThanEqual(20), + new is.And([ + a, + new is.LessThan(7) + ]) + ])); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.GreaterThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThanEqual(20) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.And([ + a, + new is.LessThan(20) + ]), 'inside'); + a = new is.GreaterThan(3); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThan(20) + ]), 'left'); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'right'); + } + }, + Or_GreaterThanEqual: { + difference: function (assert) { + var a = new is.GreaterThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.difference(b, a), new is.LessThan(7), 'inside'); + a = new is.GreaterThanEqual(3); + assert.deepEqual(set.difference(b, a), new is.LessThan(3), 'left'); + a = new is.GreaterThanEqual(21); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.LessThan(7), + new is.And([ + new is.GreaterThanEqual(20), + new is.LessThan(21) + ]) + ]), 'right'); + } + }, + LessThan_LessThan: { + union: function (assert) { + var a = new is.LessThan(5), b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThan('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.union(a, b), a); + }, + intersection: function (assert) { + var a = new is.LessThan(5), b = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), a); + a = new is.LessThan('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.LessThan(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + assert.deepEqual(set.difference(b, a), new is.And([ + b, + new is.GreaterThanEqual(5) + ])); + } + }, + LessThan_isMember: function (assert) { + assert.ok(new is.LessThan(5).isMember(4)); + assert.notOk(new is.LessThan(5).isMember(5)); + assert.notOk(new is.LessThan(5).isMember(6)); + }, + UNIVERSAL_LessThan: { + difference: function (assert) { + var a = new is.LessThan(5); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.GreaterThanEqual(5)); + } + }, + LessThan_LessThanEqual: { + union: function (assert) { + var a = new is.LessThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThan('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.union(a, b), a); + }, + intersection: function (assert) { + var a = new is.LessThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), a); + a = new is.LessThan('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.LessThan(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.LessThan(6); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.GreaterThan(5) + ])); + a = new is.LessThan(7); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.GreaterThan(5) + ])); + a = new is.LessThan(5); + b = new is.LessThanEqual(5); + assert.deepEqual(set.difference(a, b), set.EMPTY); + } + }, + LessThanEqual_LessThan: { + union: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThanEqual('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.union(a, b), a); + }, + intersection: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), a); + a = new is.LessThanEqual('foo'); + b = new is.LessThan('bar'); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + a = new is.LessThanEqual(6); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), new is.And([ + a, + new is.GreaterThanEqual(5) + ])); + a = new is.LessThanEqual(5); + b = new is.LessThan(5); + assert.deepEqual(set.difference(a, b), new is.In([5])); + } + }, + LessThan_And: { + union: function (assert) { + var a = new is.LessThan(10); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.LessThan(20)); + a = new is.LessThan(33); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.LessThan(6); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.LessThan(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), b); + a = new is.LessThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(7), + new is.LessThan(10) + ])); + a = new is.LessThan(6); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'should be empty'); + }, + difference: function (assert) { + var a = new is.LessThan(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.LessThanEqual(7), + new is.And([ + a, + new is.GreaterThanEqual(20) + ]) + ]), 'wraps'); + a = new is.LessThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.LessThanEqual(7), 'in between'); + a = new is.LessThan(3); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a, 'outside'); + } + }, + And_LessThan: { + difference: function (assert) { + var a = new is.LessThan(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'within'); + a = new is.LessThan(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(20) + ]), 'in between'); + a = new is.LessThan(4); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), b, 'outside'); + } + }, + LessThan_Or: { + union: function (assert) { + var a = new is.LessThan(10); + var b = new is.Or([ + new is.GreaterThan(20), + new is.LessThan(7) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThan(20), + new is.LessThan(10) + ])); + a = new is.LessThan(21); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.LessThan(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThan(7); + b = new is.Or([ + new is.LessThan(0), + new is.In([null]) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([null]), + a + ]), 'union with a null'); + }, + intersection: function (assert) { + var a = new is.LessThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.LessThan(7)); + a = new is.LessThan(33); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.LessThan(7), + new is.And([ + new is.GreaterThan(20), + a + ]) + ])); + a = new is.LessThan(6); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.LessThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + a + ]), 'inside'); + a = new is.LessThan(33); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThanEqual(20) + ]), 'left'); + a = new is.LessThan(6); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'right'); + } + }, + Or_LessThan: { + difference: function (assert) { + var a = new is.LessThan(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.GreaterThan(20), 'inside'); + a = new is.LessThan(33); + assert.deepEqual(set.difference(b, a), new is.GreaterThanEqual(33), 'left'); + a = new is.LessThan(6); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.GreaterThan(20), + new is.And([ + new is.LessThan(7), + new is.GreaterThanEqual(6) + ]) + ]), 'right'); + } + }, + LessThanEqual_LessThanEqual: { + union: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThanEqual('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.union(a, b), a); + }, + intersection: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), a); + a = new is.LessThanEqual('foo'); + b = new is.LessThanEqual('bar'); + assert.deepEqual(set.intersection(a, b), b); + }, + difference: function (assert) { + var a = new is.LessThanEqual(5), b = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), set.EMPTY); + assert.deepEqual(set.difference(b, a), new is.And([ + b, + new is.GreaterThan(5) + ])); + } + }, + LessThanEqual_isMember: function (assert) { + assert.ok(new is.LessThanEqual(5).isMember(4)); + assert.ok(new is.LessThanEqual(5).isMember(5)); + assert.notOk(new is.LessThanEqual(5).isMember(6)); + }, + UNIVERSAL_LessThanEqual: { + difference: function (assert) { + var a = new is.LessThanEqual(5); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.GreaterThan(5)); + } + }, + LessThanEqual_And: { + union: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.LessThan(20)); + a = new is.LessThanEqual(33); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), a); + a = new is.LessThanEqual(6); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ])); + }, + intersection: function (assert) { + var a = new is.LessThanEqual(0); + var b = new is.And([ + new is.GreaterThanEqual(0), + new is.LessThan(1) + ]); + assert.deepEqual(set.intersection(a, b), new is.In([0]), 'overlap to in'); + }, + difference: function (assert) { + var a = new is.LessThanEqual(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.LessThanEqual(7), + new is.And([ + a, + new is.GreaterThanEqual(20) + ]) + ]), 'wraps'); + a = new is.LessThanEqual(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.LessThanEqual(7), 'in between'); + a = new is.LessThanEqual(3); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(a, b), a, 'outside'); + } + }, + And_LessThanEqual: { + difference: function (assert) { + var a = new is.LessThanEqual(21); + var b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), set.EMPTY, 'within'); + a = new is.LessThanEqual(10); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(10), + new is.LessThan(20) + ]), 'in between'); + a = new is.LessThanEqual(4); + b = new is.And([ + new is.GreaterThan(7), + new is.LessThan(20) + ]); + assert.deepEqual(set.difference(b, a), b, 'outside'); + } + }, + LessThanEqual_Or: { + union: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.Or([ + new is.GreaterThan(20), + new is.LessThan(7) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThan(20), + new is.LessThanEqual(10) + ])); + a = new is.LessThanEqual(21); + assert.deepEqual(set.union(a, b), set.UNIVERSAL); + a = new is.LessThanEqual(6); + assert.deepEqual(set.union(a, b), b); + a = new is.LessThanEqual(7); + b = new is.Or([ + new is.LessThan(0), + new is.In([null]) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([null]), + a + ]), 'union with a null'); + }, + intersection: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.Or([ + new is.LessThanEqual(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.LessThanEqual(7)); + a = new is.LessThanEqual(33); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.LessThanEqual(7), + new is.And([ + new is.GreaterThan(20), + a + ]) + ])); + a = new is.LessThanEqual(6); + assert.deepEqual(set.intersection(a, b), a); + }, + difference: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + a + ]), 'inside'); + a = new is.LessThanEqual(33); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(7), + new is.LessThanEqual(20) + ]), 'left'); + a = new is.LessThanEqual(6); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'right'); + } + }, + Or_LessThanEqual: { + difference: function (assert) { + var a = new is.LessThanEqual(10); + var b = new is.Or([ + new is.LessThan(7), + new is.GreaterThan(20) + ]); + assert.deepEqual(set.difference(b, a), new is.GreaterThan(20), 'inside'); + a = new is.LessThanEqual(33); + assert.deepEqual(set.difference(b, a), new is.GreaterThan(33), 'left'); + a = new is.LessThanEqual(6); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.GreaterThan(20), + new is.And([ + new is.LessThan(7), + new is.GreaterThan(6) + ]) + ]), 'right'); + } + }, + And_And: { + union: function (assert) { + var a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(10) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.union(a, b), new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]), 'able to combine sibling ands'); + a = new is.And([ + new is.LessThan(10), + new is.GreaterThan(5) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.union(a, b), new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]), 'able to combine sibling ands'); + a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]); + assert.deepEqual(set.union(a, b), new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]), 'able to combine inner and outer'); + a = new is.And([ + new is.GreaterThan(6), + new is.LessThan(10) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(5) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + a, + b + ]), 'disjoint'); + }, + intersection: function (assert) { + var a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(10) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]), 'able to combine sibling ands'); + a = new is.And([ + new is.LessThan(10), + new is.GreaterThan(5) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]), 'able to combine sibling ands'); + a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]), 'able to combine inner and outer'); + a = new is.And([ + new is.GreaterThan(6), + new is.LessThan(10) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(5) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'disjoint'); + }, + difference: function (assert) { + var a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(10) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(6), + new is.LessThan(10) + ]), 'diff right overlaps with left'); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), 'diff left overlaps with right'); + a = new is.And([ + new is.LessThan(10), + new is.GreaterThan(5) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(6), + new is.LessThan(10) + ]), 'diff right overlaps with left (out of order)'); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), 'diff left overlaps with right (out of order)'); + a = new is.And([ + new is.GreaterThan(5), + new is.LessThan(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(10) + ]); + assert.deepEqual(set.difference(a, b), set.EMPTY, 'able to inner \\ outer'); + assert.deepEqual(set.difference(b, a), new is.Or([ + new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), + new is.And([ + new is.GreaterThanEqual(6), + new is.LessThan(10) + ]) + ]), 'able to outer \\ inner'); + a = new is.And([ + new is.GreaterThan(6), + new is.LessThan(10) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(5) + ]); + assert.deepEqual(set.difference(a, b), a, 'disjoint'); + assert.deepEqual(set.difference(b, a), b, 'disjoint'); + } + }, + And_isMember: function (assert) { + assert.ok(new is.And([ + new is.LessThan(5), + new is.GreaterThan(0) + ]).isMember(4)); + }, + UNIVERSAL_And: { + difference: function (assert) { + var a = new is.And([ + new is.GreaterThan(6), + new is.LessThan(10) + ]); + assert.deepEqual(set.difference(set.UNIVERSAL, a), new is.Or([ + new is.GreaterThanEqual(10), + new is.LessThanEqual(6) + ]), 'range and'); + } + }, + And_Or: { + union: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + var b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'outer and inner'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThan(6), + new is.GreaterThan(0) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'outer and inner arg swap'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThan(7), + new is.GreaterThan(-1) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'imperfect outer and inner arg swap'); + a = new is.Or([ + new is.In([7]), + new is.LessThanEqual(0) + ]); + b = new is.And([ + new is.NotIn([7]), + new is.GreaterThan(0) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'ins and notin'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(3) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThan(3) + ]), 'not a total overlap'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(1), + new is.LessThan(5) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + b, + a + ]), 'disjoint'); + a = new is.Or([ + new is.LessThan(0), + new is.GreaterThan(20) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(20) + ]); + var result = set.union(a, b); + assert.deepEqual(result, new is.NotIn([0]), 'NotIn'); + }, + intersection: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + var b = new is.And([ + new is.GreaterThan(1), + new is.LessThan(5) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'outer and inner disjoint'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(0), + new is.LessThanEqual(6) + ]); + assert.deepEqual(set.intersection(a, b), new is.In([ + 0, + 6 + ]), 'outer and inner overlap on values'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(10) + ]); + assert.deepEqual(set.intersection(a, b), b, 'and is entirely within part of or'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(4), + new is.LessThanEqual(10) + ]); + assert.deepEqual(set.intersection(a, b), new is.And([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(10) + ]), 'and is entirely within part of or'); + a = new is.Or([ + new is.LessThanEqual(2), + new is.GreaterThanEqual(8) + ]); + b = new is.And([ + new is.GreaterThanEqual(0), + new is.LessThanEqual(10) + ]); + var res = set.intersection(a, b); + assert.deepEqual(res, new is.Or([ + new is.And([ + new is.GreaterThanEqual(0), + new is.LessThanEqual(2) + ]), + new is.And([ + new is.GreaterThanEqual(8), + new is.LessThanEqual(10) + ]) + ]), 'and is entirely within part of or'); + }, + difference: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + assert.deepEqual(set.difference(b, a), b, 'outer and inner'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThan(7), + new is.GreaterThan(-1) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]), 'imperfect outer and inner arg swap'); + a = new is.Or([ + new is.In([7]), + new is.LessThanEqual(0) + ]); + b = new is.And([ + new is.NotIn([7]), + new is.GreaterThan(0) + ]); + assert.deepEqual(set.difference(b, a), b, 'ins and notin'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(3) + ]); + assert.deepEqual(set.difference(b, a), b, 'not a total overlap'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(1), + new is.LessThan(5) + ]); + assert.deepEqual(set.difference(b, a), b, 'disjoint'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(4), + new is.LessThanEqual(10) + ]); + assert.deepEqual(set.difference(b, a), new is.And([ + new is.GreaterThanEqual(4), + new is.LessThan(6) + ]), 'and is entirely within part of or'); + } + }, + Or_And: { + difference: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]), b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(6) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(0) + ]), 'outer and inner'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThan(7), + new is.GreaterThan(-1) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThanEqual(7), + new is.LessThanEqual(-1) + ]), 'imperfect outer and inner arg swap'); + a = new is.Or([ + new is.In([7]), + new is.LessThanEqual(0) + ]); + b = new is.And([ + new is.NotIn([7]), + new is.GreaterThan(0) + ]); + assert.deepEqual(set.difference(a, b), a, 'ins and notin'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(0), + new is.LessThan(3) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(0) + ]), 'not a total overlap'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThan(1), + new is.LessThan(5) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(0) + ]), 'disjoint'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.GreaterThanEqual(4), + new is.LessThanEqual(10) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThan(10), + new is.LessThanEqual(0) + ]), 'and is entirely within part of or'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(6) + ]); + b = new is.And([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(4) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThan(10), + new is.LessThanEqual(0) + ]), 'and is entirely within part of or reverse and'); + a = new is.Or([ + new is.GreaterThanEqual(6), + new is.LessThanEqual(0) + ]); + b = new is.And([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(4) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.GreaterThan(10), + new is.LessThanEqual(0) + ]), 'and is entirely within part of or reversed or'); + } + }, + Or_Or: { + union: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + var b = new is.Or([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.union(a, b), set.UNIVERSAL, 'separate holes'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(10), + new is.LessThanEqual(5) + ]), 'overlapping holes'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(10), + new is.LessThanEqual(5) + ]), 'overlapping holes with a single value'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.In([ + 0, + 5 + ]), + new is.GreaterThanEqual(10) + ]), 'overlapping holes with two values'); + a = new is.Or([ + new is.In([0]), + new is.LessThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.GreaterThanEqual(15), + new is.LessThanEqual(10) + ]), 'other directional holes'); + }, + intersection: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + var b = new is.Or([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.GreaterThanEqual(20), + new is.Or([ + new is.In([10]), + new is.LessThanEqual(0) + ]) + ]), 'separate holes'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.GreaterThanEqual(15), + new is.LessThanEqual(0) + ]), 'overlapping holes'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(15) + ]), 'overlapping holes with a single value'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), new is.GreaterThanEqual(15), 'overlapping holes with two values'); + a = new is.Or([ + new is.In([0]), + new is.LessThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), new is.In([5]), 'other directional holes'); + a = new is.Or([ + new is.In([0]), + new is.LessThanEqual(-1) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.intersection(a, b), set.EMPTY, 'other directional holes'); + a = new is.Or([ + new is.GreaterThanEqual(15), + new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.And([ + new is.GreaterThanEqual(15), + new is.LessThan(20) + ]) + ]); + assert.deepEqual(set.intersection(a, b), new is.Or([ + new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), + new is.And([ + new is.GreaterThanEqual(15), + new is.LessThan(20) + ]) + ]), 'or with ands'); + }, + difference: function (assert) { + var a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + var b = new is.Or([ + new is.LessThanEqual(10), + new is.GreaterThanEqual(20) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThan(10), + new is.LessThan(20) + ]), 'separate holes'); + a = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(15) + ]), 'overlapping holes'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.difference(a, b), new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(15) + ]), 'overlapping holes with a single value'); + a = new is.Or([ + new is.In([0]), + new is.GreaterThanEqual(10) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.difference(a, b), new is.Or([ + new is.In([0]), + new is.And([ + new is.GreaterThanEqual(10), + new is.LessThan(15) + ]) + ]), 'overlapping holes with two values'); + a = new is.Or([ + new is.In([0]), + new is.LessThanEqual(-1) + ]); + b = new is.Or([ + new is.In([5]), + new is.GreaterThanEqual(15) + ]); + assert.deepEqual(set.difference(a, b), a, 'other directional holes'); + a = new is.Or([ + new is.LessThanEqual(5), + new is.GreaterThanEqual(15) + ]); + b = new is.Or([ + new is.LessThanEqual(0), + new is.GreaterThanEqual(20) + ]); + var res = set.difference(a, b); + assert.deepEqual(res, new is.Or([ + new is.And([ + new is.GreaterThan(0), + new is.LessThanEqual(5) + ]), + new is.And([ + new is.GreaterThanEqual(15), + new is.LessThan(20) + ]) + ]), 'overlapping holes'); + } + }, + Or_isMember: function (assert) { + assert.notOk(new is.Or([ + new is.LessThan(0), + new is.GreaterThan(10) + ]).isMember(4)); + }, + UNIVERSAL_Or: { + difference: function (assert) { + var or = new is.Or([ + new is.LessThan(0), + new is.GreaterThan(10) + ]); + assert.deepEqual(set.difference(set.UNIVERSAL, or), new is.And([ + new is.GreaterThanEqual(0), + new is.LessThanEqual(10) + ]), 'other directional holes'); + } + }, + UNIVERSAL_All: { + difference: function (assert) { + var all = new is.All(['test']); + assert.deepEqual(set.difference(set.UNIVERSAL, all), new ValuesNot(new is.All(['test']))); + } + }, + All_UNIVERSAL: { + difference: function (assert) { + var all = new is.All(['test']); + assert.deepEqual(set.difference(all, set.UNIVERSAL), set.EMPTY); + } + }, + All_All: { + union: function (assert) { + var a = new is.All(['a']); + var b = new is.All(['b']); + assert.deepEqual(set.union(a, b), new is.Or([ + new is.All(['a']), + new is.All(['b']) + ])); + } + }, + In_All: { + union: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + }, + difference: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + } + }, + All_In: { + union: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(b, a); + }, 'unable to compare'); + }, + difference: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.difference(b, a); + }, 'unable to compare'); + } + }, + NotIn_All: { + union: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + } + }, + All_NotIn: { + union: function (assert) { + var a = new is.In(['a']); + var b = new is.All(['b']); + assert.throws(function () { + set.union(b, a); + }, 'unable to compare'); + } + }, + And_All: { + union: function (assert) { + var a = new is.And([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + }, + difference: function (assert) { + var a = new is.And([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.difference(a, b); + }, 'unable to compare'); + }, + intersection: function (assert) { + var a = new is.And([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.intersection(a, b); + }, 'unable to compare'); + } + }, + All_Or: { + union: function (assert) { + var a = new is.Or([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.union(a, b); + }, 'unable to compare'); + }, + difference: function (assert) { + var a = new is.Or([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.difference(a, b); + }, 'unable to compare'); + }, + intersection: function (assert) { + var a = new is.Or([{ a: 'b' }]); + var b = new is.All(['b']); + assert.throws(function () { + set.intersection(a, b); + }, 'unable to compare'); + } + } + }; + var makeTests = function (test, name1, name2, reversed, noDash) { + var dash = noDash ? '' : ' - - '; + if (reversed) { + if (test.difference) { + QUnit.test(dash + name1 + ' difference ' + name2, test.difference); + } else { + QUnit.skip(dash + name1 + ' difference ' + name2, function () { + }); + } + } else { + [ + 'union', + 'intersection', + 'difference' + ].forEach(function (prop) { + if (test[prop]) { + QUnit.test(dash + name1 + ' ' + prop + ' ' + name2, test[prop]); + } else { + QUnit.skip(dash + name1 + ' ' + prop + ' ' + name2, function () { + }); + } + }); + } + }; + var names = Object.keys(compare); + names.forEach(function (name1, i) { + if (!tests[name1 + '_' + name1]) { + QUnit.skip('' + name1 + '_' + name1 + '', function () { + }); + } else { + makeTests(tests[name1 + '_' + name1], name1, name1, false, true); + } + if (!tests[name1 + '_isMember']) { + QUnit.skip(' - ' + name1 + '_isMember', function () { + }); + } else { + QUnit.test(' - ' + name1 + '_isMember', tests[name1 + '_isMember']); + } + if (!tests['UNIVERSAL_' + name1]) { + QUnit.skip(' - UNIVERSAL_' + name1 + '', function () { + }); + } else { + makeTests(tests['UNIVERSAL_' + name1], 'UNIVERSAL', name1, true); + } + for (var j = i + 1; j < names.length; j++) { + var name2 = names[j]; + if (!tests[name1 + '_' + name2]) { + QUnit.skip(' - ' + name1 + '_' + name2 + '', function () { + }); + } else { + makeTests(tests[name1 + '_' + name2], name1, name2); + } + if (!tests[name2 + '_' + name1]) { + QUnit.skip(' - ' + name2 + '_' + name1 + '', function () { + }); + } else { + makeTests(tests[name2 + '_' + name1], name2, name1, true); + } + } + }); + QUnit.test('Able to do membership, union, difference with GreaterThan', function (assert) { + var DateStrSet = function (value) { + this.value = value; + }; + DateStrSet.prototype.valueOf = function () { + return new Date(this.value).getTime(); + }; + var date1980 = new Date(1980, 0, 1); + var greaterThan1980 = new compare.GreaterThan(new DateStrSet(date1980.toString())); + assert.ok(greaterThan1980.isMember(new Date(1982, 9, 20).toString()), 'is member'); + var greaterThan1990 = new compare.GreaterThan(new DateStrSet(new Date(1990, 0, 1).toString())); + var union = set.union(greaterThan1980, greaterThan1990); + assert.deepEqual(union, new compare.GreaterThan(new DateStrSet(date1980.toString())), 'union'); + var difference = set.difference(greaterThan1980, greaterThan1990); + var gt1980 = new compare.GreaterThan(new DateStrSet(date1980.toString())), lte1990 = new compare.LessThanEqual(new DateStrSet(new Date(1990, 0, 1).toString())); + assert.deepEqual(difference, new is.And([ + gt1980, + lte1990 + ]), 'difference'); + }); + QUnit.test('Able to do membership, union, difference with $in', function (assert) { + var DateStrSet = function (value) { + this.value = value; + }; + DateStrSet.prototype.valueOf = function () { + return new Date(this.value).getTime(); + }; + var date1980 = new Date(1980, 0, 1).toString(), date1990 = new Date(1990, 0, 1).toString(), date2000 = new Date(2000, 0, 1).toString(); + var in80or90 = new compare.In([ + new DateStrSet(date1980), + new DateStrSet(date1990) + ]); + assert.ok(in80or90.isMember(date1980), 'is member'); + var in90or00 = new compare.In([ + new DateStrSet(date1990), + new DateStrSet(date2000) + ]); + var union = set.union(in80or90, in90or00); + assert.deepEqual(union, new compare.In([ + new DateStrSet(date1980), + new DateStrSet(date1990), + new DateStrSet(date2000) + ]), 'union'); + }); + QUnit.test('All on arrays', function (assert) { + var arrayHasAbc = new is.All(['abc']); + assert.equal(arrayHasAbc.isMember(['abc']), true); + assert.equal(arrayHasAbc.isMember([ + 'abc', + 'def' + ]), true); + assert.equal(arrayHasAbc.isMember(['def']), false); + assert.equal(arrayHasAbc.isMember([]), false); + var hasAbcAndDef = new is.And([ + new is.All(['abc']), + new is.All(['def']) + ]); + assert.equal(hasAbcAndDef.isMember(['abc']), false); + assert.equal(hasAbcAndDef.isMember([ + 'abc', + 'def' + ]), true); + assert.equal(hasAbcAndDef.isMember(['def']), false); + assert.equal(hasAbcAndDef.isMember([]), false); + var hasAbcAndNotDef = new is.And([ + new is.All(['abc']), + new ValuesNot(new is.All(['def'])) + ]); + assert.equal(hasAbcAndNotDef.isMember(['abc']), true); + assert.equal(hasAbcAndNotDef.isMember([ + 'abc', + 'def' + ]), false); + assert.equal(hasAbcAndNotDef.isMember(['def']), false); + assert.equal(hasAbcAndNotDef.isMember([]), false); + }); +}); +/*can-query-logic@1.2.2#src/types/and-or-not-test*/ +define('can-query-logic@1.2.2#src/types/and-or-not-test', [ + 'require', + 'exports', + 'module', + './and-or-not', + 'steal-qunit', + '../set', + '../types/make-enum', + './comparisons' +], function (require, exports, module) { + var types = require('./and-or-not'); + var QUnit = require('steal-qunit'); + var set = require('../set'); + var makeEnum = require('../types/make-enum'); + var is = require('./comparisons'); + QUnit.module('can-query-logic/and-or'); + QUnit.test('AND intersection basics', function (assert) { + var AndObject = types.KeysAnd; + var isJustin = new AndObject({ name: 'Justin' }); + var is35 = new AndObject({ age: 35 }); + var is35AndJustin = set.intersection(is35, isJustin); + assert.deepEqual(is35AndJustin.values, { + name: 'Justin', + age: 35 + }, '35 and justin'); + var isJustinAnd35 = set.intersection(isJustin, is35); + assert.deepEqual(isJustinAnd35.values, { + name: 'Justin', + age: 35 + }, 'justin and 34'); + var is34 = new AndObject({ age: 34 }); + is35 = new AndObject({ age: 35 }); + var is34and35 = set.intersection(is35, is34); + assert.equal(is34and35, set.EMPTY, 'can\'t be 34 and 35'); + }); + QUnit.test('AND union basics', function (assert) { + var AndObject = types.KeysAnd; + var isJustin = new AndObject({ name: 'Justin' }); + var is35 = new AndObject({ age: 35 }); + var is35OrJustin = set.union(is35, isJustin); + assert.deepEqual(is35OrJustin, new types.ValuesOr([ + is35, + isJustin + ]), '35 and justin'); + }); + QUnit.test('AND / OR / NOT union', function (assert) { + var isJustin = new types.KeysAnd({ name: 'Justin' }), isNotJustin = new types.KeysAnd({ name: new types.ValuesNot('Justin') }); + assert.equal(set.union(isJustin, isNotJustin), set.UNIVERSAL, '{name: \'j\'} U {name: NOT(\'j\')}'); + var everything = new types.KeysAnd({}); + assert.equal(set.union(isJustin, everything), set.UNIVERSAL, '{name: \'j\'} U {}'); + var isJustinAnd21 = new types.KeysAnd({ + name: 'Justin', + age: 22 + }); + assert.equal(set.union(isJustin, isJustinAnd21), isJustin, 'super and subset'); + assert.equal(set.union(isJustinAnd21, isJustinAnd21), isJustinAnd21, 'union with itself'); + }); + QUnit.test('AND / OR / NOT difference', function (assert) { + var is35 = new types.KeysAnd({ age: 35 }), isJustin = new types.KeysAnd({ name: 'Justin' }), isJustinAnd35 = new types.KeysAnd({ + name: 'Justin', + age: 35 + }), isJustinAndNot35 = new types.KeysAnd({ + name: 'Justin', + age: new types.ValuesNot(35) + }), result; + result = set.difference(isJustin, is35); + assert.deepEqual(result, isJustinAndNot35, 'OVERLAP: {name: "Justin"} \\ {age: 35} -> {name: "justin", age: NOT(35)}'); + assert.deepEqual(set.difference(is35, is35), set.EMPTY, 'SAME SET: {age: 35} \\ {age: 35} -> EMPTY'); + assert.deepEqual(set.difference(isJustinAnd35, is35), set.EMPTY, 'SUPERSET: {age: 35, name: "Justin"} \\ {age: 35} -> EMPTY'); + assert.deepEqual(set.difference(isJustin, isJustinAnd35), isJustinAndNot35, '{name: "Justin"} \\ {age: 35, name: "Justin"} -> {name: "justin", age: NOT(35)}'); + result = set.difference(is35, new types.KeysAnd({ age: 32 })); + assert.deepEqual(result, new types.KeysAnd({ age: 35 }), 'DISJOINT: {age: 35} \\ {age: 32} -> {age: 35}'); + result = set.difference(new types.KeysAnd({ + age: 34, + name: 'Justin' + }), is35); + assert.deepEqual(result, new types.KeysAnd({ + age: 34, + name: 'Justin' + }), 'DISJOINT: {age: 34, name: "Justin"} \\ {age: 35} -> {age: 34, name: "Justin"}'); + result = set.difference(new types.KeysAnd({ foo: 'bar' }), isJustinAnd35); + assert.deepEqual(result, set.UNDEFINABLE, 'DISJOINT: {foo: "bar"} \\ {name: "Justin", age: 35} -> UNDEFINABLE'); + result = set.difference(set.UNIVERSAL, isJustinAnd35); + var compare = new types.ValuesOr([ + new types.KeysAnd({ name: new types.ValuesNot('Justin') }), + new types.KeysAnd({ age: new types.ValuesNot(35) }) + ]); + assert.deepEqual(result, compare, 'UNIVESAL: {} \\ {name: "Justin", age: 35} -> OR[ AND(name: NOT("Justin")), AND(age: NOT(35)) ]'); + result = set.difference(new types.KeysAnd({ foo: 2 }), new types.KeysAnd({ + foo: 2, + bar: set.UNIVERSAL + })); + assert.deepEqual(result, set.EMPTY, 'UNIVESAL: {foo:2} {foo:2, bar: IS_UNIVERSAL} -> set.EMPTY'); + }); + QUnit.test('AND / OR / NOT isSubset', function (assert) { + var res; + res = set.isSubset(new types.KeysAnd({ type: 'FOLDER' }), new types.KeysAnd({ type: 'FOLDER' })); + assert.ok(res, 'equal sets'); + res = set.isSubset(new types.KeysAnd({ + type: 'FOLDER', + parentId: 5 + }), new types.KeysAnd({ type: 'FOLDER' })); + assert.ok(res, 'sub set'); + res = set.isSubset(new types.KeysAnd({ type: 'FOLDER' }), new types.KeysAnd({ + type: 'FOLDER', + parentId: 5 + })); + assert.notOk(res, 'wrong way'); + res = set.isSubset(new types.KeysAnd({ + type: 'FOLDER', + parentId: 7 + }), new types.KeysAnd({ + type: 'FOLDER', + parentId: 5 + })); + assert.ok(!res, 'different values'); + }); + QUnit.test('union AND with ENUM', function (assert) { + function Color() { + } + var ColorSet = makeEnum(Color, [ + 'red', + 'green', + 'blue' + ]); + var qA = new types.KeysAnd({ + type: 'FOLDER', + status: new ColorSet('red') + }), qB = new types.KeysAnd({ + type: 'FOLDER', + status: new ColorSet('green') + }); + var res = set.union(qA, qB); + assert.deepEqual(res, new types.KeysAnd({ + type: 'FOLDER', + status: new ColorSet([ + 'red', + 'green' + ]) + }), 'able to do a union'); + }); + QUnit.test('AND isMember', function (assert) { + var folderAnd35 = new types.KeysAnd({ + type: 'FOLDER', + age: 35 + }); + assert.ok(folderAnd35.isMember({ + type: 'FOLDER', + age: 35 + })); + assert.ok(folderAnd35.isMember({ + type: 'FOLDER', + age: 35, + extra: 'value' + })); + assert.notOk(folderAnd35.isMember({ + type: 'FOLDER', + age: 36 + })); + assert.notOk(folderAnd35.isMember({ + type: 'folder', + age: 35 + })); + assert.notOk(folderAnd35.isMember({ type: 'FOLDER' })); + assert.notOk(folderAnd35.isMember({ age: 35 })); + var isJustinPostCollege = new types.KeysAnd({ + name: { first: 'Justin' }, + age: 33 + }); + assert.ok(isJustinPostCollege.isMember({ + name: { + first: 'Justin', + last: 'Meyer' + }, + age: 33 + }), 'is member'); + }); + QUnit.test('OR isMember', function (assert) { + var isFolder = new types.KeysAnd({ type: 'FOLDER' }), is35 = new types.KeysAnd({ age: 35 }), isFolderOr35 = new types.ValuesOr([ + isFolder, + is35 + ]); + assert.ok(isFolderOr35.isMember({ + type: 'FOLDER', + age: 35 + }), 'both'); + assert.notOk(isFolderOr35.isMember({}), 'empty'); + assert.ok(isFolderOr35.isMember({ + type: 'FOLDER', + age: 36 + })); + assert.ok(isFolderOr35.isMember({ + type: 'folder', + age: 35 + })); + assert.notOk(isFolderOr35.isMember({ + type: 'folder', + age: 36 + })); + assert.ok(isFolderOr35.isMember({ type: 'FOLDER' })); + assert.ok(isFolderOr35.isMember({ age: 35 })); + }); + QUnit.test('And nested objects', function (assert) { + var res; + var isNameFirstJustin = new types.KeysAnd({ name: { first: 'Justin' } }); + var isNameFirstJustin2 = new types.KeysAnd({ name: { first: 'Justin' } }); + res = set.isEqual(isNameFirstJustin, isNameFirstJustin2); + assert.equal(res, true); + }); + QUnit.module('can-query-logic/not'); + QUnit.test('union basics', function (assert) { + assert.equal(set.union(new types.ValuesNot(1), 1), set.UNIVERSAL, 'is univesal set'); + }); + QUnit.test('difference with universal', function (assert) { + assert.equal(set.difference(new types.ValuesNot(1), set.UNIVERSAL), set.EMPTY, 'not 1 \\ univesal = 1'); + assert.deepEqual(set.difference(set.UNIVERSAL, 1), new types.ValuesNot(1), '1 \\ univesal = not 1'); + }); + QUnit.test('And with nested.properties', function (assert) { + assert.equal(set.isSubset(new types.KeysAnd({ + 'name.first': 'Justin', + 'name.last': 'Meyer' + }), new types.KeysAnd({ 'name.last': 'Meyer' })), true, 'dot.ed properties work with subset'); + assert.equal(new types.KeysAnd({ + 'name.first': 'Justin', + 'name.last': 'Meyer' + }).isMember({ + name: { + first: 'Justin', + last: 'Meyer' + } + }), true, 'dot.ed properties isMember match'); + assert.equal(new types.KeysAnd({ + 'name.first': 'Justin', + 'name.last': 'Meyer' + }).isMember({ + name: { + first: 'Ramiya', + last: 'Meyer' + } + }), false, 'dot.ed properties isMember dont match'); + }); + QUnit.test('And with nested ands', function (assert) { + assert.equal(set.isSubset(new types.KeysAnd({ + name: new types.KeysAnd({ + first: 'Justin', + last: 'Meyer' + }) + }), new types.KeysAnd({ name: new types.KeysAnd({ last: 'Meyer' }) })), true, 'properties work with subset'); + assert.deepEqual(set.intersection(new types.KeysAnd({ name: new types.KeysAnd({ first: 'Justin' }) }), new types.KeysAnd({ name: new types.KeysAnd({ last: 'Meyer' }) })), new types.KeysAnd({ + name: new types.KeysAnd({ + first: 'Justin', + last: 'Meyer' + }) + }), 'properties work with intersection'); + assert.equal(new types.KeysAnd({ + name: new types.KeysAnd({ + first: 'Justin', + last: 'Meyer' + }) + }).isMember({ + name: { + first: 'Justin', + last: 'Meyer' + } + }), true, 'dot.ed properties isMember match'); + assert.equal(new types.KeysAnd({ + name: new types.KeysAnd({ + first: 'Justin', + last: 'Meyer' + }) + }).isMember({ + name: { + first: 'Ramiya', + last: 'Meyer' + } + }), false, 'dot.ed properties isMember dont match'); + }); + QUnit.test('union with comparisons', function (assert) { + var isGtJustinAndGt35 = new types.KeysAnd({ + name: new is.GreaterThan('Justin'), + age: new is.GreaterThan(35) + }); + var isGt25 = new types.KeysAnd({ age: new is.GreaterThan(25) }); + var result = set.union(isGtJustinAndGt35, isGt25); + assert.deepEqual(result, isGt25); + var a = new types.KeysAnd({ + name: new is.GreaterThan('Justin'), + age: new is.GreaterThan(35), + count: new is.GreaterThan(10) + }); + var b = new types.KeysAnd({ + age: new is.GreaterThan(25), + count: new is.GreaterThan(9) + }); + result = set.union(b, a); + assert.deepEqual(result, b); + }); +}); +/*can-query-logic@1.2.2#src/types/values-or-test*/ +define('can-query-logic@1.2.2#src/types/values-or-test', [ + 'module', + '@loader', + 'require' +], function (module, loader, require) { + loader.get('@@global-helpers').prepareGlobal({ + require: require, + name: module.id, + deps: [] + }); + var define = loader.global.define; + var require = loader.global.require; + var source = ''; + loader.global.define = undefined; + loader.global.module = undefined; + loader.global.exports = undefined; + loader.__exec({ + 'source': source, + 'address': module.uri + }); + loader.global.require = require; + loader.global.define = define; + return loader.get('@@global-helpers').retrieveGlobal(module.id, undefined); +}); +/*can-query-logic@1.2.2#src/types/basic-query-test*/ +define('can-query-logic@1.2.2#src/types/basic-query-test', [ + 'require', + 'exports', + 'module', + './basic-query', + 'steal-qunit', + './keys-and', + './values-and' +], function (require, exports, module) { + var BasicQuery = require('./basic-query'); + var QUnit = require('steal-qunit'); + var KeysAnd = require('./keys-and'); + var ValuesAnd = require('./values-and'); + QUnit.module('can-query-logic/types/basic-query filterMembersAndGetCount'); + QUnit.test('Able to filter on a universal set', function (assert) { + var parent = new BasicQuery({ filter: new KeysAnd({}) }); + var bData = [ + {}, + {} + ]; + var FooType = function (value) { + this.value = value; + }; + FooType.prototype.isMember = function () { + return true; + }; + var root = new BasicQuery({ filter: new ValuesAnd([new FooType()]) }); + var res = root.filterMembersAndGetCount(bData, parent); + assert.equal(res.count, 2, 'got all members'); + }); + QUnit.test('Page is a universal set', function (assert) { + var parent = new BasicQuery({ filter: new KeysAnd({}) }); + var bData = [ + {}, + {} + ]; + var FooType = function (value) { + this.value = value; + }; + FooType.prototype.isMember = function () { + return true; + }; + var root = new BasicQuery({ + filter: new ValuesAnd([new FooType()]), + page: new BasicQuery.RecordRange(1, 2) + }); + var res = root.filterMembersAndGetCount(bData, parent); + assert.equal(res.count, 2, 'got all members'); + }); +}); +/*can-query-logic@1.2.2#src/types/basic-query-sorting-test*/ +define('can-query-logic@1.2.2#src/types/basic-query-sorting-test', [ + 'require', + 'exports', + 'module', + './basic-query', + 'steal-qunit', + '../set', + 'can-assign', + 'can-reflect' +], function (require, exports, module) { + var BasicQuery = require('./basic-query'); + var QUnit = require('steal-qunit'); + var set = require('../set'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + QUnit.module('can-query-logic/types/basic-query sorting'); + function legacyToQuery(set) { + var copy = assign({}, set); + var page = new BasicQuery.RecordRange(copy.start || 0, copy.end || Infinity); + delete copy.start; + delete copy.end; + return new BasicQuery({ + page: page, + filter: Object.keys(copy).length ? new BasicQuery.KeysAnd(copy) : set.UNIVERSAL + }); + } + function queryToLegacy(query) { + var legacy = {}; + if (query.page) { + if (set.isEqual(query.page, set.UNIVERSAL)) { + } else { + legacy.start = query.page.start; + legacy.end = query.page.end; + } + } + return legacy; + } + function legacyIsEqual(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return set.isEqual(qA, qB); + } + function legacyDifference(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return queryToLegacy(set.difference(qA, qB)); + } + function legacyIntersection(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return queryToLegacy(set.intersection(qA, qB)); + } + function legacyUnion(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return queryToLegacy(set.union(qA, qB)); + } + function legacySubset(setA, setB) { + var qA = legacyToQuery(setA), qB = legacyToQuery(setB); + return set.isSubset(qA, qB); + } + QUnit.test('rangeInclusive legacyDifference', function (assert) { + var res = legacyDifference({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }); + assert.deepEqual(res, { + start: 0, + end: 49 + }, 'got a diff'); + res = legacyDifference({}, { + start: 0, + end: 10 + }); + assert.deepEqual(res, { + start: 11, + end: Infinity + }, 'universal set'); + res = legacyDifference({ + start: 0, + end: 49 + }, { + start: 50, + end: 101 + }); + assert.deepEqual(res, { + start: 0, + end: 49 + }, 'side by side'); + res = legacyDifference({ + start: 0, + end: 49 + }, { + start: 0, + end: 20 + }); + assert.deepEqual(res, { + start: 21, + end: 49 + }, 'first set extends past second'); + res = legacyDifference({ + start: 0, + end: 49 + }, { + start: 20, + end: 49 + }); + assert.deepEqual(res, { + start: 0, + end: 19 + }, 'first set starts before second'); + }); + QUnit.test('rangeInclusive legacyIntersection', function (assert) { + var res = legacyIntersection({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }); + assert.deepEqual(res, { + start: 50, + end: 99 + }, 'got a intersection'); + }); + QUnit.test('rangeInclusive legacyIsEqual', function (assert) { + assert.ok(!legacyIsEqual({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }), 'they are not equal'); + assert.ok(!legacyIsEqual({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }), 'they are not equal'); + }); + QUnit.test('rangeInclusive legacySubset', function (assert) { + assert.ok(legacySubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 100 + }), 'self is a subset'); + assert.ok(legacySubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }), 'end extends past subset'); + assert.equal(legacySubset({ + start: 0, + end: 101 + }, { + start: 0, + end: 100 + }), false, 'non-subset extends past end'); + assert.ok(legacySubset({ + start: 1, + end: 100 + }, { + start: 0, + end: 100 + }), 'start extends before subset'); + assert.ok(!legacySubset({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }), 'non-subset extends before start'); + }); + QUnit.test('rangeInclusive legacyUnion', function (assert) { + var res = legacyUnion({}, { + start: 0, + end: 10 + }); + assert.deepEqual(res, {}, 'universal set'); + res = legacyUnion({ + start: 100, + end: 199 + }, { + start: 200, + end: 299 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection'); + res = legacyUnion({ + start: 200, + end: 299 + }, { + start: 100, + end: 199 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection with either argument order'); + res = legacyUnion({ + start: 200, + end: 299 + }, { + start: 100, + end: 209 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect'); + res = legacyUnion({ + start: 100, + end: 209 + }, { + start: 200, + end: 299 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect with either argument order'); + res = legacyUnion({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'first set contains second'); + res = legacyUnion({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'second set contains first'); + res = legacyUnion({ + start: 100, + end: 299 + }, { + start: 100, + end: 299 + }); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'union of identical sets is the same as those sets'); + }); + QUnit.test('rangeInclusive set.count', function (assert) { + var query = new BasicQuery({ + page: new BasicQuery.RecordRange(0, 99), + filter: set.UNIVERSAL + }); + var res = query.count({ + start: 0, + end: 99 + }); + assert.equal(res, 100, 'count is right'); + }); + QUnit.test('index uses can-reflect', function (assert) { + var query = new BasicQuery({ sort: 'name' }); + var obj1Read, obj2Read, itemKeyRead, itemOwnKeyRead; + var obj1 = canReflect.assignSymbols({}, { + 'can.getKeyValue': function (key) { + obj1Read = true; + return { + id: 5, + name: 'x' + }[key]; + } + }), obj2 = canReflect.assignSymbols({}, { + 'can.getKeyValue': function (key) { + obj2Read = true; + return { + id: 7, + name: 'd' + }[key]; + } + }), item = canReflect.assignSymbols({}, { + 'can.getKeyValue': function (key) { + itemKeyRead = true; + return { + id: 1, + name: 'j' + }[key]; + }, + 'can.hasOwnKey': function (key) { + itemOwnKeyRead = true; + return key in { + id: 1, + name: 'j' + }; + } + }); + var res = query.index(item, [ + obj2, + obj1 + ]); + assert.equal(res, 1, 'inserted at 1'); + assert.deepEqual([ + obj1Read, + obj2Read, + itemKeyRead, + itemOwnKeyRead + ], [ + true, + true, + true, + true + ], 'read everything'); + }); + QUnit.test('.index should work with literal objects', function (assert) { + var query = new BasicQuery({ sort: 'name' }); + var items = [ + { + id: 1, + name: 'Item 0' + }, + { + id: 2, + name: 'Item 1' + } + ]; + var res = query.index({ + id: 1, + name: 'Item 1' + }, items); + assert.equal(res, 1, 'Item index at 1'); + }); +}); +/*can-query-logic@1.2.2#src/types/basic-query-filter-from-test*/ +define('can-query-logic@1.2.2#src/types/basic-query-filter-from-test', [ + 'require', + 'exports', + 'module', + './basic-query', + 'steal-qunit' +], function (require, exports, module) { + var BasicQuery = require('./basic-query'); + var QUnit = require('steal-qunit'); + QUnit.module('can-query-logic/types/basic-query filterFrom'); + var getId = function (d) { + return d.id; + }; + var items = [ + { + id: 0, + note: 'C', + type: 'eh' + }, + { + id: 1, + note: 'D', + type: 'critical' + }, + { + id: 2, + note: 'E', + type: 'critical' + }, + { + id: 3, + note: 'F', + type: 'eh' + }, + { + id: 4, + note: 'G', + type: 'critical' + }, + { + id: 5, + note: 'A' + }, + { + id: 6, + note: 'B', + type: 'critical' + }, + { + id: 7, + note: 'C', + type: 'critical' + } + ]; + QUnit.test('against non ranged set', function (assert) { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(1, 3) + }); + var res = query.filterFrom(items); + assert.deepEqual(res && res.map(getId), [ + 2, + 4, + 6 + ]); + }); + QUnit.test('ordered ascending and paginated', function (assert) { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(1, 3), + sort: 'note' + }); + var res = query.filterFrom(items); + assert.deepEqual(res && res.map(getId), [ + 7, + 1, + 2 + ]); + }); + QUnit.test('ordered descending and paginated', function (assert) { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(1, 3), + sort: '-note' + }); + var res = query.filterFrom(items); + assert.deepEqual(res && res.map(getId), [ + 2, + 1, + 7 + ]); + }); + QUnit.test('against paginated set', function (assert) { + var query = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(21, 23) + }); + var fromQuery = new BasicQuery({ + filter: new BasicQuery.KeysAnd({ type: 'critical' }), + page: new BasicQuery.RecordRange(20, 27) + }); + var res = query.filterFrom(items, fromQuery); + assert.deepEqual(res && res.map(getId), [ + 2, + 4, + 6 + ]); + }); + QUnit.test('returns undefined against incompatible set', function (assert) { + var query = new BasicQuery({ filter: new BasicQuery.KeysAnd({ note: 'C' }) }); + var fromQuery = new BasicQuery({ filter: new BasicQuery.KeysAnd({ type: 'critical' }) }); + var res; + try { + res = query.filterFrom(items, fromQuery); + } catch (e) { + assert.ok(true, 'throws an error'); + } + assert.notOk(res, 'did not throw an error'); + }); +}); +/*can-query-logic@1.2.2#src/types/basic-query-merge-test*/ +define('can-query-logic@1.2.2#src/types/basic-query-merge-test', [ + 'require', + 'exports', + 'module', + './basic-query', + 'steal-qunit' +], function (require, exports, module) { + var BasicQuery = require('./basic-query'); + var QUnit = require('steal-qunit'); + QUnit.module('can-query-logic/types/basic-query merge'); + var getId = function (d) { + return d.id; + }; + var items = [ + { + id: 0, + note: 'C', + type: 'eh' + }, + { + id: 1, + note: 'D', + type: 'critical' + }, + { + id: 2, + note: 'E', + type: 'critical' + }, + { + id: 3, + note: 'F', + type: 'eh' + }, + { + id: 4, + note: 'G', + type: 'critical' + }, + { + id: 5, + note: 'A' + }, + { + id: 6, + note: 'B', + type: 'critical' + }, + { + id: 7, + note: 'C', + type: 'critical' + } + ]; + var everything = new BasicQuery({}); + QUnit.test('basics', function (assert) { + var fooBar = new BasicQuery({ filter: new BasicQuery.KeysAnd({ foo: 'bar' }) }); + var res = everything.merge(fooBar, items, items.slice(0, 3), getId); + assert.deepEqual(res, items); + }); + QUnit.test('unionMembers against ranged sets', function (assert) { + var a = new BasicQuery({ page: new BasicQuery.RecordRange(10, 13) }); + var b = new BasicQuery({ page: new BasicQuery.RecordRange(10, 13) }); + var union = a.merge(b, items.slice(0, 4), items.slice(4, 8), getId); + a = new BasicQuery({ page: new BasicQuery.RecordRange(14, 17) }); + union = a.merge(b, items.slice(4, 8), items.slice(0, 4), getId); + assert.deepEqual(union, items, 'disjoint after'); + }); + QUnit.test('unionMembers against overlapping ranged sets', function (assert) { + var a = new BasicQuery({ page: new BasicQuery.RecordRange(10, 13) }); + var b = new BasicQuery({ page: new BasicQuery.RecordRange(13, 17) }); + var union = a.merge(b, items.slice(0, 5), items.slice(3, 8), getId); + assert.deepEqual(union, items); + a = new BasicQuery({ page: new BasicQuery.RecordRange(10, 11) }); + b = new BasicQuery({ page: new BasicQuery.RecordRange(11, 17) }); + union = a.merge(b, items.slice(0, 2), items.slice(1, 8), getId); + assert.deepEqual(union, items); + a = new BasicQuery({ page: new BasicQuery.RecordRange(10, 11) }); + b = new BasicQuery({ page: new BasicQuery.RecordRange(11, 17) }); + union = b.merge(a, items.slice(1, 8), items.slice(0, 2), getId); + assert.deepEqual(union, items); + }); + QUnit.test('unionMembers filters for uniqueness', function (assert) { + var aItems = items.filter(function (a) { + return a.type === 'critical'; + }); + var bItems = items.filter(function (b) { + return b.note === 'C'; + }); + var unionItems = [bItems[0]].concat(aItems); + var a = new BasicQuery({ page: new BasicQuery.KeysAnd({ type: 'critical' }) }); + var b = new BasicQuery({ page: new BasicQuery.KeysAnd({ note: 'C' }) }); + var union = a.merge(b, aItems, bItems, getId); + assert.deepEqual(union, unionItems); + union = b.merge(a, bItems, aItems, getId); + assert.deepEqual(union, unionItems); + }); +}); +/*can-query-logic@1.2.2#src/serializers/basic-query-test*/ +define('can-query-logic@1.2.2#src/serializers/basic-query-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './basic-query', + 'can-reflect', + '../types/and-or-not', + '../types/comparisons', + '../types/make-maybe', + 'can-test-helpers', + '../types/values-and' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var makeBasicQueryConvert = require('./basic-query'); + var canReflect = require('can-reflect'); + var logicTypes = require('../types/and-or-not'); + var is = require('../types/comparisons'); + var makeMaybe = require('../types/make-maybe'); + var testHelpers = require('can-test-helpers'); + var ValuesAnd = require('../types/values-and'); + QUnit.module('can-query-logic/serializers/basic-query'); + var EmptySchema = { + kind: 'record', + identity: ['id'], + keys: {} + }; + QUnit.test('basics', function (assert) { + var query = { filter: { foo: 'bar' } }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + var returnedQuery = converter.serializer.serialize(basicQuery); + assert.deepEqual(returnedQuery, query, 'got back what we give'); + }); + QUnit.test('nested properties', function (assert) { + var query = { filter: { name: { first: 'justin' } } }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + assert.deepEqual(basicQuery.filter, new logicTypes.KeysAnd({ name: new logicTypes.KeysAnd({ first: new is.In(['justin']) }) }), 'adds nested ands'); + }); + QUnit.test('$or with the same types unify into maybe', function (assert) { + var MaybeSet = makeMaybe([null]); + var converter = makeBasicQueryConvert({ + identity: ['id'], + keys: { + age: canReflect.assignSymbols({}, { 'can.SetType': MaybeSet }), + foo: String + } + }); + var query = { + filter: { + $or: [ + { + foo: 'bar', + age: { $gt: 3 } + }, + { + foo: 'bar', + age: null + } + ] + } + }; + var basicQuery = converter.hydrate(query); + assert.deepEqual(basicQuery.filter, new logicTypes.KeysAnd({ + foo: new is.In(['bar']), + age: new MaybeSet({ + range: new is.GreaterThan(3), + enum: new is.In([null]) + }) + })); + var res = converter.serializer.serialize(basicQuery); + assert.deepEqual(res, { + filter: { + $or: [ + { + foo: 'bar', + age: { $gt: 3 } + }, + { + foo: 'bar', + age: null + } + ] + } + }, 'serialized'); + }); + QUnit.test('auto-convert or schema into maybe type', function (assert) { + var MaybeNumber = canReflect.assignSymbols({}, { + 'can.new': function (val) { + if (val == null) { + return val; + } + return +val; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Number, + undefined, + null + ] + }; + } + }); + var converter = makeBasicQueryConvert({ + identity: ['id'], + keys: { + age: MaybeNumber, + foo: String + } + }); + var query = { + filter: { + $or: [ + { + foo: 'bar', + age: { $gt: '3' } + }, + { + foo: 'bar', + age: null + } + ] + } + }; + var basicQuery = converter.hydrate(query); + var res = converter.serializer.serialize(basicQuery); + assert.deepEqual(res, { + filter: { + $or: [ + { + foo: 'bar', + age: { $gt: 3 } + }, + { + foo: 'bar', + age: null + } + ] + } + }, 'serialized'); + }); + testHelpers.dev.devOnlyTest('warn if query properties are not defined (#8)', function (assert) { + assert.expect(3); + var message = 'can-query-logic: Ignoring keys: start, end.'; + var finishErrorCheck = testHelpers.dev.willWarn(message, function (actualMessage, success) { + assert.equal(actualMessage, message, 'Warning is expected message'); + assert.ok(success); + }); + var query = { + filter: { name: { first: 'justin' } }, + start: 0, + end: 1 + }; + var converter = makeBasicQueryConvert(EmptySchema); + converter.hydrate(query); + assert.equal(finishErrorCheck(), 1); + }); + QUnit.test('gt and lt', function (assert) { + var query = { + filter: { + age: { + $gt: 0, + $lt: 100 + } + } + }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + assert.deepEqual(basicQuery.filter, new logicTypes.KeysAnd({ + age: new is.And([ + new is.GreaterThan(0), + new is.LessThan(100) + ]) + })); + var res = converter.serializer.serialize(basicQuery); + assert.deepEqual(res, { + filter: { + age: { + $gt: 0, + $lt: 100 + } + } + }); + }); + QUnit.test('basicquery with no sort', function (assert) { + var query = {}; + var converter = makeBasicQueryConvert({ + identity: ['id'], + type: 'map', + keys: { + id: function (val) { + return val; + } + } + }); + var basicQuery = converter.hydrate(query); + var objs = [ + { id: 0 }, + { id: 2 } + ]; + var item = { id: 1 }; + var res = basicQuery.index(item, objs); + assert.equal(res, 1, 'inserted at 1'); + }); + QUnit.test('Complex queries with nested $not, $all', function (assert) { + var query = { + filter: { + $and: [ + { tags: { $all: ['sbux'] } }, + { tags: { $not: { $all: ['dfw'] } } } + ] + } + }; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + assert.ok(basicQuery.filter instanceof ValuesAnd); + var res = converter.serializer.serialize(basicQuery); + assert.deepEqual(res, query); + }); + QUnit.test('Inverting $not comparisons', function (assert) { + [ + { + query: { filter: { age: { $not: { $lt: 5 } } } }, + expectedInstance: is.GreaterThanEqual, + expectedValue: 5 + }, + { + query: { filter: { age: { $not: { $lte: 5 } } } }, + expectedInstance: is.GreaterThan, + expectedValue: 5 + }, + { + query: { filter: { age: { $not: { $gt: 5 } } } }, + expectedInstance: is.LessThanEqual, + expectedValue: 5 + }, + { + query: { filter: { age: { $not: { $gte: 5 } } } }, + expectedInstance: is.LessThan, + expectedValue: 5 + }, + { + query: { + filter: { + age: { + $not: { + $in: [ + 2, + 3 + ] + } + } + } + }, + expectedInstance: is.NotIn, + expectedValue: [ + 2, + 3 + ], + valueProp: 'values' + }, + { + query: { + filter: { + age: { + $not: { + $nin: [ + 2, + 3 + ] + } + } + } + }, + expectedInstance: is.In, + expectedValue: [ + 2, + 3 + ], + valueProp: 'values' + } + ].forEach(function (options) { + var query = options.query; + var ExpectedInstance = options.expectedInstance; + var expectedValue = options.expectedValue; + var prop = options.valueProp || 'value'; + var converter = makeBasicQueryConvert(EmptySchema); + var basicQuery = converter.hydrate(query); + assert.ok(basicQuery.filter.values.age instanceof ExpectedInstance, 'changed to right instance type'); + assert.deepEqual(basicQuery.filter.values.age[prop], expectedValue, 'has the correct value'); + }); + }); +}); +/*can-query-logic@1.2.2#src/serializers/comparisons-test*/ +define('can-query-logic@1.2.2#src/serializers/comparisons-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './comparisons', + 'can-reflect', + '../types/values-not' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var comparisons = require('./comparisons'); + var canReflect = require('can-reflect'); + var ValuesNot = require('../types/values-not'); + QUnit.module('can-query-logic/serializers/comparisons'); + QUnit.test('hydrate and serialize with custom types that work with operators', function (assert) { + var Type = function (value) { + this.value = value; + }; + canReflect.assignSymbols(Type.prototype, { + 'can.serialize': function () { + return this.value; + } + }); + var hydrated = comparisons.hydrate({ + $in: [ + 1, + 2 + ] + }, function (value) { + return new Type(value); + }); + assert.deepEqual(hydrated.values, [ + new Type(1), + new Type(2) + ], 'hydrated'); + var serialized = comparisons.serializer.serialize(hydrated); + assert.deepEqual(serialized, { + $in: [ + 1, + 2 + ] + }, 'serialized'); + }); + QUnit.test('unknown hydrator is called in all cases', function (assert) { + var hydrated = []; + var addToHydrated = function (value) { + hydrated.push(value); + }; + comparisons.hydrate({ + $in: [ + 1, + 2 + ] + }, addToHydrated); + comparisons.hydrate('abc', addToHydrated); + comparisons.hydrate([ + 'x', + 'y' + ], addToHydrated); + assert.deepEqual(hydrated, [ + 1, + 2, + 'abc', + 'x', + 'y' + ], 'hydrated called with the right stuff'); + }); + QUnit.test('$not and $all can work recursively', function (assert) { + var hydrated = comparisons.hydrate({ $not: { $all: ['def'] } }, function (value) { + return value; + }); + assert.ok(hydrated instanceof ValuesNot, 'is an instance'); + }); +}); +/*can-query-logic@1.2.2#src/types/make-maybe-test*/ +define('can-query-logic@1.2.2#src/types/make-maybe-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './make-maybe', + './comparisons', + '../set', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var makeMaybe = require('./make-maybe'); + var is = require('./comparisons'); + var set = require('../set'); + var canReflect = require('can-reflect'); + QUnit.module('can-query-logic/types/make-maybe'); + function DateStringSet(value) { + this.value = value; + } + DateStringSet.prototype.valueOf = function () { + return this.value == null ? this.value : new Date(this.value).getTime(); + }; + var ComparisonSet = function (value) { + this.value = value; + }; + ComparisonSet.prototype.valueOf = function () { + return this.value; + }; + var MaybeDateStringSet = makeMaybe([ + null, + undefined + ], DateStringSet); + QUnit.test('constructor normalizes', function (assert) { + var isNull_3 = new MaybeDateStringSet({ + range: new is.In([ + null, + 3 + ]) + }); + assert.deepEqual(isNull_3.range, new is.In([3]), '3 left in range'); + assert.deepEqual(isNull_3.enum, new is.In([null]), 'range moved to in'); + var isNull_3AsDateString = new MaybeDateStringSet({ + range: new is.In([ + new DateStringSet(null), + new DateStringSet(3) + ]) + }); + assert.deepEqual(isNull_3AsDateString.range, new is.In([new DateStringSet(3)]), '3 left in range'); + assert.deepEqual(isNull_3AsDateString.enum, new is.In([new DateStringSet(null)]), 'range moved to in'); + var isNull = new MaybeDateStringSet({ range: new is.In([null]) }); + assert.deepEqual(isNull.range, set.EMPTY, 'empty if only null'); + assert.deepEqual(isNull.enum, new is.In([null]), 'range moved to in'); + var res = new MaybeDateStringSet({ + range: new is.NotIn([ + null, + 3 + ]) + }); + assert.deepEqual(res.range, new is.NotIn([3]), 'not in range'); + assert.deepEqual(res.enum, new is.In([undefined]), 'not in enum'); + res = new MaybeDateStringSet({ + range: new is.And([ + new is.NotIn([null]), + new is.GreaterThan(4) + ]) + }); + assert.deepEqual(res.range, new is.GreaterThan(4), 'And with not in'); + assert.deepEqual(res.enum, set.EMPTY, 'And with not in'); + }); + QUnit.test('difference with universal', function (assert) { + var res; + var gt3 = new MaybeDateStringSet({ range: new is.GreaterThan(3) }); + res = set.difference(set.UNIVERSAL, gt3); + assert.deepEqual(res, new MaybeDateStringSet({ + enum: new is.In([ + null, + undefined + ]), + range: new is.LessThanEqual(3) + }), 'UNIVERSAL \\ $gt:3'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ range: new is.In([null]) })); + assert.deepEqual(res, new MaybeDateStringSet({ + range: set.UNIVERSAL, + enum: new is.In([undefined]) + }), 'UNIVERSAL \\ null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ range: new is.NotIn([null]) })); + assert.deepEqual(res, new MaybeDateStringSet({ + range: set.UNIVERSAL, + enum: new is.In([null]) + }), 'UNIVERSAL \\ !null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ + enum: new is.In([ + null, + undefined + ]), + range: new is.LessThanEqual(3) + })); + assert.deepEqual(res, gt3, 'secondary and primary'); + }); + QUnit.test('difference', function (assert) { + var res; + var gt3 = new MaybeDateStringSet({ range: new is.GreaterThan(3) }); + res = set.difference(new MaybeDateStringSet({ range: new is.GreaterThan(3) }), new MaybeDateStringSet({ range: new is.GreaterThan(4) })); + assert.deepEqual(res, new MaybeDateStringSet({ range: set.difference(new is.GreaterThan(3), new is.GreaterThan(4)) }), '$gt:3 \\ $gt:4'); + res = set.difference(new MaybeDateStringSet({ range: new is.NotIn([undefined]) }), new MaybeDateStringSet({ + range: new is.LessThanEqual(3), + enum: new is.In([null]) + })); + assert.deepEqual(res, new MaybeDateStringSet({ range: new is.GreaterThan(3) }), '{ne: undef} \\ {lt: 3} | null -> {gte: 3}'); + res = set.difference(new MaybeDateStringSet({ range: new is.NotIn([undefined]) }), new MaybeDateStringSet({ range: new is.LessThanEqual(3) })); + assert.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(3), + enum: new is.In([null]) + }), '{ne: undef} \\ {lt: 3}|null -> {gte: 3} | null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ range: new is.In([null]) })); + assert.deepEqual(res, new MaybeDateStringSet({ range: new is.NotIn([null]) }), 'UNIVERSAL \\ null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ + enum: new is.In([ + null, + undefined + ]), + range: new is.LessThanEqual(3) + })); + assert.deepEqual(res, gt3, 'secondary and primary'); + res = set.difference(new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + }), new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + })); + assert.equal(res, set.EMPTY, 'equal is empty'); + }); + QUnit.test('difference with ComparisonSet', function (assert) { + var three = new ComparisonSet(3), four = new ComparisonSet(3); + var res; + var gt3 = new MaybeDateStringSet({ range: new is.GreaterThan(three) }); + res = set.difference(new MaybeDateStringSet({ range: new is.GreaterThan(three) }), new MaybeDateStringSet({ range: new is.GreaterThan(four) })); + assert.deepEqual(res, new MaybeDateStringSet({ range: set.difference(new is.GreaterThan(three), new is.GreaterThan(four)) }), '$gt:3 \\ $gt:4'); + res = set.difference(new MaybeDateStringSet({ range: new is.NotIn([undefined]) }), new MaybeDateStringSet({ + range: new is.LessThanEqual(three), + enum: new is.In([null]) + })); + assert.deepEqual(res, new MaybeDateStringSet({ range: new is.GreaterThan(three) }), '{ne: undef} \\ {lt: 3} | null -> {gte: 3}'); + res = set.difference(new MaybeDateStringSet({ range: new is.NotIn([undefined]) }), new MaybeDateStringSet({ range: new is.LessThanEqual(three) })); + assert.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(three), + enum: new is.In([null]) + }), '{ne: undef} \\ {lt: 3}|null -> {gte: 3} | null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ range: new is.In([null]) })); + assert.deepEqual(res, new MaybeDateStringSet({ range: new is.NotIn([null]) }), 'UNIVERSAL \\ null'); + res = set.difference(set.UNIVERSAL, new MaybeDateStringSet({ + enum: new is.In([ + null, + undefined + ]), + range: new is.LessThanEqual(three) + })); + assert.deepEqual(res, gt3, 'secondary and primary'); + }); + QUnit.test('intersection', function (assert) { + var res; + res = set.intersection(new MaybeDateStringSet({ + range: new is.GreaterThan(3), + enum: new is.In([null]) + }), new MaybeDateStringSet({ + range: new is.GreaterThan(5), + enum: new is.In([ + null, + undefined + ]) + })); + assert.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(5), + enum: new is.In([null]) + }), 'got the right thing'); + }); + QUnit.test('union', function (assert) { + var res; + res = set.union(new MaybeDateStringSet({ + range: new is.GreaterThan(3), + enum: new is.In([null]) + }), new MaybeDateStringSet({ + range: new is.GreaterThan(5), + enum: new is.In([undefined]) + })); + assert.deepEqual(res, new MaybeDateStringSet({ + range: new is.GreaterThan(3), + enum: new is.In([ + null, + undefined + ]) + }), 'got the right thing'); + }); + QUnit.test('isSubset', function (assert) { + var res; + res = set.isSubset(new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + }), new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + })); + assert.ok(res, 'is a subset'); + }); + QUnit.test('can make maybe type from normal type and makeMaybeSetType', function (assert) { + var MaybeNumber = canReflect.assignSymbols({}, { + 'can.new': function (val) { + if (val == null) { + return val; + } + return +val; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Number, + undefined, + null + ] + }; + } + }); + assert.ok(makeMaybe.canMakeMaybeSetType(MaybeNumber), 'got everything we need'); + var types = makeMaybe.makeMaybeSetTypes(MaybeNumber); + var notUndefined = new types.Maybe({ range: new is.NotIn([new types.ComparisonSetType(undefined)]) }), nullOrLTE3 = new types.Maybe({ + range: new is.LessThanEqual(new types.ComparisonSetType(3)), + enum: new is.In([new types.ComparisonSetType(null)]) + }); + var res = set.difference(notUndefined, nullOrLTE3); + assert.deepEqual(res, new types.Maybe({ range: new is.GreaterThan(new types.ComparisonSetType(3)) }), '{ne: undef} \\ {lt: 3} | null -> {gte: 3}'); + }); + QUnit.test('can make a maybe type from a ComparisonSetType', function (assert) { + function toDate(str) { + var type = typeof str; + if (type === 'string') { + str = Date.parse(str); + return isNaN(str) ? null : new Date(str); + } else if (type === 'number') { + return new Date(str); + } else { + return str; + } + } + function DateStringSet(dateStr) { + this.setValue = dateStr; + var date = toDate(dateStr); + this.value = date == null ? date : date.getTime(); + } + DateStringSet.prototype.valueOf = function () { + return this.value; + }; + canReflect.assignSymbols(DateStringSet.prototype, { + 'can.serialize': function () { + return this.setValue; + } + }); + var MaybeDate = canReflect.assignSymbols({}, { + 'can.new': toDate, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Date, + undefined, + null + ] + }; + }, + 'can.ComparisonSetType': DateStringSet + }); + assert.ok(makeMaybe.canMakeMaybeSetType(MaybeDate), 'got everything we need'); + var types = makeMaybe.makeMaybeSetTypes(MaybeDate); + assert.equal(types.ComparisonSetType, DateStringSet, 'got the comparison type'); + var date1982_10_20 = new Date(1982, 9, 20).toString(); + var notUndefined = new types.Maybe({ range: new is.NotIn([new types.ComparisonSetType(undefined)]) }), nullOrLTE3 = new types.Maybe({ + range: new is.LessThanEqual(new types.ComparisonSetType(date1982_10_20)), + enum: new is.In([new types.ComparisonSetType(null)]) + }); + var res = set.difference(notUndefined, nullOrLTE3); + assert.deepEqual(res, new types.Maybe({ range: new is.GreaterThan(new types.ComparisonSetType(date1982_10_20)) }), '{ne: undef} \\ {lt: \'' + date1982_10_20 + '\'} | null -> {gte: \'' + date1982_10_20 + '\'}'); + }); + QUnit.test('orValues', function (assert) { + var res = new MaybeDateStringSet({ + range: new is.In([3]), + enum: set.EMPTY + }); + assert.deepEqual(res.orValues(), [new is.In([3])], 'only got range'); + res = new MaybeDateStringSet({ + range: set.EMPTY, + enum: new is.In([null]) + }); + assert.deepEqual(res.orValues(), [new is.In([null])], 'only got enum'); + }); +}); +/*can-query-logic@1.2.2#src/types/make-enum-test*/ +define('can-query-logic@1.2.2#src/types/make-enum-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './make-enum', + 'can-symbol' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var makeEnum = require('./make-enum'); + var canSymbol = require('can-symbol'); + QUnit.module('can-query-logic/types/make-enum'); + QUnit.test('.isMember', function (assert) { + var Status = makeEnum(function () { + }, [ + 'assigned', + 'complete' + ]); + var status = new Status(['assigned']); + assert.ok(status[canSymbol.for('can.isMember')]('assigned'), 'assigned is member'); + }); +}); +/*can-query-logic@1.2.2#src/types/values-and-test*/ +define('can-query-logic@1.2.2#src/types/values-and-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './keys-and', + './values-and', + './values-not', + './comparisons' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var KeysAnd = require('./keys-and'); + var ValuesAnd = require('./values-and'); + var ValuesNot = require('./values-not'); + var is = require('./comparisons'); + QUnit.module('can-query-logic/types/values-and'); + QUnit.test('works', function (assert) { + var allAndNot = new ValuesAnd([ + new KeysAnd({ tags: new is.All(['sbux']) }), + new KeysAnd({ tags: new ValuesNot(new is.All(['dfw'])) }) + ]); + assert.equal(allAndNot.isMember({ tags: ['sbux'] }), true); + assert.equal(allAndNot.isMember({ + tags: [ + 'sbux', + 'dfw' + ] + }), false); + }); +}); +/*can-query-logic@1.2.2#compat/compat*/ +define('can-query-logic@1.2.2#compat/compat', [ + 'require', + 'exports', + 'module', + '../can-query-logic', + 'can-reflect', + 'can-key/transform/transform', + 'can-key/delete/delete', + 'can-key/get/get', + '../src/types/make-enum', + '../src/set', + '../src/helpers' +], function (require, exports, module) { + var Query = require('../can-query-logic'); + var canReflect = require('can-reflect'); + var transform = require('can-key/transform/transform'); + var deleteKey = require('can-key/delete/delete'); + var getKey = require('can-key/get/get'); + var makeEnum = require('../src/types/make-enum'); + var SET = require('../src/set'); + var helpers = require('../src/helpers'); + var IsBoolean = function () { + }; + makeEnum(IsBoolean, [ + true, + false + ], function (value) { + if (value === 'true') { + return true; + } else if (value === 'false') { + return false; + } else { + return value; + } + }); + function hasKey(obj, keys, parent, parentKey) { + if (obj && typeof obj === 'object') { + for (var key in obj) { + if (keys[key]) { + if (typeof keys[key] === 'function') { + parent[parentKey] = keys[key](obj); + } else { + return true; + } + } else { + if (hasKey(obj[key], keys, obj, key)) { + return true; + } + } + } + } + return false; + } + function convertToJSONAPISort(sortPropValue) { + var parts = sortPropValue.split(' '); + var isDesc = (parts[1] || '').toLowerCase() === 'desc'; + return isDesc ? '-' + parts[0] : parts[0]; + } + function convertToLegacySort(value) { + var result = helpers.sortData(value); + return result.desc ? '-' + result.prop : result.prop; + } + var defaultAlgebra; + var set = { + UNIVERSAL: SET.UNIVERSAL, + EMPTY: SET.EMPTY, + UNDEFINABLE: SET.UNDEFINABLE, + UNKNOWABLE: SET.UNKNOWABLE, + Algebra: function () { + var mutators = { + schema: [], + hydrate: [], + serialize: [] + }; + canReflect.eachIndex(arguments, function (value) { + for (var prop in value) { + if (mutators[prop]) { + mutators[prop].push(value[prop]); + } else { + throw new Error('can-query-logic: This type of configuration is not supported. Please use can-query-logic directly.'); + } + } + }); + var obj = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + var schema = { + kind: 'record', + identity: [], + keys: {} + }; + mutators.schema.forEach(function (updateSchema) { + updateSchema(schema); + }); + if (!schema.identity.length) { + schema.identity.push('id'); + } + return schema; + } + }); + return new Query(obj, { + toQuery: function (data) { + return mutators.hydrate.reduce(function (last, hydrator) { + return hydrator(last); + }, { filter: data }); + }, + toParams: function (data) { + if (SET.isSpecial(data)) { + return data; + } + if (Array.isArray(data.filter)) { + return SET.UNDEFINABLE; + } + var filter = data.filter || {}; + if (hasKey(filter, { + '$ne': true, + '$in': function (val) { + return val.$in; + } + })) { + return SET.UNDEFINABLE; + } + var out = mutators.serialize.reduce(function (last, serializer) { + return serializer(last); + }, data); + filter = out.filter || {}; + delete out.filter; + return canReflect.assign(out, filter); + } + }); + }, + Translate: function (clause, prop) { + if (clause !== 'where') { + throw new Error('can-query-logic/compat.Translate is only able to translate the where clause'); + } + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + var value = clone.filter[prop]; + delete clone.filter[prop]; + if (value) { + canReflect.assign(clone.filter, value); + } + return clone; + }, + serialize: function (query) { + if (query.filter) { + var clone = canReflect.serialize(query); + var filter = query.filter; + clone.filter = {}; + clone.filter[prop] = filter; + return clone; + } else { + return query; + } + } + }; + }, + props: { + boolean: function (prop) { + return { + schema: function (schema) { + schema.keys[prop] = IsBoolean; + } + }; + }, + dotNotation: function () { + return {}; + }, + enum: function (property, propertyValues) { + function Enum() { + } + makeEnum(Enum, propertyValues); + return { + schema: function (schema) { + schema.keys[property] = Enum; + } + }; + }, + id: function (id) { + return { + 'schema': function (schema) { + schema.identity.push(id); + } + }; + }, + offsetLimit: function (offset, limit) { + offset = offset || 'offset'; + limit = limit || 'limit'; + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + if (offset in clone.filter || limit in clone.filter) { + clone.page = {}; + } + if (offset in clone.filter) { + clone.page.start = parseInt(clone.filter[offset], 10); + delete clone.filter[offset]; + } + if (limit in clone.filter) { + clone.page.end = (clone.page.start || 0) + parseInt(clone.filter[limit], 10) - 1; + delete clone.filter[limit]; + } + return clone; + }, + serialize: function (raw) { + var clone = canReflect.serialize(raw); + if (clone.page) { + clone[offset] = clone.page.start; + clone[limit] = clone.page.end - clone.page.start + 1; + delete clone.page; + } + return clone; + } + }; + }, + rangeInclusive: function (start, end) { + var hydrateTransfomer = {}; + hydrateTransfomer['filter.' + start] = 'page.start'; + hydrateTransfomer['filter.' + end] = 'page.end'; + var serializeTransformer = { + 'page.start': start, + 'page.end': end + }; + return { + hydrate: function (raw) { + var res = transform(raw, hydrateTransfomer); + if (res.page) { + if (res.page.start) { + res.page.start = parseInt(res.page.start, 10); + } + if (res.page.end) { + res.page.end = parseInt(res.page.end, 10); + } + } + return res; + }, + serialize: function (raw) { + return transform(raw, serializeTransformer); + } + }; + }, + ignore: function (prop) { + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + delete clone.filter[prop]; + return clone; + } + }; + }, + sort: function (prop, sortFunc) { + if (!prop) { + prop = 'sort'; + } + if (sortFunc) { + throw new Error('can-query-logic/compat.sort - sortFunc is not supported'); + } + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + var sort = getKey(clone, 'filter.' + prop); + if (sort !== undefined) { + deleteKey(clone, 'filter.' + prop); + clone.sort = convertToJSONAPISort(sort); + } + return clone; + }, + serialize: function (raw) { + var clone = canReflect.serialize(raw); + var sort = clone.sort; + if (sort !== undefined) { + delete clone.sort; + clone[prop] = convertToLegacySort(sort); + } + return clone; + } + }; + } + } + }; + function makeAlgebra(algebra) { + if (!algebra) { + return defaultAlgebra; + } else if (!(algebra instanceof Query)) { + return new set.Algebra(algebra); + } + return algebra; + } + function makeFromTwoQueries(prop) { + set[prop] = function (a, b, algebra) { + return makeAlgebra(algebra)[prop](a, b); + }; + } + makeFromTwoQueries('difference'); + makeFromTwoQueries('union'); + makeFromTwoQueries('intersection'); + makeFromTwoQueries('isSubset'); + makeFromTwoQueries('isEqual'); + makeFromTwoQueries('isProperSubset'); + set.count = function (query, algebra) { + return makeAlgebra(algebra).count(query); + }; + set.comparators = set.props; + defaultAlgebra = new set.Algebra(); + module.exports = set; +}); +/*can-query-logic@1.2.2#compat/prop_tests/boolean_test*/ +define('can-query-logic@1.2.2#compat/prop_tests/boolean_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set compat props.boolean'); + QUnit.test('boolean set.difference', function (assert) { + var prop = props.boolean('completed'); + var res = set.difference({}, { completed: true }, prop); + assert.deepEqual(res, { completed: false }, 'inverse of true'); + res = set.difference({}, { completed: false }, prop); + assert.deepEqual(res, { completed: true }, 'inverse of false'); + }); + QUnit.test('boolean set.union', function (assert) { + var prop = props.boolean('completed'); + var res = set.union({ completed: false }, { completed: true }, prop); + assert.deepEqual(res, {}, 'union of true and false is entire boolean set'); + }); + QUnit.test('boolean set.intersection', function (assert) { + var prop = props.boolean('completed'); + var res = set.intersection({ foo: 'bar' }, { completed: true }, prop); + assert.deepEqual(res, { + foo: 'bar', + completed: true + }, 'intersection is false (#4)'); + }); + QUnit.test('strings false and true are treated as booleans', function (assert) { + var prop = props.boolean('completed'); + var res; + res = set.isSubset({}, { completed: 'true' }, prop); + assert.ok(!res, '{} and \'true\' not a subset'); + res = set.isSubset({}, { completed: 'false' }, prop); + assert.ok(!res, '{} and \'false\' not a subset'); + res = set.isSubset({ completed: 'true' }, {}, prop); + assert.ok(res, 'subset'); + res = set.isSubset({ completed: 'false' }, {}, prop); + assert.ok(res, 'subset'); + res = set.union({ completed: 'false' }, { completed: 'true' }, prop); + assert.deepEqual(res, {}, 'union of true and false is entire boolean set'); + res = set.isEqual({ completed: false }, { completed: 'false' }, prop); + assert.ok(res, 'false and \'false\''); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/enum_test*/ +define('can-query-logic@1.2.2#compat/prop_tests/enum_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set compat props.enum'); + QUnit.test('enum set.intersection', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]); + var res = set.intersection({}, { type: 'new' }, prop); + assert.deepEqual(res, { type: 'new' }, 'single enum intersected with universal set is idempotent'); + res = set.intersection({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { + type: [ + 'new', + 'prep' + ] + }, 'array enum intersected with unversal set is idempotent'); + res = set.intersection({ type: ['prep'] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { type: 'prep' }, 'items v items intersection'); + res = set.intersection({ type: [] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, set.EMPTY, 'empty v array intersection'); + res = set.intersection({ type: 'new' }, {}, prop); + assert.deepEqual(res, { type: 'new' }, 'single v all'); + }); + QUnit.test('enum set.difference', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]), res; + res = set.difference({}, { type: 'new' }, prop); + assert.deepEqual(res, { + type: [ + 'prep', + 'deliver', + 'delivered' + ] + }, 'difference from universal set'); + res = set.difference({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { + type: [ + 'deliver', + 'delivered' + ] + }, 'difference from universal set'); + res = set.difference({ type: ['prep'] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, set.EMPTY, 'difference from a superset'); + res = set.difference({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { + type: [ + 'deliver', + 'delivered' + ] + }, 'empty enum definition is same as universal set'); + res = set.difference({ type: 'new' }, {}, prop); + assert.deepEqual(res, set.EMPTY, 'all'); + }); + QUnit.test('enum set.union', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]); + var res = set.union({}, { type: 'new' }, prop); + assert.deepEqual(res, {}, 'all'); + res = set.union({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, {}, 'intersection'); + res = set.union({ type: ['prep'] }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, { + type: [ + 'prep', + 'new' + ] + }, 'union of a superset is superset'); + res = set.union({}, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, {}, 'intersection'); + res = set.union({ type: 'new' }, {}, prop); + assert.deepEqual(res, {}, 'all'); + res = set.union({ + type: [ + 'deliver', + 'delivered' + ] + }, { + type: [ + 'new', + 'prep' + ] + }, prop); + assert.deepEqual(res, {}, 'intersection'); + }); + QUnit.test('enum set.equal', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]), res; + res = set.isEqual({}, { + type: [ + 'new', + 'prep', + 'deliver', + 'delivered' + ] + }, prop); + assert.deepEqual(res, true, 'subset of all possible enums is the same as universal set'); + res = set.isEqual({ type: ['prep'] }, { type: ['prep'] }, prop); + assert.deepEqual(res, true, 'identical sets with single array enum are equal'); + res = set.isEqual({ type: 'prep' }, { type: 'prep' }, prop); + assert.deepEqual(res, true, 'identical sets with single property enum are equal'); + res = set.isEqual({ type: 'new' }, { type: 'prep' }, prop); + assert.deepEqual(res, false, 'two sets with different enum properties are not equal'); + }); + QUnit.test('enum set.isSubset', function (assert) { + var prop = props['enum']('type', [ + 'new', + 'prep', + 'deliver', + 'delivered' + ]); + var res = set.isSubset({}, { type: 'new' }, prop); + assert.deepEqual(res, false, 'universal set is not a subset'); + res = set.isSubset({ type: 'new' }, {}, prop); + assert.deepEqual(res, true, 'any single enum is a subset of universal set'); + res = set.isSubset({}, { + type: [ + 'new', + 'prep', + 'deliver', + 'delivered' + ] + }, prop); + assert.deepEqual(res, true, 'enum set matching definition of universal set is a subset of universal set'); + res = set.isSubset({ type: ['prep'] }, { type: ['prep'] }, prop); + assert.deepEqual(res, true, 'any list of possible enums are subset of universal set'); + res = set.isSubset({ type: 'prep' }, { type: 'prep' }, prop); + assert.deepEqual(res, true, 'intersection'); + res = set.isSubset({ type: 'new' }, { type: 'prep' }, prop); + assert.deepEqual(res, false, 'all'); + res = set.isSubset({ type: 'prep' }, { + type: [ + 'new', + 'prep', + 'deliver', + 'delivered' + ] + }, prop); + assert.deepEqual(res, true, 'intersection'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/id_test*/ +define('can-query-logic@1.2.2#compat/prop_tests/id_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set props.id'); + QUnit.test('id set.difference', function (assert) { + var idProps = props.id('color'); + var res; + res = set.difference({ color: 'red' }, { color: 'blue' }, idProps); + assert.deepEqual(res, { color: 'red' }, 'id changes always false'); + res = set.difference({ color: 'red' }, {}, idProps); + assert.deepEqual(res, set.EMPTY, 'id removal always false'); + res = set.difference({}, { color: 'blue' }, idProps); + assert.deepEqual(res, set.UNDEFINABLE, 'id addition always true'); + }); + QUnit.test('id set.difference with where', function (assert) { + var algebra = new set.Algebra(props.id('color'), props.enum('type', [ + 'light', + 'dark' + ])); + var res; + res = set.difference({ + color: 'red', + type: [ + 'light', + 'dark' + ] + }, { + color: 'blue', + type: 'light' + }, algebra); + assert.deepEqual(res, { + color: 'red', + type: [ + 'light', + 'dark' + ] + }, 'id changes always false'); + res = set.difference({ + color: 'red', + type: [ + 'light', + 'dark' + ] + }, { type: 'light' }, algebra); + assert.deepEqual(res, { + color: 'red', + type: 'dark' + }, 'id removal always false'); + var a2 = new set.Algebra(props.enum('color', [ + 'red', + 'green' + ])); + res = set.difference({ + color: [ + 'red', + 'green' + ] + }, { + status: 'accepted', + color: 'red' + }, a2); + assert.deepEqual(res, set.UNDEFINABLE, 'id addition always true'); + res = set.difference({ + type: [ + 'light', + 'dark' + ] + }, { type: 'light' }, algebra); + assert.deepEqual(res, { type: 'dark' }, 'no id clause, fall back to where'); + res = set.difference({ + color: 'red', + type: [ + 'light', + 'dark' + ] + }, { + color: 'red', + type: 'light' + }, algebra); + assert.deepEqual(res, { + color: 'red', + type: 'dark' + }, 'no id change, fall back to where'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/rangeInclusive_test*/ +define('can-query-logic@1.2.2#compat/prop_tests/rangeInclusive_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set props.rangeInclusive'); + QUnit.test('rangeInclusive set.equal', function (assert) { + assert.ok(set.isEqual({ + start: 0, + end: 100 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'they are equal'); + assert.ok(!set.isEqual({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }, props.rangeInclusive('start', 'end')), 'they are not equal'); + assert.ok(!set.isEqual({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }, props.rangeInclusive('start', 'end')), 'they are not equal'); + }); + QUnit.test('rangeInclusive set.isSubset', function (assert) { + assert.ok(set.isSubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'self is a subset'); + assert.ok(set.isSubset({ + start: 0, + end: 100 + }, { + start: 0, + end: 101 + }, props.rangeInclusive('start', 'end')), 'end extends past subset'); + assert.ok(!set.isSubset({ + start: 0, + end: 101 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'non-subset extends past end'); + assert.ok(set.isSubset({ + start: 1, + end: 100 + }, { + start: 0, + end: 100 + }, props.rangeInclusive('start', 'end')), 'start extends before subset'); + assert.ok(!set.isSubset({ + start: 0, + end: 100 + }, { + start: 1, + end: 100 + }, props.rangeInclusive('start', 'end')), 'non-subset extends before start'); + }); + QUnit.test('rangeInclusive set.difference', function (assert) { + var prop = props.rangeInclusive('start', 'end'); + var res = set.difference({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }, prop); + assert.deepEqual(res, { + start: 0, + end: 49 + }, 'got a diff'); + res = set.difference({}, { + start: 0, + end: 10 + }, prop); + assert.deepEqual(res, { start: 11 }, 'universal set'); + res = set.difference({ + start: 0, + end: 49 + }, { + start: 50, + end: 101 + }, prop); + assert.deepEqual(res, { + start: 0, + end: 49 + }, 'side by side'); + res = set.difference({ + start: 0, + end: 49 + }, { + start: 0, + end: 20 + }, prop); + assert.deepEqual(res, { + start: 21, + end: 49 + }, 'first set extends past second'); + res = set.difference({ + start: 0, + end: 49 + }, { + start: 20, + end: 49 + }, prop); + assert.deepEqual(res, { + start: 0, + end: 19 + }, 'first set starts before second'); + }); + QUnit.test('rangeInclusive set.union', function (assert) { + var prop = props.rangeInclusive('start', 'end'); + var res = set.union({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }, prop); + assert.deepEqual(res, { + start: 0, + end: 101 + }, 'got a union'); + res = set.union({}, { + start: 0, + end: 10 + }, prop); + assert.deepEqual(res, {}, 'universal set'); + res = set.union({ + start: 100, + end: 199 + }, { + start: 200, + end: 299 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection'); + res = set.union({ + start: 200, + end: 299 + }, { + start: 100, + end: 199 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'no intersection with either argument order'); + res = set.union({ + start: 200, + end: 299 + }, { + start: 100, + end: 209 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect'); + res = set.union({ + start: 100, + end: 209 + }, { + start: 200, + end: 299 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'sets can intersect with either argument order'); + res = set.union({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'first set contains second'); + res = set.union({ + start: 100, + end: 299 + }, { + start: 103, + end: 209 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'second set contains first'); + res = set.union({ + start: 100, + end: 299 + }, { + start: 100, + end: 299 + }, prop); + assert.deepEqual(res, { + start: 100, + end: 299 + }, 'union of identical sets is the same as those sets'); + }); + QUnit.test('rangeInclusive set.count', function (assert) { + var prop = props.rangeInclusive('start', 'end'); + var res = set.count({ + start: 0, + end: 99 + }, prop); + assert.equal(res, 100, 'count is right'); + }); + QUnit.test('rangeInclusive set.intersection', function (assert) { + var prop = props.rangeInclusive('start', 'end'); + var res = set.intersection({ + start: 0, + end: 99 + }, { + start: 50, + end: 101 + }, prop); + assert.deepEqual(res, { + start: 50, + end: 99 + }, 'got a intersection'); + res = set.intersection({ + start: 0, + end: 10, + age: 35 + }, { + start: 0, + end: 100, + name: 'JBM' + }, prop); + assert.deepEqual(res, set.UNDEFINABLE, 'got a intersection'); + }); + QUnit.test('rangeInclusive with string numbers (#17)', function (assert) { + var algebra = new set.Algebra(props.rangeInclusive('start', 'end')); + assert.ok(algebra.isSubset({ + start: '1', + end: '100' + }, { + start: '0', + end: '100' + }), '.subset'); + var res = algebra.filterMembers({ + start: '2', + end: '3' + }, { + start: '1', + end: '4' + }, [ + { id: 1 }, + { id: 2 }, + { id: 3 }, + { id: 4 } + ]); + assert.deepEqual(res, [ + { id: 2 }, + { id: 3 } + ], '.filterMembers'); + res = algebra.unionMembers({ + start: '2', + end: '3' + }, { + start: '1', + end: '4' + }, [ + { id: 2 }, + { id: 3 } + ], [ + { id: 1 }, + { id: 2 }, + { id: 3 }, + { id: 4 } + ]); + assert.deepEqual(res, [ + { id: 1 }, + { id: 2 }, + { id: 3 }, + { id: 4 } + ], '.unionMembers'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/offsetLimit_test*/ +define('can-query-logic@1.2.2#compat/prop_tests/offsetLimit_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + QUnit.module('can-set props.limitOffset'); + QUnit.test('offsetLimit set.equal', function (assert) { + assert.ok(set.isEqual({ + offset: 0, + limit: 99 + }, { + offset: 0, + limit: 99 + }, props.offsetLimit('offset', 'limit')), 'they are equal'); + assert.ok(!set.isEqual({ + offset: 0, + limit: 100 + }, { + offset: 0, + limit: 101 + }, props.offsetLimit('offset', 'limit')), 'they are not equal'); + assert.ok(!set.isEqual({ + offset: 0, + limit: 100 + }, { + offset: 1, + limit: 100 + }, props.offsetLimit('offset', 'limit')), 'they are not equal'); + }); + QUnit.test('offsetLimit set.union', function (assert) { + var prop = props.offsetLimit('offset', 'limit'), res; + res = set.union({ + offset: 0, + limit: 100 + }, { + offset: 50, + limit: 52 + }, prop); + assert.deepEqual(res, { + offset: 0, + limit: 102 + }, 'got a union'); + res = set.union({}, { + offset: 0, + limit: 10 + }, prop); + assert.deepEqual(res, {}, 'universal set'); + res = set.union({ + offset: 100, + limit: 100 + }, { + offset: 200, + limit: 100 + }, prop); + assert.deepEqual(res, { + offset: 100, + limit: 200 + }, 'no intersection'); + res = set.union({ + offset: 200, + limit: 100 + }, { + offset: 100, + limit: 100 + }, prop); + assert.deepEqual(res, { + offset: 100, + limit: 200 + }, 'no intersection with either argument order'); + res = set.union({ + offset: 100, + limit: 110 + }, { + offset: 200, + limit: 100 + }, prop); + assert.deepEqual(res, { + offset: 100, + limit: 200 + }, 'sets can intersect with either argument order'); + }); + QUnit.test('rangeInclusive set.count', function (assert) { + var prop = props.offsetLimit('offset', 'limit'); + var res = set.count({ + offset: 0, + limit: 100 + }, prop); + assert.equal(res, 100, 'count is right'); + }); + QUnit.test('rangeInclusive set.intersection', function (assert) { + var prop = props.offsetLimit('offset', 'limit'); + var res = set.intersection({ + offset: 0, + limit: 100 + }, { + offset: 50, + limit: 52 + }, prop); + assert.deepEqual(res, { + offset: 50, + limit: 50 + }, 'got a intersection'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/sort_test*/ +define('can-query-logic@1.2.2#compat/prop_tests/sort_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../compat', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var set = require('../compat'), props = set.props; + var canReflect = require('can-reflect'); + QUnit.module('can-set props.sort'); + QUnit.test('set.difference', function (assert) { + var prop = props.sort('sort'), res; + res = set.difference({ sort: 'foo' }, { completed: true }, prop); + assert.deepEqual(res, set.UNDEFINABLE, 'diff should be true'); + res = set.difference({ completed: true }, { + completed: true, + sort: 'foo' + }, prop); + assert.equal(res, set.EMPTY, 'the same except for sort'); + res = set.difference({ completed: true }, { sort: 'foo' }, prop); + assert.equal(res, set.EMPTY, 'nothing in completed:true that isn\'t in everything'); + res = set.difference({ completed: true }, { + foo: 'bar', + sort: 'foo' + }, prop); + assert.equal(res, set.UNDEFINABLE, 'we can diff, it exists, we don\'t know what it is though'); + }); + QUnit.test('set.union', function (assert) { + var prop = props.sort('sort'), res; + res = set.union({ sort: 'name' }, { completed: true }, prop); + assert.deepEqual(res, {}, 'set / subset sort left'); + res = set.union({}, { + completed: true, + sort: 'name' + }, prop); + assert.deepEqual(res, {}, 'set / subset sort right'); + res = set.union({ sort: 'name' }, { + completed: true, + sort: 'namer' + }, prop); + assert.deepEqual(res, {}, 'set / subset both sorts'); + res = set.union({ completed: true }, { sort: 'foo' }, prop); + assert.deepEqual(res, {}, 'subset / set'); + res = set.union({ + foo: 'bar', + sort: 'foo' + }, { foo: 'bar' }, prop); + assert.deepEqual(res, { foo: 'bar' }, 'equal'); + res = set.union({ foo: 'bar' }, { + foo: 'zed', + sort: 'foo' + }, prop); + assert.deepEqual(res, { + foo: [ + 'bar', + 'zed' + ] + }, 'values not equal'); + res = set.union({ + foo: 'bar', + sort: 'foo' + }, { name: 'A' }, prop); + assert.deepEqual(res, set.UNDEFINABLE, 'values not equal'); + }); + QUnit.test('set.union Array', function (assert) { + var prop = props.sort('sort'); + var res = set.union({ + foo: [ + 'a', + 'b' + ], + sort: 'foo' + }, { + foo: [ + 'a', + 'c' + ] + }, prop); + assert.deepEqual(res, { + foo: [ + 'a', + 'b', + 'c' + ] + }, 'set / subset'); + }); + QUnit.test('set.count', function (assert) { + assert.ok(set.count({ sort: 'name' }) === Infinity, 'defaults to infinity'); + assert.ok(set.count({ + foo: 'bar', + sort: 'foo' + }, {}) === Infinity, 'defaults to infinity'); + }); + QUnit.test('set.intersection', function (assert) { + var prop = props.sort('sort'), res; + res = set.intersection({}, { sort: 'name' }, prop); + assert.deepEqual(res, {}, 'no sort if only one is sorted'); + res = set.intersection({ sort: 'name' }, { sort: 'name' }, prop); + assert.deepEqual(res, { sort: 'name' }, 'equal'); + res = set.intersection({ type: 'new' }, { + sort: 'name', + userId: 5 + }, prop); + assert.deepEqual(res, { + type: 'new', + userId: 5 + }, ''); + res = set.intersection({ + type: 'new', + sort: 'age' + }, { + sort: 'name', + userId: 5 + }, prop); + assert.deepEqual(res, { + type: 'new', + userId: 5 + }, ''); + }); + QUnit.test('set.intersection Array', function (assert) { + var prop = props.sort('sort'); + var res = set.intersection({ + foo: [ + 'a', + 'b' + ], + sort: 'foo' + }, { + foo: [ + 'a', + 'c' + ] + }, prop); + assert.deepEqual(res, { foo: 'a' }, 'intersection'); + }); + QUnit.test('set.isSubset', function (assert) { + var algebra = new set.Algebra(props.sort('sort'), set.props.ignore('foo'), set.props.ignore('bar'), set.props.ignore('kind'), set.props.ignore('count')); + assert.ok(algebra.isSubset({ + type: 'FOLDER', + sort: 'thing' + }, { type: 'FOLDER' }), 'equal sets with sort on the left'); + assert.ok(algebra.isSubset({ type: 'FOLDER' }, { + type: 'FOLDER', + sort: 'thing' + }), 'equal sets with sort on the right'); + assert.ok(algebra.isSubset({ + type: 'FOLDER', + parentId: 5, + sort: 'thing' + }, { type: 'FOLDER' }), 'sub set with sort on the left'); + assert.ok(algebra.isSubset({ + type: 'FOLDER', + parentId: 5 + }, { + type: 'FOLDER', + sort: 'thing' + }), 'sub set with sort on the right'); + assert.ok(!algebra.isSubset({ + type: 'FOLDER', + sort: 'thing' + }, { + type: 'FOLDER', + parentId: 5 + }), 'wrong way with sort on the left'); + assert.ok(!algebra.isSubset({ type: 'FOLDER' }, { + type: 'FOLDER', + parentId: 5, + sort: 'thing' + }), 'wrong way with sort on the right'); + assert.ok(!algebra.isSubset({ + type: 'FOLDER', + parentId: 7, + sort: 'thing' + }, { + type: 'FOLDER', + parentId: 5 + }), 'different values with sort on the left'); + assert.ok(!algebra.isSubset({ + type: 'FOLDER', + parentId: 7 + }, { + type: 'FOLDER', + parentId: 5, + sort: 'thing' + }), 'different values with sort on the right'); + }); + QUnit.test('set.isSubset with range', function (assert) { + var algebra = new set.Algebra(props.sort('sort'), props.rangeInclusive('start', 'end')); + var addSort = function (set, value) { + set.sort = value; + }; + var sort = { + left: function (setA) { + addSort(setA, 'prop'); + }, + right: function (setA, setB) { + addSort(setB, 'prop'); + }, + same: function (setA, setB) { + addSort(setA, 'prop'); + addSort(setB, 'prop'); + }, + different: function (setA, setB) { + addSort(setA, 'propA'); + addSort(setB, 'propB'); + } + }; + var addRange = function (set, start, end) { + set.start = start; + set.end = end; + }; + var range = { + left: function (setA) { + addRange(setA, 0, 9); + }, + right: function (setA, setB) { + addRange(setB, 0, 9); + }, + same: function (setA, setB) { + addRange(setA, 0, 9); + addRange(setB, 0, 9); + }, + superLeft: function (setA, setB) { + addRange(setA, 0, 9); + addRange(setB, 3, 7); + }, + superRight: function (setA, setB) { + addRange(setB, 0, 9); + addRange(setA, 3, 7); + } + }; + var sets = { + same: function () { + }, + superLeft: function (setA, setB) { + setB.type = 'apples'; + }, + superRight: function (setA) { + setA.type = 'apples'; + } + }; + var make = function () { + var setA = {}, setB = {}; + canReflect.eachIndex(arguments, function (method) { + method(setA, setB); + }); + return { + left: setA, + right: setB + }; + }; + var assertSubset = function (methods, result) { + var sets = make.apply(null, methods); + assert.equal(algebra.isSubset(sets.left, sets.right), result, JSON.stringify(sets.left) + ' \u2282 ' + JSON.stringify(sets.right) + ' = ' + result); + }; + assertSubset([ + sets.same, + range.same, + sort.different + ], undefined); + }); + QUnit.test('set.index', function (assert) { + var algebra = new set.Algebra(props.sort('sort')); + var index = algebra.index({ sort: 'name' }, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { name: 'k' }); + assert.equal(index, 2); + }); + QUnit.test('set.filterMembers (#14)', function (assert) { + var algebra = new set.Algebra(props.sort('sort')); + var subset = algebra.filterMembers({ sort: 'name' }, {}, [ + { + id: 1, + name: 's' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 'g' + } + ]); + assert.deepEqual(subset, [ + { + id: 4, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 1, + name: 's' + } + ]); + }); + QUnit.test('set.unionMembers', function (assert) { + var algebra = new set.Algebra(props.sort('sort'), props.boolean('complete')); + var union = algebra.unionMembers({ + sort: 'name', + complete: true + }, { + sort: 'name', + complete: false + }, [ + { + id: 4, + name: 'g', + complete: true + }, + { + id: 3, + name: 'm', + complete: true + } + ], [ + { + id: 2, + name: 'j', + complete: false + }, + { + id: 1, + name: 's', + complete: false + } + ]); + assert.deepEqual(union, [ + { + id: 4, + name: 'g', + complete: true + }, + { + id: 2, + name: 'j', + complete: false + }, + { + id: 3, + name: 'm', + complete: true + }, + { + id: 1, + name: 's', + complete: false + } + ]); + }); + QUnit.test('set.union keeps sort', function (assert) { + var algebra = new set.Algebra(props.sort('sort'), props.boolean('complete')); + var union = algebra.union({ + sort: 'name', + complete: true + }, { + sort: 'name', + complete: false + }); + assert.deepEqual(union, { sort: 'name' }); + }); + QUnit.test('paginated and sorted is subset (#17)', function (assert) { + var algebra = new set.Algebra(props.sort('sort'), props.rangeInclusive('start', 'end')), res; + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, { + start: 0, + end: 100, + sort: 'age' + }); + assert.equal(res, undefined, 'parent:paginate+order child:paginate+order (different order)'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, { sort: 'name' }); + assert.equal(res, true, 'parent:order child:paginate+order'); + res = algebra.isSubset({ sort: 'name' }, { sort: 'name' }); + assert.equal(res, true, 'parent:order child:order (same)'); + res = algebra.isSubset({ sort: 'name' }, { sort: 'age' }); + assert.equal(res, true, 'parent:order child:order (different)'); + res = algebra.isSubset({ + start: 0, + end: 100 + }, { sort: 'name' }); + assert.equal(res, true, 'parent:order child:paginate'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'age' + }, { sort: 'name' }); + assert.equal(res, true, 'parent:order child:paginate+order'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, { + start: 0, + end: 100 + }); + assert.equal(res, undefined, 'parent:paginate child:paginate+order'); + res = algebra.isSubset({ sort: 'name' }, { + start: 0, + end: 100 + }); + assert.equal(res, false, 'parent:paginate child:order (same)'); + res = algebra.isSubset({ + start: 0, + end: 100, + sort: 'name' + }, {}); + assert.equal(res, true, 'parent:-- child:paginate+order'); + res = algebra.isSubset({ + start: 10, + end: 90, + sort: 'name' + }, { + start: 0, + end: 100, + sort: 'name' + }); + assert.equal(res, true, 'child in smaller range, same sort'); + res = algebra.isSubset({ + start: 10, + end: 90, + sort: 'name' + }, { + start: 0, + end: 100, + sort: 'age' + }); + assert.equal(res, undefined, 'child in smaller range, but different sort'); + }); +}); +/*can-query-logic@1.2.2#compat/prop_tests/translate_test*/ +define('can-query-logic@1.2.2#compat/prop_tests/translate_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../../src/set', + '../compat' +], function (require, exports, module) { + require('steal-qunit'); + var querySet = require('../../src/set'); + var set = require('../compat'); + var ignoreProp = function () { + return true; + }; + QUnit.module('can-set set.Translate - nested where'); + QUnit.test('set.equal', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where'), set.props.ignore('count')); + var res; + res = algebra.isEqual({ $where: { type: 'FOLDER' } }, { + $where: { + type: 'FOLDER', + count: 5 + } + }); + assert.ok(res, 'count ignored'); + res = algebra.isEqual({ $where: { type: 'FOLDER' } }, { $where: { type: 'FOLDER' } }); + assert.ok(res, 'folder case ignored'); + }); + QUnit.test('set.isSubset', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where'), set.props.ignore('foo'), set.props.ignore('bar'), set.props.ignore('kind'), set.props.ignore('count')); + var res; + res = algebra.isSubset({ $where: { type: 'FOLDER' } }, { $where: { type: 'FOLDER' } }); + assert.ok(res, 'equal sets'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + parentId: 5 + } + }, { $where: { type: 'FOLDER' } }); + assert.ok(res, 'sub set'); + res = algebra.isSubset({ $where: { type: 'FOLDER' } }, { + $where: { + type: 'FOLDER', + parentId: 5 + } + }); + assert.ok(!res, 'wrong way'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + parentId: 7 + } + }, { + $where: { + type: 'FOLDER', + parentId: 5 + } + }); + assert.ok(!res, 'different values'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + count: 5 + } + }, { $where: { type: 'FOLDER' } }); + assert.ok(res, 'count ignored'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + category: 'tree' + } + }, { + $where: { + type: 'FOLDER', + foo: true, + bar: true + } + }); + assert.ok(res, 'understands a subset'); + res = algebra.isSubset({ + $where: { + type: 'FOLDER', + foo: true, + bar: true + } + }, { + $where: { + type: 'FOLDER', + kind: 'tree' + } + }); + assert.ok(res, 'ignores nulls'); + }); + QUnit.test('set.isProperSubset', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + assert.equal(algebra.isProperSubset({ $where: { foo: 'bar' } }, { $where: {} }), true); + assert.equal(algebra.isProperSubset({ $where: {} }, { $where: {} }), false); + assert.equal(algebra.isProperSubset({ $where: {} }, { $where: { foo: 'bar' } }), false); + }); + QUnit.test('set.difference', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.difference({ $where: {} }, { $where: { completed: true } }); + assert.equal(res, querySet.UNDEFINABLE, 'diff should be true'); + res = algebra.difference({ $where: { completed: true } }, { $where: { completed: true } }); + assert.equal(res, querySet.EMPTY); + res = algebra.difference({ $where: { completed: true } }, { $where: {} }); + assert.equal(res, querySet.EMPTY); + res = algebra.difference({ $where: { completed: true } }, { $where: { userId: 5 } }); + assert.equal(res, querySet.UNDEFINABLE); + }); + QUnit.test('set.union', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.union({ $where: {} }, { $where: { completed: true } }); + assert.deepEqual(res, {}, 'set / subset'); + res = algebra.union({ $where: { completed: true } }, { $where: {} }); + assert.deepEqual(res, {}, 'subset / set'); + res = algebra.union({ $where: { foo: 'bar' } }, { $where: { foo: 'bar' } }); + assert.deepEqual(res, { $where: { foo: 'bar' } }, 'equal'); + res = algebra.union({ $where: { foo: 'bar' } }, { $where: { foo: 'zed' } }); + assert.deepEqual(res, { + $where: { + foo: [ + 'bar', + 'zed' + ] + } + }, 'values not equal'); + res = algebra.union({ $where: { foo: 'bar' } }, { $where: { name: 'A' } }); + assert.deepEqual(res, querySet.UNDEFINABLE, 'values not equal'); + }); + QUnit.test('set.union Array', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.union({ + $where: { + foo: [ + 'a', + 'b' + ] + } + }, { + $where: { + foo: [ + 'a', + 'c' + ] + } + }); + assert.deepEqual(res, { + $where: { + foo: [ + 'a', + 'b', + 'c' + ] + } + }, 'set / subset'); + }); + QUnit.test('set.intersection', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')), res; + res = algebra.intersection({ $where: {} }, { $where: { completed: true } }); + assert.deepEqual(res, { $where: { completed: true } }, 'set / subset'); + res = algebra.intersection({ $where: { completed: true } }, { $where: {} }); + assert.deepEqual(res, { $where: { completed: true } }, 'subset / set'); + res = algebra.intersection({ $where: { foo: 'bar' } }, { $where: { foo: 'bar' } }); + assert.deepEqual(res, { $where: { foo: 'bar' } }, 'equal'); + res = algebra.intersection({ $where: { foo: 'bar' } }, { $where: { foo: 'zed' } }); + assert.deepEqual(res, querySet.EMPTY, 'values not equal'); + res = algebra.intersection({ $where: { foo: 'bar' } }, { $where: { completed: true } }); + assert.deepEqual(res, { + $where: { + foo: 'bar', + completed: true + } + }, 'intersection should combine definitions'); + }); + QUnit.test('set.intersection Array', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where')); + var res = algebra.intersection({ + $where: { + foo: [ + 'a', + 'b' + ] + } + }, { + $where: { + foo: [ + 'a', + 'c' + ] + } + }); + assert.deepEqual(res, { $where: { foo: 'a' } }, 'intersection'); + }); + QUnit.test('set.has', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', '$where'), set.props.ignore('count'), set.props.ignore('foo'), set.props.ignore('bar'), set.props.ignore('kind')); + assert.ok(algebra.isMember({ $where: { someId: 5 } }, { + someId: 5, + name: 'foo' + }), 'contains'); + var res; + res = algebra.isMember({ $where: { type: 'FOLDER' } }, { type: 'FOLDER' }); + assert.ok(res, 'equal sets'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + parentId: 5 + } + }, { type: 'FOLDER' }); + assert.equal(res, false, 'doesnt match'); + res = algebra.isMember({ $where: { type: 'FOLDER' } }, { + type: 'FOLDER', + parentId: 5 + }); + assert.ok(true, 'is a subset'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + parentId: 7 + } + }, { + type: 'FOLDER', + parentId: 5 + }); + assert.ok(!res, 'different values'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + count: 5 + } + }, { type: 'FOLDER' }, { count: ignoreProp }); + assert.ok(res, 'count ignored'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + kind: 'tree' + } + }, { + type: 'FOLDER', + foo: true, + bar: true + }); + assert.ok(res, 'understands a subset'); + res = algebra.isMember({ + $where: { + type: 'FOLDER', + foo: true, + bar: true + } + }, { + type: 'FOLDER', + kind: 'tree' + }); + assert.ok(res, 'ignores nulls'); + }); +}); +/*can-query-logic@1.2.2#compat/compat-test*/ +define('can-query-logic@1.2.2#compat/compat-test', [ + 'require', + 'exports', + 'module', + './prop_tests/boolean_test', + './prop_tests/enum_test', + './prop_tests/id_test', + './prop_tests/rangeInclusive_test', + './prop_tests/offsetLimit_test', + './prop_tests/sort_test', + './prop_tests/translate_test' +], function (require, exports, module) { + require('./prop_tests/boolean_test'); + require('./prop_tests/enum_test'); + require('./prop_tests/id_test'); + require('./prop_tests/rangeInclusive_test'); + require('./prop_tests/offsetLimit_test'); + require('./prop_tests/sort_test'); + require('./prop_tests/translate_test'); +}); +/*can-query-logic@1.2.2#test/special-comparison-logic-test*/ +define('can-query-logic@1.2.2#test/special-comparison-logic-test', [ + 'require', + 'exports', + 'module', + '../can-query-logic', + 'steal-qunit', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + var QueryLogic = require('../can-query-logic'); + var QUnit = require('steal-qunit'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + QUnit.module('can-query-logic special comparison logic'); + QUnit.test('where to filter', function (assert) { + var todoQueryLogic = new QueryLogic({}, { + toQuery: function (params) { + var where = params.where; + delete params.where; + params.filter = where; + return params; + }, + toParams: function (query) { + var where = query.filter; + delete query.filter; + query.where = where; + return query; + } + }); + var q1 = { where: { first: 'FIRST' } }, q2 = { where: { second: 'SECOND' } }; + var q3 = todoQueryLogic.intersection(q1, q2); + assert.deepEqual(q3, { + where: { + first: 'FIRST', + second: 'SECOND' + } + }, 'got intersection'); + }); + var stringIncludes = function (strA, strB) { + return strA.indexOf(strB) >= 0; + }; + QUnit.test('Searchable string', function (assert) { + function SearchableStringSet(value) { + this.value = value; + } + canReflect.assignSymbols(SearchableStringSet.prototype, { + 'can.isMember': function (value) { + return stringIncludes(value, this.value); + }, + 'can.serialize': function () { + return this.value; + } + }); + QueryLogic.defineComparison(SearchableStringSet, SearchableStringSet, { + union: function (searchA, searchB) { + if (stringIncludes(searchA.value, searchB.value)) { + return searchB; + } + if (stringIncludes(searchB.value, searchA.value)) { + return searchA; + } + return new QueryLogic.ValuesOr([ + searchA, + searchB + ]); + }, + intersection: function (searchA, searchB) { + if (stringIncludes(searchA.value, searchB.value)) { + return searchA; + } + if (stringIncludes(searchB.value, searchA.value)) { + return searchB; + } + return QueryLogic.UNDEFINABLE; + }, + difference: function (searchA, searchB) { + if (stringIncludes(searchA.value, searchB.value)) { + return QueryLogic.EMPTY; + } + if (stringIncludes(searchB.value, searchA.value)) { + return QueryLogic.UNDEFINABLE; + } + return QueryLogic.UNDEFINABLE; + } + }); + function SearchableString() { + } + SearchableString[canSymbol.for('can.SetType')] = SearchableStringSet; + var todoQueryLogic = new QueryLogic({ keys: { name: SearchableString } }); + var res = todoQueryLogic.isSubset({ filter: { name: 'beat' } }, { filter: { name: 'eat' } }); + assert.equal(res, true, 'is subset'); + res = todoQueryLogic.isSubset({ filter: { name: 'eat' } }, { filter: { name: 'beat' } }); + assert.equal(res, false, 'not subset'); + var hydrated = todoQueryLogic.hydrate({ filter: { name: 'eat' } }); + assert.deepEqual(hydrated.filter, new QueryLogic.KeysAnd({ name: new SearchableStringSet('eat') }), 'hydrated right'); + res = todoQueryLogic.union({ filter: { name: 'eat' } }, { filter: { name: 'foo' } }); + assert.deepEqual(res, { + filter: { + name: [ + 'eat', + 'foo' + ] + } + }); + assert.ok(todoQueryLogic.isMember({ filter: { name: 'eat' } }, { + id: 1, + name: 'eat beans' + }), 'isMember true'); + assert.notOk(todoQueryLogic.isMember({ filter: { name: 'eat' } }, { + id: 1, + name: 'foo bar' + }), 'isMember false'); + }); + QUnit.test('value type', function (assert) { + function DateStringSet(dateStr) { + this.dateStr = dateStr; + } + DateStringSet.prototype.valueOf = function () { + return new Date(this.dateStr).valueOf(); + }; + canReflect.assignSymbols(DateStringSet.prototype, { + 'can.serialize': function () { + return this.dateStr; + } + }); + function DateString() { + } + canReflect.assignSymbols(DateString, { 'can.SetType': DateStringSet }); + var queryLogic = new QueryLogic({ keys: { date: DateString } }); + var oct20_1982 = new Date(1982, 9, 20), date90s = new Date(1990, 0, 1); + var result = queryLogic.filterMembers({ filter: { date: { $gt: oct20_1982.toString() } } }, [ + { + id: 1, + date: new Date(1981, 9, 20).toString() + }, + { + id: 2, + date: new Date(1982, 9, 20).toString() + }, + { + id: 3, + date: new Date(1983, 9, 20).toString() + }, + { + id: 4, + date: new Date(1984, 9, 20).toString() + } + ]); + assert.deepEqual(result.map(function (item) { + return item.id; + }), [ + 3, + 4 + ], 'filtered correctly'); + var union = queryLogic.union({ filter: { date: [oct20_1982.toString()] } }, { filter: { date: [date90s.toString()] } }); + assert.deepEqual(union, { + filter: { + date: { + $in: [ + oct20_1982.toString(), + date90s.toString() + ] + } + } + }, 'union of 2 dates works correctly'); + result = queryLogic.filterMembers({ sort: 'date' }, [ + { + id: 2, + date: new Date(1982, 9, 20).toString() + }, + { + id: 1, + date: new Date(1981, 9, 20).toString() + }, + { + id: 4, + date: new Date(1984, 9, 20).toString() + }, + { + id: 3, + date: new Date(1983, 9, 20).toString() + } + ]); + var ids = result.map(function (item) { + return item.id; + }); + assert.deepEqual(ids, [ + 1, + 2, + 3, + 4 + ], 'sorted correctly'); + var index = queryLogic.index({ sort: 'date' }, [ + { + id: 1, + date: new Date(2018, 4, 20).toString() + }, + { + id: 2, + date: new Date(2018, 4, 21).toString() + }, + { + id: 3, + date: new Date(2018, 4, 22).toString() + }, + { + id: 4, + date: new Date(2018, 4, 23).toString() + } + ], { + id: 4, + date: new Date(2018, 4, 24).toString() + }); + assert.equal(index, 4, 'added at the end'); + }); + QUnit.test('sort a type that is similar to the member values (#31)', function (assert) { + function StringIgnoreCaseSet(value) { + this.value = value; + } + StringIgnoreCaseSet.prototype.valueOf = function () { + return this.value.toLowerCase(); + }; + canReflect.assignSymbols(StringIgnoreCaseSet.prototype, { + 'can.serialize': function () { + return this.value; + } + }); + var StringIgnoreCase = canReflect.assignSymbols({}, { + 'can.SetType': StringIgnoreCaseSet, + 'can.new': function (value) { + return value; + } + }); + var queryLogic = new QueryLogic({ + keys: { name: StringIgnoreCase }, + identity: ['id'] + }); + var filter = queryLogic.filterMembers({ sort: 'name' }, [ + { + id: 1, + name: 'grab coffee' + }, + { + id: 2, + name: 'finish these docs' + }, + { + id: 3, + name: 'Learn CanJS' + } + ]); + assert.deepEqual([ + { + id: 2, + name: 'finish these docs' + }, + { + id: 1, + name: 'grab coffee' + }, + { + id: 3, + name: 'Learn CanJS' + } + ], filter); + }); +}); +/*can-query-logic@1.2.2#test/make-enum-logic-test*/ +define('can-query-logic@1.2.2#test/make-enum-logic-test', [ + 'require', + 'exports', + 'module', + 'can-query-logic', + 'can-reflect', + '../src/types/make-enum' +], function (require, exports, module) { + var QueryLogic = require('can-query-logic'); + var canReflect = require('can-reflect'); + var makeEnum = require('../src/types/make-enum'); + QUnit.module('can-query-logic with makeEnum'); + function Color() { + } + makeEnum(Color, [ + 'red', + 'green', + 'blue' + ]); + var TODO = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + return { + kind: 'record', + identity: ['id'], + keys: { + id: Number, + points: Number, + status: Color, + complete: Boolean, + name: String + } + }; + } + }); + var algebra = new QueryLogic(TODO); + QUnit.test('union - enum', function (assert) { + var unionResult = algebra.union({ + filter: { + name: 'Justin', + status: 'red' + } + }, { + filter: { + name: 'Justin', + status: 'green' + } + }); + assert.deepEqual(unionResult, { + filter: { + name: 'Justin', + status: [ + 'red', + 'green' + ] + } + }); + }); + QUnit.test('automatic enum', function (assert) { + var MaybeBoolean = canReflect.assignSymbols({}, { + 'can.new': function (val) { + if (val == null) { + return val; + } + if (val === 'false' || val === '0' || !val) { + return false; + } + return true; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + true, + false, + undefined, + null + ] + }; + } + }); + var queryLogic = new QueryLogic({ + identity: ['id'], + keys: { complete: MaybeBoolean } + }); + var res; + res = queryLogic.difference({}, { filter: { complete: true } }); + assert.deepEqual(res, { + filter: { + complete: [ + false, + undefined, + null + ] + } + }, 'enum works'); + }); + QUnit.test('makeEnum from homepage with schema type', function (assert) { + var Status = canReflect.assignSymbols({}, { + 'can.new': function (val) { + return val; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + 'new', + 'assigned', + 'complete' + ] + }; + } + }); + var todoLogic = new QueryLogic({ + identity: ['id'], + keys: { status: Status } + }); + var unionQuery = todoLogic.union({ + filter: { + status: [ + 'new', + 'assigned' + ] + } + }, { filter: { status: 'complete' } }); + assert.deepEqual(unionQuery, {}); + }); + QUnit.test('makeEnum from homepage', function (assert) { + var Status = QueryLogic.makeEnum([ + 'new', + 'assigned', + 'complete' + ]); + var todoLogic = new QueryLogic({ + identity: ['id'], + keys: { status: Status } + }); + var unionQuery = todoLogic.union({ + filter: { + status: [ + 'new', + 'assigned' + ] + } + }, { filter: { status: 'complete' } }); + assert.deepEqual(unionQuery, {}); + }); +}); +/*can-query-logic@1.2.2#test/maybe-type-test*/ +define('can-query-logic@1.2.2#test/maybe-type-test', [ + 'require', + 'exports', + 'module', + '../can-query-logic', + 'steal-qunit', + 'can-reflect' +], function (require, exports, module) { + var QueryLogic = require('../can-query-logic'); + var QUnit = require('steal-qunit'); + var canReflect = require('can-reflect'); + QUnit.module('can-query-logic with maybe type'); + QUnit.test('basics', function (assert) { + var MaybeNumber = canReflect.assignSymbols({}, { + 'can.new': function (val) { + if (val == null) { + return val; + } + return +val; + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Number, + undefined, + null + ] + }; + } + }); + var todoQueryLogic = new QueryLogic({ keys: { age: MaybeNumber } }); + var unionized = todoQueryLogic.union({ filter: { age: 7 } }, { filter: { age: '07' } }); + assert.deepEqual(unionized, { filter: { age: 7 } }, 'string numbers are converted to numbers'); + }); + QUnit.test('MaybeDate', function (assert) { + function toDate(str) { + var type = typeof str; + if (type === 'string') { + str = Date.parse(str); + return isNaN(str) ? null : new Date(str); + } else if (type === 'number') { + return new Date(str); + } else { + return str; + } + } + function DateStringSet(dateStr) { + this.setValue = dateStr; + var date = toDate(dateStr); + this.value = date == null ? date : date.getTime(); + } + DateStringSet.prototype.valueOf = function () { + return this.value; + }; + canReflect.assignSymbols(DateStringSet.prototype, { + 'can.serialize': function () { + return this.setValue; + } + }); + var MaybeDate = canReflect.assignSymbols({}, { + 'can.new': toDate, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + Date, + undefined, + null + ] + }; + }, + 'can.ComparisonSetType': DateStringSet + }); + var todoQueryLogic = new QueryLogic({ keys: { due: MaybeDate } }); + var store = [ + { + id: 1, + due: null + }, + { + id: 2, + due: new Date(2001, 0, 1).toString() + }, + { + id: 3, + due: new Date(2000, 0, 1).toString() + }, + { + id: 4, + due: null + } + ]; + var results = todoQueryLogic.filterMembers({ sort: 'due' }, store); + assert.deepEqual(results, [ + { + id: 1, + due: null + }, + { + id: 4, + due: null + }, + { + id: 3, + due: new Date(2000, 0, 1).toString() + }, + { + id: 2, + due: new Date(2001, 0, 1).toString() + } + ]); + }); +}); +/*can-query-logic@1.2.2#can-query-logic-test*/ +define('can-query-logic@1.2.2#can-query-logic-test', [ + 'require', + 'exports', + 'module', + './src/set-test', + './src/helpers-test', + './src/types/make-real-number-range-inclusive-test', + './src/types/comparisons-test', + './src/types/and-or-not-test', + './src/types/values-or-test', + './src/types/basic-query-test', + './src/types/basic-query-sorting-test', + './src/types/basic-query-filter-from-test', + './src/types/basic-query-merge-test', + './src/serializers/basic-query-test', + './src/serializers/comparisons-test', + './src/types/make-maybe-test', + './src/types/make-enum-test', + './src/types/values-and-test', + './compat/compat-test', + './test/special-comparison-logic-test', + './test/make-enum-logic-test', + './test/maybe-type-test', + 'steal-qunit', + 'can-query-logic', + 'can-reflect' +], function (require, exports, module) { + require('./src/set-test'); + require('./src/helpers-test'); + require('./src/types/make-real-number-range-inclusive-test'); + require('./src/types/comparisons-test'); + require('./src/types/and-or-not-test'); + require('./src/types/values-or-test'); + require('./src/types/basic-query-test'); + require('./src/types/basic-query-sorting-test'); + require('./src/types/basic-query-filter-from-test'); + require('./src/types/basic-query-merge-test'); + require('./src/serializers/basic-query-test'); + require('./src/serializers/comparisons-test'); + require('./src/types/make-maybe-test'); + require('./src/types/make-enum-test'); + require('./src/types/values-and-test'); + require('./compat/compat-test'); + require('./test/special-comparison-logic-test'); + require('./test/make-enum-logic-test'); + require('./test/maybe-type-test'); + var QUnit = require('steal-qunit'); + var QueryLogic = require('can-query-logic'); + var canReflect = require('can-reflect'); + var algebra = new QueryLogic(); + QUnit.module('can-query-logic'); + QUnit.test('union', function (assert) { + var unionResult = algebra.union({ filter: { name: 'Ramiya' } }, { filter: { name: 'Bohdi' } }); + assert.deepEqual(unionResult, { + filter: { + name: { + $in: [ + 'Ramiya', + 'Bohdi' + ] + } + } + }); + }); + QUnit.test('difference', function (assert) { + var differenceResult = algebra.difference({ + filter: { + name: { + $in: [ + 'Ramiya', + 'Bohdi' + ] + } + } + }, { filter: { name: 'Bohdi' } }); + assert.deepEqual(differenceResult, { filter: { name: 'Ramiya' } }); + }); + QUnit.test('subset', function (assert) { + var subsetResult = algebra.isSubset({ filter: { name: 'Bohdi' } }, { + filter: { + name: { + $in: [ + 'Ramiya', + 'Bohdi' + ] + } + } + }); + assert.deepEqual(subsetResult, true); + }); + QUnit.test('isMember', function (assert) { + var hasResult = algebra.isMember({ filter: { name: 'Bohdi' } }, { name: 'Bohdi' }); + assert.deepEqual(hasResult, true); + }); + QUnit.test('filterMembers basics', function (assert) { + var subset = algebra.filterMembers({ + filter: { + name: { + $in: [ + 'Bohdi', + 'Ramiya' + ] + } + } + }, {}, [ + { name: 'Bohdi' }, + { name: 'Ramiya' }, + { name: 'Payal' }, + { name: 'Justin' } + ]); + assert.deepEqual(subset, [ + { name: 'Bohdi' }, + { name: 'Ramiya' } + ]); + subset = algebra.filterMembers({ + filter: { + name: { + $in: [ + 'Payal', + 'Ramiya', + 'Justin' + ] + } + }, + page: { + start: '1', + end: '2' + } + }, {}, [ + { name: 'Bohdi' }, + { name: 'Ramiya' }, + { name: 'Payal' }, + { name: 'Justin' } + ]); + assert.deepEqual(subset, [ + { name: 'Payal' }, + { name: 'Justin' } + ]); + }); + QUnit.test('unionMembers basics', function (assert) { + var union = algebra.unionMembers({ filter: { name: 'Bohdi' } }, { filter: { name: 'Ramiya' } }, [{ + name: 'Bohdi', + id: 1 + }], [{ + name: 'Ramiya', + id: 2 + }]); + assert.deepEqual(union, [ + { + name: 'Bohdi', + id: 1 + }, + { + name: 'Ramiya', + id: 2 + } + ]); + }); + QUnit.test('count basics', function (assert) { + assert.equal(algebra.count({}), Infinity); + assert.equal(algebra.count({ + page: { + start: 1, + end: 2 + } + }), 2); + }); + QUnit.test('index basics', function (assert) { + var index = algebra.index({ sort: 'name' }, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { name: 'k' }); + assert.equal(index, 2); + index = algebra.index({ sort: '-name' }, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ].reverse(), { name: 'k' }); + assert.equal(index, 2); + index = algebra.index({}, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { + id: 0, + name: 'k' + }); + assert.equal(index, 0); + index = algebra.index({}, [ + { + id: 1, + name: 'g' + }, + { + id: 2, + name: 'j' + }, + { + id: 3, + name: 'm' + }, + { + id: 4, + name: 's' + } + ], { name: 'k' }); + assert.equal(index, undefined, 'no value if no id'); + var TODO_id = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + return { + kind: 'record', + identity: ['_id'], + keys: { + id: Number, + points: Number, + complete: Boolean, + name: String + } + }; + } + }); + var algebra2 = new QueryLogic(TODO_id); + index = algebra2.index({}, [ + { + id: 1, + _id: 0 + }, + { + id: 2, + _id: 1 + }, + { + id: 3, + _id: 3 + }, + { + id: 4, + _id: 4 + } + ], { + id: 0, + _id: 2 + }); + assert.equal(index, 2); + }); + QUnit.test('filterMembers with reverse sort', function (assert) { + var sortedMembers = algebra.filterMembers({ sort: '-name' }, [ + { + id: 1, + name: 'a' + }, + { + id: 2, + name: 'z' + }, + { + id: 3, + name: 'f' + }, + { + id: 4, + name: 's' + } + ]); + assert.deepEqual(sortedMembers, [ + { + id: 2, + name: 'z' + }, + { + id: 4, + name: 's' + }, + { + id: 3, + name: 'f' + }, + { + id: 1, + name: 'a' + } + ]); + }); + QUnit.test('isPaginated, removePagination', function (assert) { + assert.equal(algebra.isPaginated({}), false, 'universe is not paginated'); + assert.equal(algebra.isPaginated({ filter: { foo: 'bar' } }), false, 'filter is not paginated'); + assert.equal(algebra.isPaginated({ sort: 'bar' }), false, 'sort is not paginated'); + assert.equal(algebra.isPaginated({ + page: { + start: 1, + end: 2 + } + }), true, 'page is paginated'); + assert.deepEqual(algebra.removePagination({}), {}, 'removePagination universe'); + assert.deepEqual(algebra.removePagination({ filter: { foo: 'bar' } }), { filter: { foo: 'bar' } }, 'removePagination filter'); + assert.deepEqual(algebra.removePagination({ sort: 'bar' }), { sort: 'bar' }, 'removePagination sort'); + assert.deepEqual(algebra.removePagination({ + page: { + start: 1, + end: 2 + } + }), {}, 'removePagination page'); + }); + QUnit.test('Value returned by makeEnum is constructorLike', function (assert) { + var Status = QueryLogic.makeEnum([ + 'new', + 'preparing', + 'delivery', + 'delivered' + ]); + var pass = canReflect.isConstructorLike(Status); + assert.ok(pass, 'Status is constructor like'); + }); + QUnit.test('can call low-level APIs from the outside', function (assert) { + var gt1 = new QueryLogic.GreaterThan(1); + var lte1 = new QueryLogic.LessThanEqual(1); + assert.equal(QueryLogic.intersection(gt1, lte1), QueryLogic.EMPTY); + var isGtJustinAndGt35 = new QueryLogic.KeysAnd({ + name: new QueryLogic.GreaterThan('Justin'), + age: new QueryLogic.GreaterThan(35) + }); + var isGt25 = new QueryLogic.KeysAnd({ age: new QueryLogic.GreaterThan(25) }); + assert.deepEqual(QueryLogic.union(isGtJustinAndGt35, isGt25), isGt25, 'fewer clauses'); + }); +}); +/*can-value@1.1.2#test/test*/ +define('can-value@1.1.2#test/test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../can-value', + 'can-reflect', + 'can-reflect-dependencies', + 'can-simple-map' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canValue = require('../can-value'); + var canReflect = require('can-reflect'); + var canReflectDeps = require('can-reflect-dependencies'); + var SimpleMap = require('can-simple-map'); + var onlyDevTest = steal.isEnv('production') ? QUnit.skip : QUnit.test; + var supportsFunctionNames = function () { + var fn = function () { + }; + return !!fn.name; + }(); + QUnit.module('can-value'); + QUnit.test('bind method works', function (assert) { + var outer = new SimpleMap({ inner: new SimpleMap({ key: 'hello' }) }); + var observable = canValue.bind(outer, 'inner.key'); + assert.equal(canReflect.getValue(observable), 'hello', 'getting works'); + canReflect.setValue(observable, 'aloha'); + assert.equal(outer.get('inner').get('key'), 'aloha', 'setting works'); + }); + QUnit.test('from method works', function (assert) { + var outer = { inner: { key: 'hello' } }; + var observation = canValue.from(outer, 'inner.key'); + assert.equal(canReflect.getValue(observation), 'hello', 'getting works'); + var errorThrown; + try { + canReflect.setValue(observation, 'aloha'); + } catch (error) { + errorThrown = error; + } + assert.ok(errorThrown instanceof Error, 'setting doesn\u2019t work'); + }); + if (supportsFunctionNames) { + onlyDevTest('from method returns an observation with a helpful name', function (assert) { + var outer = { inner: { key: 'hello' } }; + var observation = canValue.from(outer, 'inner.key'); + assert.equal(canReflect.getName(observation), 'Observation>', 'observation has the correct name'); + }); + } + onlyDevTest('from method observable has dependency data', function (assert) { + var outer = new SimpleMap({ inner: new SimpleMap({ key: 'hello' }) }); + var observation = canValue.from(outer, 'inner.key'); + canReflect.onValue(observation, function () { + }); + var observationDepData = canReflectDeps.getDependencyDataOf(observation); + assert.deepEqual(observationDepData, { + whatChangesMe: { + derive: { + keyDependencies: new Map([ + [ + outer, + new Set(['inner']) + ], + [ + outer.get('inner'), + new Set(['key']) + ] + ]) + } + } + }, 'the observation has the correct mutation dependencies'); + var innerDepData = canReflectDeps.getDependencyDataOf(outer, 'inner'); + assert.deepEqual(innerDepData, { whatIChange: { derive: { valueDependencies: new Set([observation]) } } }, 'outer.inner has the correct mutation dependencies'); + var keyDepData = canReflectDeps.getDependencyDataOf(outer.get('inner'), 'key'); + assert.deepEqual(keyDepData, { whatIChange: { derive: { valueDependencies: new Set([observation]) } } }, 'outer.inner.key has the correct mutation dependencies'); + }); + QUnit.test('with method works', function (assert) { + var observable = canValue.with(15); + assert.equal(canReflect.getValue(observable), 15, 'getting works'); + canReflect.setValue(observable, 22); + assert.equal(canReflect.getValue(observable), 22, 'setting works'); + }); + QUnit.test('returnedBy method works', function (assert) { + var person = new SimpleMap({ + first: 'Grace', + last: 'Murray' + }); + var observable = canValue.returnedBy(function () { + return person.get('first') + ' ' + person.get('last'); + }); + assert.equal(canReflect.getValue(observable), 'Grace Murray', 'getting works'); + person.set('last', 'Hopper'); + assert.equal(canReflect.getValue(observable), 'Grace Hopper', 'setting works'); + }); + QUnit.test('returnedBy(getter(lastSet)) method works', function (assert) { + var person = new SimpleMap({ + first: 'Grace', + last: 'Murray' + }); + var observable = canValue.returnedBy(function (lastSet) { + return person.get('first') + lastSet + person.get('last'); + }, null, ' '); + assert.equal(canReflect.getValue(observable), 'Grace Murray', 'getting works'); + person.set('last', 'Hopper'); + assert.equal(canReflect.getValue(observable), 'Grace Hopper', 'setting dep works'); + observable.value = ' J '; + assert.equal(observable.value, 'Grace J Hopper', 'setting works'); + }); + QUnit.test('to method works', function (assert) { + var outer = { inner: { key: 'hello' } }; + var setProp = canValue.to(outer, 'inner.key'); + assert.equal(canReflect.getValue(setProp), setProp, 'getting the value doesn\u2019t work'); + canReflect.setValue(setProp, 'aloha'); + assert.equal(outer.inner.key, 'aloha', 'setting works'); + }); + onlyDevTest('to method observable has dependency data', function (assert) { + var outer = new SimpleMap({ inner: new SimpleMap({ key: 'hello' }) }); + var observable = canValue.to(outer, 'inner.key'); + canReflect.onValue(observable, function () { + }); + var innerDepData = canReflectDeps.getDependencyDataOf(outer, 'inner'); + assert.notOk(innerDepData, 'outer.inner has no mutation dependencies'); + var keyDepData = canReflectDeps.getDependencyDataOf(outer.get('inner'), 'key'); + assert.deepEqual(keyDepData, { + whatChangesMe: { + mutate: { + keyDependencies: new Map(), + valueDependencies: new Set([observable]) + } + } + }, 'outer.inner.key has the correct mutation dependencies'); + var observableDepData = canReflectDeps.getDependencyDataOf(observable); + assert.deepEqual(observableDepData, { + whatIChange: { + mutate: { + keyDependencies: new Map([[ + outer.get('inner'), + new Set(['key']) + ]]) + } + } + }, 'observable has the correct mutation dependencies'); + }); + QUnit.test('to method observable works when the keys change', function (assert) { + var originalInner = new SimpleMap({ key: 'hello' }); + var outer = new SimpleMap({ inner: originalInner }); + var observable = canValue.to(outer, 'inner.key'); + var newInner = new SimpleMap({ key: 'aloha' }); + outer.set('inner', newInner); + canReflect.setValue(observable, 'ciao'); + assert.equal(newInner.get('key'), 'ciao', 'setting works after changing the inner object'); + assert.equal(originalInner.get('key'), 'hello', 'the original inner object is untouched'); + }); + onlyDevTest('to method observable works when the keys change - dependency data', function (assert) { + var originalInner = new SimpleMap({ key: 'hello' }); + var outer = new SimpleMap({ inner: originalInner }); + var observable = canValue.to(outer, 'inner.key'); + canReflect.onValue(observable, function () { + }); + var newInner = new SimpleMap({ key: 'aloha' }); + outer.set('inner', newInner); + canReflect.setValue(observable, 'ciao'); + var innerDepData = canReflectDeps.getDependencyDataOf(outer, 'inner'); + assert.notOk(innerDepData, 'outer.inner has no mutation dependencies'); + var originalKeyDepData = canReflectDeps.getDependencyDataOf(originalInner, 'key'); + assert.notOk(originalKeyDepData, 'original outer.inner.key no longer has any dependencies'); + var newKeyDepData = canReflectDeps.getDependencyDataOf(newInner, 'key'); + assert.deepEqual(newKeyDepData, { + whatChangesMe: { + mutate: { + keyDependencies: new Map(), + valueDependencies: new Set([observable]) + } + } + }, 'outer.inner.key has the correct mutation dependencies'); + var observableDepData = canReflectDeps.getDependencyDataOf(observable); + assert.deepEqual(observableDepData, { + whatIChange: { + mutate: { + keyDependencies: new Map([[ + newInner, + new Set(['key']) + ]]) + } + } + }, 'observable has the correct mutation dependencies'); + }); +}); +/*can-param@1.1.3#can-param*/ +define('can-param@1.1.3#can-param', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + function buildParam(prefix, obj, add) { + if (Array.isArray(obj)) { + for (var i = 0, l = obj.length; i < l; ++i) { + var inner = obj[i]; + var shouldIncludeIndex = typeof inner === 'object'; + var arrayIndex = shouldIncludeIndex ? '[' + i + ']' : '[]'; + buildParam(prefix + arrayIndex, inner, add); + } + } else if (obj && typeof obj === 'object') { + for (var name in obj) { + buildParam(prefix + '[' + name + ']', obj[name], add); + } + } else { + add(prefix, obj); + } + } + module.exports = namespace.param = function param(object) { + var pairs = [], add = function (key, value) { + pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); + }; + for (var name in object) { + buildParam(name, object[name], add); + } + return pairs.join('&').replace(/%20/g, '+'); + }; +}); +/*can-ajax@2.4.6#can-ajax*/ +define('can-ajax@2.4.6#can-ajax', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-reflect', + 'can-namespace', + 'can-parse-uri', + 'can-param' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var Global = require('can-globals/global/global'); + var canReflect = require('can-reflect'); + var namespace = require('can-namespace'); + var parseURI = require('can-parse-uri'); + var param = require('can-param'); + var xhrs = [ + function () { + return new XMLHttpRequest(); + }, + function () { + return new ActiveXObject('Microsoft.XMLHTTP'); + }, + function () { + return new ActiveXObject('MSXML2.XMLHTTP.3.0'); + }, + function () { + return new ActiveXObject('MSXML2.XMLHTTP'); + } + ], _xhrf = null; + var originUrl = parseURI(Global().location.href); + var globalSettings = {}; + var makeXhr = function () { + if (_xhrf != null) { + return _xhrf(); + } + for (var i = 0, l = xhrs.length; i < l; i++) { + try { + var f = xhrs[i], req = f(); + if (req != null) { + _xhrf = f; + return req; + } + } catch (e) { + continue; + } + } + return function () { + }; + }; + var contentTypes = { + json: 'application/json', + form: 'application/x-www-form-urlencoded' + }; + var _xhrResp = function (xhr, options) { + try { + var type = options.dataType || xhr.getResponseHeader('Content-Type').split(';')[0]; + if (type && (xhr.responseText || xhr.responseXML)) { + switch (type) { + case 'text/xml': + case 'xml': + return xhr.responseXML; + case 'text/json': + case 'application/json': + case 'text/javascript': + case 'application/javascript': + case 'application/x-javascript': + case 'json': + return xhr.responseText && JSON.parse(xhr.responseText); + default: + return xhr.responseText; + } + } else { + return xhr; + } + } catch (e) { + return xhr; + } + }; + function ajax(o) { + var xhr = makeXhr(), timer, n = 0; + var deferred = {}, isFormData; + var promise = new Promise(function (resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); + var requestUrl; + var isAborted = false; + promise.abort = function () { + isAborted = true; + xhr.abort(); + }; + o = [ + { + userAgent: 'XMLHttpRequest', + lang: 'en', + type: 'GET', + data: null, + dataType: 'json' + }, + globalSettings, + o + ].reduce(function (a, b, i) { + return canReflect.assignDeep(a, b); + }); + var async = o.async !== false; + if (!o.contentType) { + o.contentType = o.type.toUpperCase() === 'GET' ? contentTypes.form : contentTypes.json; + } + if (o.crossDomain == null) { + try { + requestUrl = parseURI(o.url); + o.crossDomain = !!(requestUrl.protocol && requestUrl.protocol !== originUrl.protocol || requestUrl.host && requestUrl.host !== originUrl.host); + } catch (e) { + o.crossDomain = true; + } + } + if (o.timeout) { + timer = setTimeout(function () { + xhr.abort(); + if (o.timeoutFn) { + o.timeoutFn(o.url); + } + }, o.timeout); + } + xhr.onreadystatechange = function () { + try { + if (xhr.readyState === 4) { + if (timer) { + clearTimeout(timer); + } + if (xhr.status < 300) { + if (o.success) { + o.success(_xhrResp(xhr, o)); + } + } else if (o.error) { + o.error(xhr, xhr.status, xhr.statusText); + } + if (o.complete) { + o.complete(xhr, xhr.statusText); + } + if (xhr.status >= 200 && xhr.status < 300) { + deferred.resolve(_xhrResp(xhr, o)); + } else { + deferred.reject(_xhrResp(xhr, o)); + } + } else if (o.progress) { + o.progress(++n); + } + } catch (e) { + deferred.reject(e); + } + }; + var url = o.url, data = null, type = o.type.toUpperCase(); + var isJsonContentType = o.contentType === contentTypes.json; + var isPost = type === 'POST' || type === 'PUT'; + if (!isPost && o.data) { + url += '?' + (isJsonContentType ? JSON.stringify(o.data) : param(o.data)); + } + xhr.open(type, url, async); + var isSimpleCors = o.crossDomain && [ + 'GET', + 'POST', + 'HEAD' + ].indexOf(type) !== -1; + isFormData = typeof FormData !== 'undefined' && o.data instanceof FormData; + if (isPost) { + if (isFormData) { + data = o.data; + } else { + if (isJsonContentType && !isSimpleCors) { + data = typeof o.data === 'object' ? JSON.stringify(o.data) : o.data; + xhr.setRequestHeader('Content-Type', 'application/json'); + } else { + data = param(o.data); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + } + } + } else { + xhr.setRequestHeader('Content-Type', o.contentType); + } + if (!isSimpleCors) { + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + } + if (o.xhrFields) { + for (var f in o.xhrFields) { + xhr[f] = o.xhrFields[f]; + } + } + function send() { + if (!isAborted) { + xhr.send(data); + } + } + if (o.beforeSend) { + var result = o.beforeSend.call(o, xhr, o); + if (canReflect.isPromise(result)) { + result.then(send).catch(deferred.reject); + return promise; + } + } + send(); + return promise; + } + module.exports = namespace.ajax = ajax; + module.exports.ajaxSetup = function (o) { + globalSettings = o || {}; + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-make-map@1.2.2#can-make-map*/ +define('can-make-map@1.2.2#can-make-map', function (require, exports, module) { + 'use strict'; + function makeMap(str) { + var obj = {}, items = str.split(','); + items.forEach(function (name) { + obj[name] = true; + }); + return obj; + } + module.exports = makeMap; +}); +/*can-ajax@2.4.6#test/qunit*/ +define('can-ajax@2.4.6#test/qunit', [ + 'require', + 'exports', + 'module', + 'qunit', + 'steal-qunit' +], function (require, exports, module) { + 'use strict'; + var testType = typeof process !== 'undefined' && process.env.TEST; + var isMochaQUnitUI = testType === 'mocha'; + var isQunit = testType === 'qunit'; + if (isMochaQUnitUI) { + QUnit.assert.async = function () { + QUnit.stop(); + return function done(error) { + if (error) { + return QUnit.ok(false, '' + error); + } + QUnit.start(); + }; + }; + QUnit.test = test; + module.exports = QUnit; + } else if (isQunit) { + module.exports = require('qunit'); + } else { + module.exports = require('steal-qunit'); + } +}); +/*can-ajax@2.4.6#test/helpers*/ +define('can-ajax@2.4.6#test/helpers', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getGlobal = require('can-globals/global/global'); + function isProduction() { + var root = getGlobal(); + if (root.System) { + return root.System.env.indexOf('production') !== -1; + } + if (root.process) { + var nodeEnv = root.process.env.NODE_ENV; + return nodeEnv === 'production' || nodeEnv === 'window-production'; + } + return false; + } + function isServer() { + var root = getGlobal(); + var testType = root.process && root.process.env.TEST; + return testType === 'qunit'; + } + module.exports = { + isProduction: isProduction, + isServer: isServer + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-ajax@2.4.6#can-ajax-test*/ +define('can-ajax@2.4.6#can-ajax-test', [ + 'require', + 'exports', + 'module', + './can-ajax', + 'can-namespace', + 'can-make-map', + 'can-globals/global/global', + 'can-parse-uri', + './test/qunit', + './test/helpers' +], function (require, exports, module) { + (function (global, __dirname, require, exports, module) { + var ajax = require('./can-ajax'); + var namespace = require('can-namespace'); + var makeMap = require('can-make-map'); + var GLOBAL = require('can-globals/global/global'); + var parseURI = require('can-parse-uri'); + var QUnit = require('./test/qunit'); + var helpers = require('./test/helpers'); + var isMainCanTest = typeof System === 'object' && System.env !== 'canjs-test'; + var hasLocalServer = !helpers.isServer() && !helpers.isProduction(); + QUnit.module('can-ajax'); + var makeFixture = function (XHR) { + var oldXhr = window.XMLHttpRequest || window.ActiveXObject; + if (window.XMLHttpRequest) { + window.XMLHttpRequest = XHR; + } else if (window.ActiveXObject) { + window.ActiveXObject = XHR; + } + return function restoreXHR() { + if (window.XMLHttpRequest) { + window.XMLHttpRequest = oldXhr; + } else if (window.ActiveXObject) { + window.ActiveXObject = oldXhr; + } + }; + }; + var makePredicateContains = function (str) { + var obj = makeMap(str); + return function (val) { + return obj[val]; + }; + }; + if (hasLocalServer) { + QUnit.test('basic get request', function (assert) { + var done = assert.async(); + ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.json' + }).then(function (resp) { + assert.equal(resp.message, 'VALUE'); + done(); + }); + }); + QUnit.test('synchronous get request', function (assert) { + var done = assert.async(); + var ok = true; + ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.json', + async: false, + success: function () { + assert.ok(ok, 'Callback happens before returning.'); + } + }).then(function () { + assert.ok(!ok, 'Promise resolves after returning'); + done(); + }); + ok = false; + }); + } + QUnit.test('added to namespace (#99)', function (assert) { + assert.equal(namespace.ajax, ajax); + }); + if (hasLocalServer) { + QUnit.test('GET requests with dataType parse JSON (#106)', function (assert) { + var done = assert.async(); + ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.txt', + dataType: 'json' + }).then(function (resp) { + assert.equal(resp.message, 'VALUE'); + done(); + }); + }); + } + QUnit.test('ignores case of type parameter for a post request (#100)', function (assert) { + var done = assert.async(); + var requestHeaders = { CONTENT_TYPE: 'Content-Type' }, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 200; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === requestHeaders.CONTENT_TYPE) { + var o = {}; + o[header] = value; + this.responseText = JSON.stringify(o); + } + }; + }); + ajax({ + type: 'post', + url: 'http://anotherdomain.com/foo', + data: { bar: 'qux' } + }).then(function (value) { + assert.equal(value[requestHeaders.CONTENT_TYPE], 'application/x-www-form-urlencoded'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('url encodes GET requests when no contentType', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + ajax({ + type: 'get', + url: 'http://anotherdomain.com/foo', + data: { foo: 'bar' } + }).then(function (value) { + assert.equal(value['Content-Type'], 'application/x-www-form-urlencoded'); + assert.equal(value.data, undefined, 'No data provided because it\'s a GET'); + assert.equal(value.url, 'http://anotherdomain.com/foo?foo=bar'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('Stringifies GET requests when contentType=application/json', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + ajax({ + type: 'get', + url: 'http://anotherdomain.com/foo', + data: { foo: 'bar' }, + contentType: 'application/json' + }).then(function (value) { + assert.equal(value['Content-Type'], 'application/json'); + assert.equal(value.data, undefined, 'No data provided because it\'s a GET'); + assert.equal(value.url, 'http://anotherdomain.com/foo?{"foo":"bar"}'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('Stringifies POST requests when there is no contentType', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + var origin = parseURI(GLOBAL().location.href); + var url = origin.protocol + origin.authority + '/foo'; + ajax({ + type: 'post', + url: url, + data: { foo: 'bar' } + }).then(function (value) { + assert.equal(value['Content-Type'], 'application/json'); + assert.equal(value.data, '{"foo":"bar"}', 'Data was stringified'); + assert.equal(value.url, url); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('url encodes POST requests when contentType=application/x-www-form-urlencoded', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + ajax({ + type: 'post', + url: 'http://anotherdomain.com/foo', + data: { foo: 'bar' }, + contentType: 'application/x-www-form-urlencoded' + }).then(function (value) { + assert.equal(value['Content-Type'], 'application/x-www-form-urlencoded'); + assert.equal(value.data, 'foo=bar', 'Data was url encoded'); + assert.equal(value.url, 'http://anotherdomain.com/foo'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + if (typeof XDomainRequest === 'undefined') { + QUnit.test('cross domain post request should change data to form data (#90)', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 204; + this.responseText = ''; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'POST', + url: 'https://httpbin.org/post', + data: { 'message': 'VALUE' }, + dataType: 'application/json' + }).then(function (resp) { + assert.deepEqual(headers, { 'Content-Type': 'application/x-www-form-urlencoded' }); + restore(); + done(); + }); + }); + QUnit.test('GET CORS should be a simple request - without a preflight (#187)', function (assert) { + var done = assert.async(); + var isSimpleRequest = true, restore; + var isSimpleMethod = makePredicateContains('GET,POST,HEAD'); + var isSimpleHeader = makePredicateContains('Accept,Accept-Language,Content-Language,Content-Type,DPR,Downlink,Save-Data,Viewport-Width,Width'); + var isSimpleContentType = makePredicateContains('application/x-www-form-urlencoded,multipart/form-data,text/plain'); + restore = makeFixture(function () { + this.open = function (type, url) { + if (!isSimpleMethod(type)) { + isSimpleRequest = false; + } + }; + var response = {}; + this.send = function () { + this.responseText = JSON.stringify(response); + this.readyState = 4; + this.status = 200; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type' && !isSimpleContentType(value)) { + isSimpleRequest = false; + } + if (isSimpleRequest && !isSimpleHeader(header)) { + isSimpleRequest = false; + } + response[header] = value; + }; + }); + ajax({ + url: 'http://query.yahooapis.com/v1/public/yql', + data: { + q: 'select * from geo.places where text="sunnyvale, ca"', + format: 'json' + } + }).then(function (response) { + assert.ok(isSimpleRequest, 'CORS GET is simple'); + restore(); + done(); + }, function (err) { + assert.ok(false, 'Should be resolved'); + restore(); + done(); + }); + }); + } + if (isMainCanTest && hasLocalServer) { + QUnit.test('abort', function (assert) { + var done = assert.async(); + var promise = ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.json' + }); + promise.catch(function (xhr) { + if (xhr instanceof Error) { + assert.equal(xhr.message, 'Could not complete the operation due to error c00c023f.'); + done(); + } else { + setTimeout(function () { + assert.equal(xhr.readyState, 0, 'aborts the promise'); + done(); + }, 50); + } + }); + promise.abort(); + }); + } + QUnit.test('crossDomain is true for relative requests', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify({ great: 'success' }); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'post', + url: '/foo', + data: { bar: 'qux' }, + dataType: 'json' + }).then(function (value) { + assert.deepEqual(headers, { + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest' + }); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('handles 204 No Content responses when expecting JSON', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 204; + this.responseText = ''; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'delete', + url: '/foo', + data: { id: 'qux' }, + dataType: 'json' + }).then(function () { + assert.deepEqual(headers, { + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest' + }); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('handles responseText containing text when expecting JSON (#46)', function (assert) { + var done = assert.async(); + var NOT_FOUND_CODE = 404; + var NOT_FOUND_MSG = 'NOT FOUND'; + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = NOT_FOUND_CODE; + this.responseText = NOT_FOUND_MSG; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'get', + url: '/foo', + dataType: 'json' + }).then(function (value) { + assert.notOk(value, 'success callback call not expected'); + }, function (xhr) { + assert.equal(xhr.status, 404); + assert.equal(xhr.responseText, NOT_FOUND_MSG); + }).then(function () { + restore(); + done(); + }); + }); + if (hasLocalServer) { + QUnit.test('correctly serializes null and undefined values (#177)', function (assert) { + var done = assert.async(); + ajax({ + type: 'get', + url: __dirname + '/can-ajax-test-result.txt', + data: { foo: null } + }).then(function (resp) { + assert.equal(resp.message, 'VALUE'); + done(); + }); + }); + } + QUnit.test('It doesn\'t stringify FormData', function (assert) { + var done = assert.async(); + var formData = new FormData(); + formData.append('foo', 'bar'); + var restore = makeFixture(function () { + var o = {}; + this.open = function (type, url) { + o.url = url; + }; + this.send = function (data) { + o.data = data; + this.readyState = 4; + this.status = 200; + this.responseText = JSON.stringify(o); + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + if (header === 'Content-Type') { + o[header] = value; + } + }; + }); + var origin = parseURI(GLOBAL().location.href); + var url = origin.protocol + origin.authority + '/foo'; + ajax({ + type: 'post', + url: url, + data: formData + }).then(function (value) { + assert.equal(value.url, url); + assert.equal(typeof value['Content-Type'], 'undefined', 'Content-Type should not be set'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('abort', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var aborted = false; + this.open = function (type, url) { + }; + this.setRequestHeader = function (header, value) { + }; + this.send = function () { + }; + this.abort = function () { + assert.ok(true, 'called the underlying XHR.abort'); + restore(); + done(); + }; + }); + var request = ajax({ url: '/foo' }); + request.abort(); + }); + QUnit.test('abort prevents sending if beforeSend is not finished', function (assert) { + var done = assert.async(); + var restore = makeFixture(function () { + var aborted = false; + this.open = function (type, url) { + }; + this.setRequestHeader = function (header, value) { + }; + this.abort = function () { + assert.ok(true, 'XHR abort was called'); + }; + this.send = function () { + assert.notOk(true, 'should not have been called'); + }; + }); + var request = ajax({ + url: '/foo', + beforeSend: function (xhr) { + return new Promise(function (resolve) { + setTimeout(resolve, 1); + }); + } + }); + request.abort(); + setTimeout(function () { + restore(); + done(); + }, 10); + }); + QUnit.test('beforeSend', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 204; + this.responseText = ''; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'post', + url: '/foo', + data: { id: 'qux' }, + dataType: 'json', + xhrFields: { 'CustomHeader': 'CustomValue' }, + beforeSend: function (xhr) { + assert.ok(xhr.hasOwnProperty('CustomHeader'), 'xhrField header set'); + xhr.setRequestHeader('Authorization', 'Bearer 123'); + } + }).then(function (value) { + assert.ok(headers.hasOwnProperty('Authorization'), 'authorization header set'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('beforeSend async', function (assert) { + var done = assert.async(); + var headers = {}; + var restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + this.readyState = 4; + this.status = 204; + this.responseText = ''; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + url: '/foo', + beforeSend: function (xhr) { + return new Promise(function (resolve) { + setTimeout(function () { + xhr.setRequestHeader('Authorization', 'Bearer 123'); + resolve(); + }, 1); + }); + } + }).then(function (value) { + assert.ok(headers.hasOwnProperty('Authorization'), 'authorization header set'); + }, function (reason) { + assert.notOk(reason, 'request failed with reason = ', reason); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('beforeSend rejects the ajax promise on failure', function (assert) { + var done = assert.async(); + var error = new Error(); + var restore = makeFixture(function () { + this.open = function (type, url) { + }; + this.send = function () { + assert.notOk(true, 'Should not be called'); + }; + this.setRequestHeader = function (header, value) { + }; + }); + ajax({ + url: '/foo', + beforeSend: function (xhr) { + return new Promise(function (resolve, reject) { + setTimeout(function () { + reject(error); + }, 1); + }); + } + }).then(function (value) { + assert.notOk(true, 'request should have rejected'); + }, function (reason) { + assert.ok(true, 'request rejected'); + assert.equal(reason, error, 'error is what we expect'); + }).then(function () { + restore(); + done(); + }); + }); + QUnit.test('async should be always true #51', function (assert) { + var done = assert.async(); + var headers = {}, restore = makeFixture(function () { + this.open = function (type, url, async) { + assert.ok(async); + }; + this.send = function () { + this.readyState = 4; + this.status = 204; + this.responseText = ''; + this.onreadystatechange(); + }; + this.setRequestHeader = function (header, value) { + headers[header] = value; + }; + }); + ajax({ + type: 'get', + url: '/ep' + }).then(function () { + restore(); + done(); + }); + }); + }(function () { + return this; + }(), '/', require, exports, module)); +}); +/*can-assign@1.3.3#can-assign-test*/ +define('can-assign@1.3.3#can-assign-test', [ + 'require', + 'exports', + 'module', + './can-assign', + 'steal-qunit' +], function (require, exports, module) { + var assign = require('./can-assign'); + var QUnit = require('steal-qunit'); + QUnit.module('can-assign'); + QUnit.test('Assign all properties to an object', function (assert) { + var a = { + a: 1, + b: 2, + d: 3 + }; + var b = { + a: 1, + b: 3, + c: 2 + }; + var expected = { + a: 1, + b: 3, + c: 2, + d: 3 + }; + var actual = assign(a, b); + for (var prop in actual) { + assert.equal(expected[prop], actual[prop]); + } + }); + QUnit.test('Works with readonly properties', function (assert) { + var obj = {}; + Object.defineProperty(obj, 'a', { + value: 'a', + writable: false + }); + Object.defineProperty(obj, 'b', { + value: 'b', + writable: true + }); + Object.defineProperty(obj, 'c', { + get: function () { + return 'c'; + }, + set: function (value) { + this.b = value; + }, + configurable: true + }); + try { + assign(obj, { + a: 'c', + b: 'f', + d: 'd' + }); + assert.equal(obj.a, 'a'); + assert.equal(obj.b, 'f'); + assert.equal(obj.c, 'c'); + assert.equal(obj.d, 'd'); + assign(obj, { c: 'h' }); + assert.equal(obj.a, 'a'); + assert.equal(obj.b, 'h'); + assert.equal(obj.c, 'c'); + assert.equal(obj.d, 'd'); + } catch (err) { + assert.ok(false, err); + } + }); +}); +/*can-bind@1.5.1#test/helpers*/ +define('can-bind@1.5.1#test/helpers', function (require, exports, module) { + function incrementByOne(newValue) { + return newValue + 1; + } + function protectAgainstInfiniteLoops(func) { + var counter = 0; + return function () { + counter += 1; + if (counter > 10) { + throw new Error('Infinite loop'); + } + return func.apply(null, arguments); + }; + } + module.exports = { + incrementByOne: incrementByOne, + protectAgainstInfiniteLoops: protectAgainstInfiniteLoops, + moduleHooks: { + setup: function () { + this.groupCollapsed = console.groupCollapsed; + if (this.groupCollapsed) { + console.groupCollapsed = null; + } + }, + teardown: function () { + if (this.groupCollapsed) { + console.groupCollapsed = this.groupCollapsed; + } + } + } + }; +}); +/*can-bind@1.5.1#test/core*/ +define('can-bind@1.5.1#test/core', [ + 'require', + 'exports', + 'module', + '../can-bind', + 'can-reflect', + 'can-reflect-dependencies', + 'can-test-helpers', + './helpers', + 'can-observation', + 'steal-qunit', + 'can-simple-observable/settable/settable', + 'can-simple-map', + 'can-simple-observable', + 'can-queues' +], function (require, exports, module) { + var Bind = require('../can-bind'); + var canReflect = require('can-reflect'); + var canReflectDeps = require('can-reflect-dependencies'); + var canTestHelpers = require('can-test-helpers'); + var helpers = require('./helpers'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + var queues = require('can-queues'); + QUnit.module('can-bind core', helpers.moduleHooks); + QUnit.test('one-way binding to child', function (assert) { + var parentValue = new SimpleObservable(0); + var parent = new Observation(function () { + return parentValue.get(); + }); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + parentValue.set(15); + assert.equal(canReflect.getValue(child), 15, 'child updates'); + child.set(22); + assert.equal(canReflect.getValue(parent), 15, 'parent does not update'); + binding.stop(); + parentValue.set(45); + assert.equal(canReflect.getValue(child), 22, 'parent listener correctly turned off'); + }); + canTestHelpers.dev.devOnlyTest('one-way binding to child - dependency data', function (assert) { + var parentValue = new SimpleObservable(0); + var parent = new Observation(function () { + return parentValue.get(); + }); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + var childDepData = canReflectDeps.getDependencyDataOf(child); + var valueDependencies = new Set(); + valueDependencies.add(parent); + assert.deepEqual(childDepData, { whatChangesMe: { mutate: { valueDependencies: valueDependencies } } }, 'child observable has the correct mutation dependencies'); + var parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.deepEqual(parentDepData, { + whatChangesMe: { derive: { valueDependencies: new Set([parentValue]) } }, + whatIChange: { mutate: { valueDependencies: new Set([child]) } } + }, 'parent observable has the correct mutation dependencies'); + binding.stop(); + childDepData = canReflectDeps.getDependencyDataOf(child); + assert.equal(childDepData, undefined, 'child observable has no mutation dependencies after stop()'); + parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.equal(parentDepData, undefined, 'parent observable has no mutation dependencies after stop()'); + }); + QUnit.test('one-way binding to parent', function (assert) { + var parent = new SimpleObservable(0); + var childValue = new SimpleObservable(0); + var child = new Observation(function () { + return childValue.get(); + }); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + parent.set(15); + assert.equal(canReflect.getValue(child), 0, 'child does not update'); + childValue.set(22); + assert.equal(canReflect.getValue(parent), 22, 'parent updates'); + binding.stop(); + childValue.set(58); + assert.equal(canReflect.getValue(parent), 22, 'child listener correctly turned off'); + }); + canTestHelpers.dev.devOnlyTest('one-way binding to parent - dependency data', function (assert) { + var parent = new SimpleObservable(0); + var childValue = new SimpleObservable(0); + var child = new Observation(function () { + return childValue.get(); + }); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + var childDepData = canReflectDeps.getDependencyDataOf(child); + assert.deepEqual(childDepData, { + whatChangesMe: { derive: { valueDependencies: new Set([childValue]) } }, + whatIChange: { mutate: { valueDependencies: new Set([parent]) } } + }, 'child observable has the correct mutation dependencies'); + var parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.deepEqual(parentDepData, { whatChangesMe: { mutate: { valueDependencies: new Set([child]) } } }, 'parent observable has the correct mutation dependencies'); + binding.stop(); + childDepData = canReflectDeps.getDependencyDataOf(child); + assert.equal(childDepData, undefined, 'child observable has no mutation dependencies after stop()'); + parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.equal(parentDepData, undefined, 'parent observable has no mutation dependencies after stop()'); + }); + QUnit.test('basic two-way binding', function (assert) { + var parent = new SimpleObservable(0); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + parent.set(15); + assert.equal(canReflect.getValue(child), 15, 'child updates'); + child.set(22); + assert.equal(canReflect.getValue(parent), 22, 'parent updates'); + assert.equal(child.handlers.get([]).length, 1, '1 child listener before calling stop()'); + assert.equal(parent.handlers.get([]).length, 1, '1 parent listener before calling stop()'); + binding.stop(); + assert.equal(child.handlers.get([]).length, 0, '0 child listeners after calling stop()'); + assert.equal(parent.handlers.get([]).length, 0, '0 parent listeners after calling stop()'); + parent.set(45); + assert.equal(canReflect.getValue(child), 22, 'parent listener correctly turned off'); + child.set(58); + assert.equal(canReflect.getValue(parent), 45, 'child listener correctly turned off'); + }); + canTestHelpers.dev.devOnlyTest('basic two-way binding - dependency data', function (assert) { + var parent = new SimpleObservable(0); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + var childDepData = canReflectDeps.getDependencyDataOf(child); + assert.deepEqual(childDepData, { + whatChangesMe: { mutate: { valueDependencies: new Set([parent]) } }, + whatIChange: { mutate: { valueDependencies: new Set([parent]) } } + }, 'child observable has the correct mutation dependencies'); + var parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.deepEqual(parentDepData, { + whatChangesMe: { mutate: { valueDependencies: new Set([child]) } }, + whatIChange: { mutate: { valueDependencies: new Set([child]) } } + }, 'parent observable has the correct mutation dependencies'); + binding.stop(); + childDepData = canReflectDeps.getDependencyDataOf(child); + assert.equal(childDepData, undefined, 'child observable has no mutation dependencies after stop()'); + parentDepData = canReflectDeps.getDependencyDataOf(parent); + assert.equal(parentDepData, undefined, 'parent observable has no mutation dependencies after stop()'); + }); + canTestHelpers.dev.devOnlyTest('updateChildName and updateParentName options', function (assert) { + var parent = new SimpleObservable(0); + var child = new SimpleObservable(0); + var binding = new Bind({ + child: child, + parent: parent, + updateChildName: 'custom child name', + updateParentName: 'custom parent name' + }); + assert.equal(binding._updateChild.name, 'custom child name', 'child name is correct'); + assert.equal(binding._updateParent.name, 'custom parent name', 'parent name is correct'); + }); + QUnit.test('two-way binding with both values undefined', function (assert) { + var child = new SimpleObservable(undefined); + var parent = new SimpleObservable(undefined); + var setChildWasCalled = false; + var binding = new Bind({ + child: child, + parent: parent, + setChild: function () { + setChildWasCalled = true; + } + }); + binding.start(); + assert.equal(setChildWasCalled, true, 'setChild was called'); + binding.stop(); + }); + QUnit.test('two-way binding updates are ignored after calling stop()', function (assert) { + var child = new SimpleObservable(15); + var parent = new SimpleObservable(15); + var binding = new Bind({ + child: child, + parent: parent + }); + var turnOffBinding = function () { + binding.stop(); + }; + canReflect.onValue(parent, turnOffBinding, 'domUI'); + binding.start(); + parent.set(undefined); + assert.equal(canReflect.getValue(child), 15, 'child stays the same'); + assert.equal(canReflect.getValue(parent), undefined, 'parent stays the same'); + canReflect.offValue(parent, turnOffBinding, 'domUI'); + }); + QUnit.test('parentValue property', function (assert) { + var parent = new SimpleObservable(15); + var child = new SimpleObservable(22); + var binding = new Bind({ + child: child, + parent: parent, + priority: 15 + }); + assert.equal(binding.parentValue, 15, 'can get parentValue'); + }); + QUnit.test('priority option', function (assert) { + var parent = new SettableObservable(helpers.incrementByOne, null, 0); + var child = new SettableObservable(helpers.incrementByOne, null, 0); + new Bind({ + child: child, + parent: parent, + priority: 15 + }); + assert.equal(canReflect.getPriority(child), 15, 'child priority set'); + assert.equal(canReflect.getPriority(parent), 15, 'parent priority set'); + }); + QUnit.test('setChild and setParent options', function (assert) { + var parent = new SimpleObservable(undefined); + var map = new SimpleMap({ prop: 'value' }); + var child = new Observation(function () { + return map.serialize(); + }); + var binding = new Bind({ + child: child, + parent: parent, + setChild: function (newValue) { + var split = newValue.split('='); + var objectValue = {}; + objectValue[split[0]] = split[1]; + map.set(objectValue); + }, + setParent: function (newValue) { + parent.set('prop=' + newValue.prop); + } + }); + binding.start(); + parent.set('prop=15'); + assert.deepEqual(canReflect.getValue(child), { prop: '15' }, 'child updates'); + map.set({ prop: 22 }); + assert.equal(canReflect.getValue(parent), 'prop=22', 'parent updates'); + binding.stop(); + parent.set('prop=45'); + assert.deepEqual(canReflect.getValue(child), { prop: 22 }, 'parent listener correctly turned off'); + }); + QUnit.test('use onEmit if observable has Symbol(\'can.onEmit\')', function (assert) { + var child = new SimpleObservable(5); + var parent = new SimpleObservable(1); + var childOffEmitCalled = false; + var childOnEmitCalled = false; + var setParentWasCalled = false; + var childEmitFn = null; + canReflect.assignSymbols(child, { + 'can.onEmit': function (updateFn) { + childOnEmitCalled = true; + childEmitFn = updateFn; + }, + 'can.offEmit': function () { + childOffEmitCalled = true; + }, + 'can.onValue': null + }); + var binding = new Bind({ + child: child, + parent: parent, + onInitDoNotUpdateParent: true, + childToParent: true, + parentToChild: false, + setParent: function (newValue) { + setParentWasCalled = true; + parent.set(newValue); + } + }); + binding.start(); + assert.equal(canReflect.getValue(parent), 1, 'has correct initial value'); + childEmitFn(5); + assert.equal(canReflect.getValue(parent), 5, 'has emitted value'); + assert.equal(childOnEmitCalled, true, 'onEmit was fired'); + assert.equal(setParentWasCalled, true, 'parent was updated'); + binding.stop(); + assert.equal(childOffEmitCalled, true, 'offEmit was fired'); + }); + if (queues.domQueue) { + QUnit.test('able to queue changes in dom queue', function (assert) { + var child = new SimpleObservable(5); + var parent = new SimpleObservable(1); + var element = document.createElement('div'); + var binding = new Bind({ + child: child, + parent: parent, + element: element, + queue: 'dom' + }); + binding.start(); + assert.equal(child.value, 1, 'updated child'); + }); + } +}); +/*can-bind@1.5.1#test/cycles-and-sticky*/ +define('can-bind@1.5.1#test/cycles-and-sticky', [ + 'require', + 'exports', + 'module', + '../can-bind', + 'can-reflect', + 'can-test-helpers', + './helpers', + 'steal-qunit', + 'can-simple-observable/settable/settable', + 'can-simple-observable' +], function (require, exports, module) { + var Bind = require('../can-bind'); + var canReflect = require('can-reflect'); + var canTestHelpers = require('can-test-helpers'); + var helpers = require('./helpers'); + var QUnit = require('steal-qunit'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var SimpleObservable = require('can-simple-observable'); + QUnit.module('can-bind cycles and sticky', helpers.moduleHooks); + QUnit.test('two-way binding with childSticksToParent', function (assert) { + var child = new SimpleObservable(0); + var parent = new SimpleObservable(0); + canReflect.assignSymbols(parent, { + 'can.setValue': function (newVal) { + if (newVal !== undefined) { + this.set(newVal); + } + } + }); + var binding = new Bind({ + child: child, + parent: parent, + sticky: 'childSticksToParent' + }); + binding.start(); + child.set(15); + assert.equal(canReflect.getValue(child), 15, 'child updates'); + assert.equal(canReflect.getValue(parent), 15, 'parent updates'); + child.set(undefined); + assert.equal(canReflect.getValue(child), 15, 'child stays the same'); + assert.equal(canReflect.getValue(parent), 15, 'parent stays the same'); + binding.stop(); + }); + function cycleStickyTest(options, assert) { + var child = options.child; + var cycles = options.cycles; + var expectedChild = options.expectedChild; + var expectedParent = options.expectedParent; + var parent = options.parent; + var sticky = options.sticky; + var debugName = options.debugName; + var binding = new Bind({ + child: child, + cycles: cycles, + onInitDoNotUpdateChild: true, + parent: parent, + sticky: sticky, + debugName: debugName + }); + binding.start(); + if (options.startBySetting === 'child') { + child.set(1); + } else if (options.startBySetting === 'parent') { + parent.set(1); + } else { + throw new Error('No startBySetting option given'); + } + assert.equal(canReflect.getValue(parent), expectedParent, 'parent updates'); + assert.equal(canReflect.getValue(child), expectedChild, 'child updates'); + binding.stop(); + } + QUnit.test('cyclical two-way binding - 0 cycles not sticky', function (assert) { + cycleStickyTest({ + parent: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + child: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + cycles: 0, + sticky: null, + startBySetting: 'parent', + expectedParent: 2, + expectedChild: 3 + }, assert); + }); + canTestHelpers.dev.devOnlyTest('cyclical two-way binding - 0 cycles not sticky - warning in dev', function (assert) { + var warningRegex = /Printing mutation history: 3 2/; + var teardown = canTestHelpers.dev.willWarn(warningRegex); + var parentSet = helpers.protectAgainstInfiniteLoops(helpers.incrementByOne); + Object.defineProperty(parentSet, 'name', { + value: 'PARENT', + configurable: true + }); + var parent = new SettableObservable(parentSet, null, 0); + var childSet = helpers.protectAgainstInfiniteLoops(helpers.incrementByOne); + Object.defineProperty(childSet, 'name', { + value: 'CHILD', + configurable: true + }); + var child = new SettableObservable(childSet, null, 0); + cycleStickyTest({ + parent: parent, + child: child, + startBySetting: 'parent', + expectedParent: 2, + expectedChild: 3 + }, assert); + assert.equal(teardown(), 1, 'warning shown'); + }); + QUnit.test('cyclical two-way binding - 1 cycle not sticky', function (assert) { + cycleStickyTest({ + parent: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + child: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + cycles: 1, + sticky: null, + startBySetting: 'parent', + expectedParent: 4, + expectedChild: 5 + }, assert); + }); + QUnit.test('cyclical two-way binding - 2 cycles not sticky', function (assert) { + cycleStickyTest({ + parent: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + child: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, 0), + cycles: 2, + sticky: null, + startBySetting: 'parent', + expectedParent: 6, + expectedChild: 7 + }, assert); + }); + QUnit.test('two-way binding - 0 cycles childSticksToParent', function (assert) { + cycleStickyTest({ + parent: new SettableObservable(helpers.protectAgainstInfiniteLoops(helpers.incrementByOne), null, -1), + child: new SimpleObservable(0), + cycles: 0, + sticky: 'childSticksToParent', + startBySetting: 'child', + expectedParent: 2, + expectedChild: 2 + }, assert); + }); + canTestHelpers.dev.devOnlyTest('warn when changing the value of a sticky binding child-side', function (assert) { + assert.expect(8); + var msg = /.* changing or converting its value when set.*/; + var teardown = canTestHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'Correct warning generated'); + } + }); + var parent = new SimpleObservable(1); + var child = new SettableObservable(helpers.protectAgainstInfiniteLoops(function () { + return 0; + }), 0); + canReflect.setName(child.observation.func, 'Test Child Observable'); + cycleStickyTest({ + parent: parent, + child: child, + startBySetting: 'parent', + sticky: 'childSticksToParent', + expectedParent: 1, + expectedChild: 0 + }, assert); + assert.equal(teardown(), 1, 'Warning generated only once'); + var shortName = 'The test binding'; + teardown = canTestHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'Correct warning generated'); + } + }); + cycleStickyTest({ + parent: parent, + child: child, + startBySetting: 'parent', + sticky: 'childSticksToParent', + expectedParent: 1, + expectedChild: 0, + debugName: shortName + }, assert); + assert.equal(teardown(), 1, 'Warning generated only once'); + }); +}); +/*can-bind@1.5.1#test/detection*/ +define('can-bind@1.5.1#test/detection', [ + 'require', + 'exports', + 'module', + '../can-bind', + 'steal-qunit', + 'can-simple-map', + 'can-simple-observable', + 'can-value' +], function (require, exports, module) { + var Bind = require('../can-bind'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + var value = require('can-value'); + QUnit.module('can-bind binding detection'); + QUnit.test('child-to-parent without child setter', function (assert) { + var parent = new SimpleObservable(undefined); + var map = new SimpleMap({ prop: 'value' }); + var child = value.from(map, 'prop'); + var binding = new Bind({ + child: child, + parent: parent + }); + assert.equal(binding._childToParent, true, 'child -> parent detection'); + assert.equal(binding._parentToChild, false, 'parent -> child detection'); + }); + QUnit.test('child-to-parent without parent getter', function (assert) { + var child = new SimpleObservable(undefined); + var map = new SimpleMap({ prop: 'value' }); + var parent = value.to(map, 'prop'); + var binding = new Bind({ + child: child, + parent: parent + }); + assert.equal(binding._childToParent, true, 'child -> parent detection'); + assert.equal(binding._parentToChild, false, 'parent -> child detection'); + }); + QUnit.test('error thrown for no-way binding', function (assert) { + var child = value.from(new SimpleMap({ prop: 'value' }), 'prop'); + var parent = value.from(new SimpleMap({ prop: 'value' }), 'prop'); + assert.throws(function () { + new Bind({ + child: child, + parent: parent + }); + }, /binding/, 'error thrown'); + }); +}); +/*can-bind@1.5.1#test/initialization*/ +define('can-bind@1.5.1#test/initialization', [ + 'require', + 'exports', + 'module', + '../can-bind', + 'can-reflect', + 'steal-qunit', + 'can-simple-observable/settable/settable', + 'can-simple-observable' +], function (require, exports, module) { + var Bind = require('../can-bind'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + var SettableObservable = require('can-simple-observable/settable/settable'); + var SimpleObservable = require('can-simple-observable'); + QUnit.module('can-bind initialization'); + QUnit.test('undefined child and defined parent with setter', function (assert) { + var child = new SimpleObservable(undefined); + var parentSetterWasCalled = false; + var parent = new SimpleObservable(15); + canReflect.assignSymbols(parent, { + 'can.setValue': function () { + parentSetterWasCalled = true; + } + }); + var binding = new Bind({ + child: child, + parent: parent + }); + binding.start(); + assert.equal(parentSetterWasCalled, false, 'parent setter was not called'); + binding.stop(); + }); + QUnit.test('undefined parent and null child with setter', function (assert) { + var parent = new SimpleObservable(undefined); + var child = new SettableObservable(function (newValue) { + return newValue || ''; + }, null, null); + var binding = new Bind({ + child: child, + cycles: 0, + parent: parent, + sticky: 'childSticksToParent' + }); + binding.start(); + assert.equal(canReflect.getValue(child), '', 'child value is correct'); + binding.stop(); + }); + function initializationTest(options, assert) { + var child = new SimpleObservable(options.startingChild); + var parent = new SimpleObservable(options.startingParent); + var binding = new Bind({ + child: child, + childToParent: options.childToParent, + onInitDoNotUpdateChild: options.onInitDoNotUpdateChild, + onInitDoNotUpdateParent: options.onInitDoNotUpdateParent, + onInitSetUndefinedParentIfChildIsDefined: options.onInitSetUndefinedParentIfChildIsDefined, + parent: parent, + parentToChild: options.parentToChild + }); + binding.start(); + assert.equal(canReflect.getValue(child), options.expectedChild, 'child value is correct'); + assert.equal(canReflect.getValue(parent), options.expectedParent, 'parent value is correct'); + binding.stop(); + } + QUnit.test('child=1 <-> parent=2 => child=2 parent=2', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=1 <-> parent=undefined => child=1 parent=1', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }, assert); + }); + QUnit.test('child=undefined <-> parent=2 => child=2 parent=2', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=undefined <-> parent=undefined => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 <-> parent=3 => child=3 parent=3', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('child=1 -> parent=2 => child=1 parent=1', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }, assert); + }); + QUnit.test('child=1 -> parent=undefined => child=1 parent=1', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitDoNotUpdateParent: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }, assert); + }); + QUnit.test('child=1 -> parent=undefined => child=1 parent=undefined', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitDoNotUpdateParent: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=undefined -> parent=2 => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=undefined -> parent=undefined => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 -> parent=3 => child=3 parent=3', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: true, + parentToChild: false, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('child=1 <- parent=2 => child=2 parent=2', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=1 <- parent=undefined => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=undefined <- parent=2 => child=2 parent=2', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 2, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=undefined <- parent=undefined => child=undefined parent=undefined', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 <- parent=3 => child=3 parent=3', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: false, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('child=1 <-> parent=2 => child=1 parent=2 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=1 <-> parent=undefined => child=1 parent=1 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 1 + }, assert); + }); + QUnit.test('child=undefined <-> parent=2 => child=undefined parent=2 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=undefined <-> parent=undefined => child=undefined parent=undefined [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 <-> parent=3 => child=3 parent=3 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: true, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('child=1 <- parent=2 => child=1 parent=2 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=1 <- parent=undefined => child=1 parent=undefined [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 1, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 1, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=undefined <- parent=2 => child=undefined parent=2 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: 2, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: 2 + }, assert); + }); + QUnit.test('child=undefined <- parent=undefined => child=undefined parent=undefined [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: undefined, + startingParent: undefined, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: undefined, + expectedParent: undefined + }, assert); + }); + QUnit.test('child=3 <- parent=3 => child=3 parent=3 [onInitDoNotUpdateChild=true]', function (assert) { + initializationTest({ + startingChild: 3, + startingParent: 3, + childToParent: false, + parentToChild: true, + onInitDoNotUpdateChild: true, + onInitSetUndefinedParentIfChildIsDefined: true, + expectedChild: 3, + expectedParent: 3 + }, assert); + }); + QUnit.test('parent and child properties', function (assert) { + var child = new SimpleObservable(undefined); + var parentSetterWasCalled = false; + var parent = new SimpleObservable(15); + canReflect.assignSymbols(parent, { + 'can.setValue': function () { + parentSetterWasCalled = true; + } + }); + var binding = new Bind({ + child: child, + parent: parent + }); + assert.equal(binding.child, child, 'child'); + assert.equal(binding.parent, parent, 'child'); + }); +}); +/*can-bind@1.5.1#test/test*/ +define('can-bind@1.5.1#test/test', [ + 'require', + 'exports', + 'module', + './core', + './cycles-and-sticky', + './detection', + './initialization' +], function (require, exports, module) { + require('./core'); + require('./cycles-and-sticky'); + require('./detection'); + require('./initialization'); +}); +/*can-construct@3.5.6#can-construct_test*/ +define('can-construct@3.5.6#can-construct_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-construct', + 'can-log/dev/dev' +], function (require, exports, module) { + (function (global, require, exports, module) { + QUnit = require('steal-qunit'); + var Construct = require('can-construct'); + var dev = require('can-log/dev/dev'); + QUnit.module('can-construct', { + beforeEach: function (assert) { + var Animal = this.Animal = Construct.extend({ + count: 0, + test: function () { + return this.match ? true : false; + } + }, { + init: function () { + this.constructor.count++; + this.eyes = false; + } + }); + var Dog = this.Dog = this.Animal.extend({ match: /abc/ }, { + init: function () { + Animal.prototype.init.apply(this, arguments); + }, + talk: function () { + return 'Woof'; + } + }); + this.Ajax = this.Dog.extend({ count: 0 }, { + init: function (hairs) { + Dog.prototype.init.apply(this, arguments); + this.hairs = hairs; + this.setEyes(); + }, + setEyes: function () { + this.eyes = true; + } + }); + } + }); + QUnit.test('inherit', function (assert) { + var Base = Construct({}); + assert.ok(new Base() instanceof Construct); + var Inherit = Base({}); + assert.ok(new Inherit() instanceof Base); + }); + QUnit.test('Creating', function (assert) { + new this.Dog(); + var a1 = new this.Animal(); + new this.Animal(); + var ajax = new this.Ajax(1000); + assert.equal(2, this.Animal.count, 'right number of animals'); + assert.equal(1, this.Dog.count, 'right number of animals'); + assert.ok(this.Dog.match, 'right number of animals'); + assert.ok(!this.Animal.match, 'right number of animals'); + assert.ok(this.Dog.test(), 'right number of animals'); + assert.ok(!this.Animal.test(), 'right number of animals'); + assert.equal(1, this.Ajax.count, 'right number of animals'); + assert.equal(2, this.Animal.count, 'right number of animals'); + assert.equal(true, ajax.eyes, 'right number of animals'); + assert.equal(1000, ajax.hairs, 'right number of animals'); + assert.ok(a1 instanceof this.Animal); + assert.ok(a1 instanceof Construct); + }); + QUnit.test('new instance', function (assert) { + var d = this.Ajax.newInstance(6); + assert.equal(6, d.hairs); + }); + QUnit.test('namespaces', function (assert) { + var fb = Construct.extend('Bar'); + assert.ok(!window.Bar, 'not added to global namespace'); + if (Object.getOwnPropertyDescriptor) { + assert.equal(fb.name, 'Bar', 'name is right'); + } + assert.equal(fb.shortName, 'Bar', 'short name is right'); + }); + QUnit.test('setups', function (assert) { + var order = 0, staticSetup, staticSetupArgs, staticInit, staticInitArgs, protoSetup, protoInitArgs, protoInit, staticProps = { + setup: function () { + staticSetup = ++order; + staticSetupArgs = arguments; + return ['something']; + }, + init: function () { + staticInit = ++order; + staticInitArgs = arguments; + } + }, protoProps = { + setup: function (name) { + protoSetup = ++order; + return ['Ford: ' + name]; + }, + init: function () { + protoInit = ++order; + protoInitArgs = arguments; + } + }; + var Car = Construct.extend('Car', staticProps, protoProps); + new Car('geo'); + assert.equal(staticSetup, 1); + assert.equal(staticInit, 2); + assert.equal(protoSetup, 3); + assert.equal(protoInit, 4); + assert.deepEqual(Array.prototype.slice.call(staticInitArgs), ['something']); + assert.deepEqual(Array.prototype.slice.call(protoInitArgs), ['Ford: geo']); + assert.deepEqual(Array.prototype.slice.call(staticSetupArgs), [ + Construct, + 'Car', + staticProps, + protoProps + ], 'static construct'); + Car.extend('Truck'); + assert.equal(staticSetup, 5, 'Static setup is called if overwriting'); + }); + QUnit.test('Creating without extend', function (assert) { + var Bar = Construct('Bar', { + ok: function () { + assert.ok(true, 'ok called'); + } + }); + new Bar().ok(); + var Foo = Bar('Foo', { + dude: function () { + assert.ok(true, 'dude called'); + } + }); + new Foo().dude(true); + }); + QUnit.test('setup called with original arguments', function (assert) { + var o2 = {}; + var o1 = { + setup: function (base, arg1, arg2) { + assert.equal(o1, arg1, 'first argument is correct'); + assert.equal(o2, arg2, 'second argument is correct'); + } + }; + Construct.extend(o1, o2); + }); + QUnit.test('legacy namespace strings (A.B.C) accepted', function (assert) { + var Type = Construct.extend('Foo.Bar.Baz'); + var expectedValue = ~steal.config('env').indexOf('production') ? '' : 'Foo_Bar_Baz'; + assert.ok(new Type() instanceof Construct, 'No unexpected behavior in the prototype chain'); + if (Function.prototype.name) { + assert.equal(Type.name, expectedValue, 'Name becomes underscored'); + } + }); + QUnit.test('reserved words accepted', function (assert) { + var Type = Construct.extend('const'); + var expectedValue = ~steal.config('env').indexOf('production') ? '' : 'Const'; + assert.ok(new Type() instanceof Construct, 'No unexpected behavior in the prototype chain'); + if (Function.prototype.name) { + assert.equal(Type.name, expectedValue, 'Name becomes capitalized'); + } + }); + QUnit.test('basic injection attacks thwarted', function (assert) { + var rootToken = typeof window === 'undefined' ? 'global' : 'window'; + var rootObject = typeof window === 'undefined' ? global : window; + var expando = 'foo' + Math.random().toString(10).slice(2); + var MalignantType; + try { + MalignantType = Construct.extend('(){};' + rootToken + '.' + expando + '=\'bar\';var f=function'); + } catch (e) { + } finally { + assert.equal(rootObject[expando], undefined, 'Injected code doesn\'t run'); + } + delete rootObject[expando]; + try { + MalignantType = Construct.extend('(){},' + rootToken + '.' + expando + '=\'baz\',function'); + } catch (e) { + } finally { + assert.equal(rootObject[expando], undefined, 'Injected code doesn\'t run'); + } + }); + QUnit.test('setters not invoked on extension (#28)', function (assert) { + var extending = true; + var Base = Construct.extend('Base', { + set something(value) { + assert.ok(!extending, 'called when not extending'); + }, + get something() { + } + }); + Base.extend('Extended', { something: 'value' }); + extending = false; + new Base().something = 'foo'; + }); + QUnit.test('return alternative value simple', function (assert) { + var Alternative = function () { + }; + var Base = Construct.extend({ + setup: function () { + return new Construct.ReturnValue(new Alternative()); + } + }); + assert.ok(new Base() instanceof Alternative, 'Should create an instance of Alternative'); + }); + QUnit.test('return alternative value on setup (full case)', function (assert) { + var Student = function (name, school) { + this.name = name; + this.school = school; + this.isStudent = true; + }; + var Person = Construct.extend({ + setup: function (opts) { + if (opts.age >= 16) { + return new Construct.ReturnValue(new Student(opts.name, opts.school)); + } + opts.isStudent = false; + return [opts]; + }, + init: function (params) { + this.age = params.age; + this.name = params.name; + this.isStudent = params.isStudent; + } + }); + assert.equal(new Person({ age: 12 }).isStudent, false, 'Age 12 cannot be a student'); + assert.equal(new Person({ age: 30 }).isStudent, true, 'Age 20 can be a student'); + assert.ok(new Person({ age: 30 }) instanceof Student, 'Should return an instance of Student'); + }); + QUnit.test('extends defaults right', function (assert) { + var BASE = Construct.extend({ defaults: { foo: 'bar' } }, {}); + var INHERIT = BASE.extend({ defaults: { newProp: 'newVal' } }, {}); + assert.ok(INHERIT.defaults.foo === 'bar', 'Class must inherit defaults from the parent class'); + assert.ok(INHERIT.defaults.newProp === 'newVal', 'Class must have own defaults'); + }); + QUnit.test('enumerability', function (assert) { + var Parent = Construct.extend('Parent', {}); + var child = new Parent(); + child.foo = 'bar'; + var props = {}; + for (var prop in child) { + props[prop] = true; + } + assert.deepEqual(props, { foo: true }, 'only has ownProps'); + }); + QUnit.test('Has default init, setup functions', function (assert) { + var instance = new Construct(); + assert.equal(typeof instance.init, 'function', 'has init'); + assert.equal(typeof instance.setup, 'function', 'has setup'); + }); + QUnit.test('Extending should not update defaults nested objects', function (assert) { + var Parent = Construct.extend({ defaults: { obj: { foo: 'Bar' } } }, {}); + var Child = Parent.extend({ defaults: { obj: { foo: 'Baz' } } }, {}); + assert.equal(Parent.defaults.obj.foo, 'Bar', 'Base defaults are not changed'); + assert.equal(Child.defaults.obj.foo, 'Baz', 'Child defaults get defaults right'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-construct-super@3.2.1#can-construct-super*/ +define('can-construct-super@3.2.1#can-construct-super', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-construct' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var Construct = require('can-construct'); + var hasOwnProperty = Object.prototype.hasOwnProperty; + var isFunction = function (val) { + return typeof val === 'function'; + }, fnTest = /xyz/.test(function () { + return this.xyz; + }) ? /\b_super\b/ : /.*/, getset = [ + 'get', + 'set' + ], getSuper = function (base, name, fn) { + return function () { + var hasExistingValue = false; + var existingValue; + var prototype = getPrototypeOf(this); + var existingPrototypeValue = prototype._super; + if (hasOwnProperty.call(this, '_super')) { + hasExistingValue = true; + existingValue = this._super; + delete this._super; + } + prototype._super = base[name]; + var ret = fn.apply(this, arguments); + prototype._super = existingPrototypeValue; + if (hasExistingValue) { + this._super = existingValue; + } + return ret; + }; + }; + Construct._defineProperty = function (addTo, base, name, descriptor) { + var _super = Object.getOwnPropertyDescriptor(base, name); + if (_super) { + canReflect.each(getset, function (method) { + if (isFunction(_super[method]) && isFunction(descriptor[method])) { + descriptor[method] = getSuper(_super, method, descriptor[method]); + } else if (!isFunction(descriptor[method])) { + descriptor[method] = _super[method]; + } + }); + } + Object.defineProperty(addTo, name, descriptor); + }; + var getPrototypeOf = Object.getPrototypeOf || function (obj) { + return obj.__proto__; + }; + var getPropertyDescriptor = Object.getPropertyDescriptor || function (subject, name) { + if (name in subject) { + var pd = Object.getOwnPropertyDescriptor(subject, name); + var proto = getPrototypeOf(subject); + while (pd === undefined && proto !== null) { + pd = Object.getOwnPropertyDescriptor(proto, name); + proto = getPrototypeOf(proto); + } + return pd; + } + }; + Construct._overwrite = function (addTo, base, name, val) { + var baseDescriptor = getPropertyDescriptor(base, name); + var baseValue = baseDescriptor && baseDescriptor.value; + Object.defineProperty(addTo, name, { + value: isFunction(val) && isFunction(baseValue) && fnTest.test(val) ? getSuper(base, name, val) : val, + configurable: true, + enumerable: true, + writable: true + }); + }; + module.exports = Construct; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-construct-super@3.2.1#test/can-construct-super_test*/ +define('can-construct-super@3.2.1#test/can-construct-super_test', [ + 'require', + 'exports', + 'module', + 'can-construct-super', + 'steal-qunit' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Construct = require('can-construct-super'); + var QUnit = require('steal-qunit'); + QUnit.module('can-construct-super'); + QUnit.test('prototype super', function (assert) { + var A = Construct.extend({ + init: function (arg) { + this.arg = arg + 1; + }, + add: function (num) { + return this.arg + num; + } + }); + var B = A({ + init: function (arg) { + this._super(arg + 2); + }, + add: function (arg) { + return this._super(arg + 1); + } + }); + var b = new B(1); + assert.equal(b.arg, 4); + assert.equal(b.add(2), 7); + }); + QUnit.test('static super', function (assert) { + var First = Construct.extend({ + raise: function (num) { + return num; + } + }, {}); + var Second = First.extend({ + raise: function (num) { + return this._super(num) * num; + } + }, {}); + assert.equal(Second.raise(2), 4); + }); + QUnit.test('findAll super', function (assert) { + var Parent = Construct.extend({ + findAll: function () { + assert.equal(this.shortName, 'child'); + return Promise.resolve(); + }, + shortName: 'parent' + }, {}); + var Child = Parent.extend({ + findAll: function () { + return this._super(); + }, + shortName: 'child' + }, {}); + var done = assert.async(); + assert.expect(1); + Child.findAll({}); + done(); + }); + if (Object.getOwnPropertyDescriptor) { + QUnit.test('_super supports getters and setters', function (assert) { + var Person = Construct.extend({ + get age() { + return 42; + }, + set name(value) { + this._name = value; + }, + get name() { + return this._name; + } + }); + var OtherPerson = Person.extend({ + get age() { + return this._super() + 8; + }, + set name(value) { + this._super(value + '_super'); + } + }); + var test = new OtherPerson(); + test.base = 2; + assert.equal(test.age, 50, 'Getter and _super works'); + test.name = 'David'; + assert.equal(test.name, 'David_super', 'Setter ran'); + }); + } + QUnit.test('setters not invoked on extension (#9)', function (assert) { + var extending = true; + var Base = Construct.extend('Base', { + set something(value) { + assert.ok(!extending, 'set not called when not extending'); + }, + get something() { + assert.ok(!extending, 'get not called when not extending'); + } + }); + Base.extend('Extended', { something: 'value' }); + extending = false; + new Base().something = 'foo'; + }); + QUnit.test('_super isn\'t always available (#11)', function (assert) { + var Parent = Construct.extend({}); + var Child = Parent.extend({ + init: function () { + this._super(); + assert.ok(true); + } + }); + new Child(); + }); + QUnit.test('_super should work for sealed instances', function (assert) { + var A = Construct.extend({ + init: function (arg) { + this.arg = arg + 1; + }, + add: function (num) { + return this.arg + num; + } + }); + var B = A({ + init: function (arg) { + this._super(arg + 2); + }, + add: function (arg) { + return this._super(arg + 1); + } + }); + var b = new B(1); + Object.seal(b); + assert.equal(b.arg, 4, 'should instantiate properly'); + assert.equal(b.add(2), 7, 'should call methods properly'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-control@5.0.1#can-control*/ +define('can-control@5.0.1#can-control', [ + 'require', + 'exports', + 'module', + 'can-construct', + 'can-namespace', + 'can-assign', + 'can-stache-key', + 'can-reflect', + 'can-observation', + 'can-event-queue/map/map', + 'can-log/dev/dev', + 'can-queues', + 'can-string', + 'can-key/get/get', + 'can-dom-mutate', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Construct = require('can-construct'); + var namespace = require('can-namespace'); + var assign = require('can-assign'); + var observeReader = require('can-stache-key'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var canEvent = require('can-event-queue/map/map'); + var dev = require('can-log/dev/dev'); + var queues = require('can-queues'); + var string = require('can-string'); + var get = require('can-key/get/get'); + var domMutate = require('can-dom-mutate'); + var canSymbol = require('can-symbol'); + var controlsSymbol = canSymbol.for('can.controls'); + var processors; + var bind = function (el, ev, callback, queue) { + canEvent.on.call(el, ev, callback, queue); + return function () { + canEvent.off.call(el, ev, callback, queue); + }; + }, slice = [].slice, paramReplacer = /\{([^\}]+)\}/g, delegate = function (el, selector, ev, callback) { + canEvent.on.call(el, ev, selector, callback); + return function () { + canEvent.off.call(el, ev, selector, callback); + }; + }, binder = function (el, ev, callback, selector) { + return selector ? delegate(el, selector.trim(), ev, callback) : bind(el, ev, callback); + }, basicProcessor; + var Control = Construct.extend('Control', { + setup: function () { + Construct.setup.apply(this, arguments); + if (Control) { + var control = this, funcName; + control.actions = {}; + for (funcName in control.prototype) { + if (control._isAction(funcName)) { + control.actions[funcName] = control._action(funcName); + } + } + } + }, + _shifter: function (context, name) { + var method = typeof name === 'string' ? context[name] : name; + if (typeof method !== 'function') { + method = context[method]; + } + var Control = this; + function controlMethod() { + var wrapped = Control.wrapElement(this); + context.called = name; + return method.apply(context, [wrapped].concat(slice.call(arguments, 0))); + } + return controlMethod; + }, + _isAction: function (methodName) { + var val = this.prototype[methodName], type = typeof val; + return methodName !== 'constructor' && (type === 'function' || type === 'string' && typeof this.prototype[val] === 'function') && !!(Control.isSpecial(methodName) || processors[methodName] || /[^\w]/.test(methodName)); + }, + _action: function (methodName, options, controlInstance) { + var readyCompute, unableToBind; + paramReplacer.lastIndex = 0; + if (options || !paramReplacer.test(methodName)) { + var controlActionData = function () { + var delegate; + var name = methodName.replace(paramReplacer, function (matched, key) { + var value, parent; + if (this._isDelegate(options, key)) { + delegate = this._getDelegate(options, key); + return ''; + } + key = this._removeDelegateFromKey(key); + parent = this._lookup(options)[0]; + value = observeReader.read(parent, observeReader.reads(key), { readCompute: false }).value; + if (value === undefined && typeof window !== 'undefined') { + value = get(window, key); + } + if (!parent || !(canReflect.isObservableLike(parent) && canReflect.isMapLike(parent)) && !value) { + unableToBind = true; + return null; + } + if (typeof value === 'string') { + return value; + } else { + delegate = value; + return ''; + } + }.bind(this)); + name = name.trim(); + var parts = name.split(/\s+/g), event = parts.pop(); + return { + processor: this.processors[event] || basicProcessor, + parts: [ + name, + parts.join(' '), + event + ], + delegate: delegate || undefined + }; + }; + readyCompute = new Observation(controlActionData, this); + if (controlInstance) { + var handler = function (actionData) { + if (controlInstance._bindings.control[methodName]) { + controlInstance._bindings.control[methodName](controlInstance.element); + } + controlInstance._bindings.control[methodName] = actionData.processor(actionData.delegate || controlInstance.element, actionData.parts[2], actionData.parts[1], methodName, controlInstance); + }; + canReflect.onValue(readyCompute, handler, 'mutate'); + controlInstance._bindings.readyComputes[methodName] = { + compute: readyCompute, + handler: handler + }; + } + return readyCompute.get(); + } + }, + _lookup: function (options) { + return [ + options, + window + ]; + }, + _removeDelegateFromKey: function (key) { + return key; + }, + _isDelegate: function (options, key) { + return key === 'element'; + }, + _getDelegate: function (options, key) { + return undefined; + }, + processors: {}, + defaults: {}, + convertElement: function (element) { + element = typeof element === 'string' ? document.querySelector(element) : element; + return this.wrapElement(element); + }, + wrapElement: function (el) { + return el; + }, + unwrapElement: function (el) { + return el; + }, + isSpecial: function (eventName) { + return eventName === 'inserted' || eventName === 'removed'; + } + }, { + setup: function (element, options) { + var cls = this.constructor, pluginname = cls.pluginName || cls.shortName, arr; + if (!element) { + throw new Error('Creating an instance of a named control without passing an element'); + } + this.element = cls.convertElement(element); + if (pluginname && pluginname !== 'Control' && this.element.classList) { + this.element.classList.add(pluginname); + } + arr = this.element[controlsSymbol]; + if (!arr) { + arr = []; + this.element[controlsSymbol] = arr; + } + arr.push(this); + if (canReflect.isObservableLike(options) && canReflect.isMapLike(options)) { + for (var prop in cls.defaults) { + if (!options.hasOwnProperty(prop)) { + observeReader.set(options, prop, cls.defaults[prop]); + } + } + this.options = options; + } else { + this.options = assign(assign({}, cls.defaults), options); + } + this.on(); + return [ + this.element, + this.options + ]; + }, + on: function (el, selector, eventName, func) { + if (!el) { + this.off(); + var cls = this.constructor, bindings = this._bindings, actions = cls.actions, element = this.constructor.unwrapElement(this.element), destroyCB = Control._shifter(this, 'destroy'), funcName, ready; + for (funcName in actions) { + if (actions.hasOwnProperty(funcName)) { + ready = actions[funcName] || cls._action(funcName, this.options, this); + if (ready) { + bindings.control[funcName] = ready.processor(ready.delegate || element, ready.parts[2], ready.parts[1], funcName, this); + } + } + } + var removalDisposal = domMutate.onNodeDisconnected(element, function () { + var doc = element.ownerDocument; + var ownerNode = doc.contains ? doc : doc.documentElement; + if (!ownerNode || ownerNode.contains(element) === false) { + if (queues.domQueue.isFlushing) { + queues.mutateQueue.enqueue(destroyCB); + } else { + destroyCB(); + } + } + }); + bindings.user.push(function () { + if (removalDisposal) { + removalDisposal(); + removalDisposal = undefined; + } + }); + return bindings.user.length; + } + if (typeof el === 'string') { + func = eventName; + eventName = selector; + selector = el; + el = this.element; + } + if (func === undefined) { + func = eventName; + eventName = selector; + selector = null; + } + if (typeof func === 'string') { + func = Control._shifter(this, func); + } + this._bindings.user.push(binder(el, eventName, func, selector)); + return this._bindings.user.length; + }, + off: function () { + var el = this.constructor.unwrapElement(this.element), bindings = this._bindings; + if (bindings) { + (bindings.user || []).forEach(function (value) { + value(el); + }); + canReflect.eachKey(bindings.control || {}, function (value) { + value(el); + }); + canReflect.eachKey(bindings.readyComputes || {}, function (value) { + canReflect.offValue(value.compute, value.handler, 'mutate'); + }); + } + this._bindings = { + user: [], + control: {}, + readyComputes: {} + }; + }, + destroy: function () { + if (this.element === null) { + return; + } + var Class = this.constructor, pluginName = Class.pluginName || Class.shortName && string.underscore(Class.shortName), controls; + this.off(); + if (pluginName && pluginName !== 'can_control' && this.element.classList) { + this.element.classList.remove(pluginName); + } + controls = this.element[controlsSymbol]; + if (controls) { + controls.splice(controls.indexOf(this), 1); + } + this.element = null; + } + }); + processors = Control.processors; + basicProcessor = function (el, event, selector, methodName, control) { + return binder(el, event, Control._shifter(control, methodName), selector); + }; + [ + 'beforeremove', + 'change', + 'click', + 'contextmenu', + 'dblclick', + 'keydown', + 'keyup', + 'keypress', + 'mousedown', + 'mousemove', + 'mouseout', + 'mouseover', + 'mouseup', + 'reset', + 'resize', + 'scroll', + 'select', + 'submit', + 'focusin', + 'focusout', + 'mouseenter', + 'mouseleave', + 'touchstart', + 'touchmove', + 'touchcancel', + 'touchend', + 'touchleave', + 'inserted', + 'removed', + 'dragstart', + 'dragenter', + 'dragover', + 'dragleave', + 'drag', + 'drop', + 'dragend' + ].forEach(function (v) { + processors[v] = basicProcessor; + }); + module.exports = namespace.Control = Control; +}); +/*can-control@5.0.1#can-control_test*/ +define('can-control@5.0.1#can-control_test', [ + 'require', + 'exports', + 'module', + 'can-control', + 'steal-qunit', + 'can-fragment', + 'can-log/dev/dev', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-globals', + 'can-queues', + 'can-simple-map', + 'can-define/map/', + 'can-simple-observable', + 'can-symbol' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Control = require('can-control'); + var QUnit = require('steal-qunit'); + var fragment = require('can-fragment'); + var dev = require('can-log/dev/dev'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var globals = require('can-globals'); + var queues = require('can-queues'); + var SimpleMap = require('can-simple-map'); + var DefineMap = require('can-define/map/'); + var SimpleObservable = require('can-simple-observable'); + var canSymbol = require('can-symbol'); + QUnit.module('can-control', { + beforeEach: function (assert) { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('parameterized actions', function (assert) { + var called = false, WeirderBind = Control.extend({ + '{parameterized}': function () { + called = true; + } + }), a; + this.fixture.appendChild(fragment('
      ')); + a = document.getElementById('crazy'); + new WeirderBind(a, { parameterized: 'sillyEvent' }); + domEvents.dispatch(a, 'sillyEvent'); + assert.ok(called, 'heard the trigger'); + }); + QUnit.test('windowresize', function (assert) { + var called = false, WindowBind = Control.extend('', { + '{window} resize': function () { + called = true; + } + }); + this.fixture.appendChild(fragment('
      ')); + new WindowBind('#weird'); + domEvents.dispatch(window, 'resize'); + assert.ok(called, 'got window resize event'); + }); + QUnit.test('on', function (assert) { + assert.expect(9); + var called = false, DelegateTest = Control.extend({ + click: function () { + } + }), Tester = Control.extend({ + init: function (el, ops) { + this.on(window, 'click', function (ev) { + assert.ok(true, 'Got window click event'); + }); + this.on(window, 'click', 'clicked'); + this.on('click', function () { + assert.ok(true, 'Directly clicked element'); + }); + this.on('click', 'clicked'); + }, + clicked: function (context) { + assert.ok(true, 'Controller action delegated click triggered, too'); + } + }), div = document.createElement('div'); + this.fixture.appendChild(div); + var rb = new Tester(div); + this.fixture.appendChild(fragment('')); + var dt = new DelegateTest('#els'); + dt.on(document.querySelector('#els span'), 'a', 'click', function () { + called = true; + }); + domEvents.dispatch(document.querySelector('#els a'), 'click'); + assert.ok(called, 'delegate works'); + domMutateNode.removeChild.call(this.fixture, document.querySelector('#els')); + domEvents.dispatch(div, 'click'); + domEvents.dispatch(window, 'click'); + rb.destroy(); + }); + QUnit.test('inherit', function (assert) { + var called = false, Parent = Control.extend({ + click: function () { + called = true; + } + }), Child = Parent.extend({}); + this.fixture.appendChild(fragment('')); + new Child('#els'); + domEvents.dispatch(document.querySelector('#els'), 'click'); + assert.ok(called, 'inherited the click method'); + }); + QUnit.test('space makes event', function (assert) { + assert.expect(1); + var Dot = Control.extend({ + ' foo': function () { + assert.ok(true, 'called'); + } + }); + this.fixture.appendChild(fragment('')); + new Dot('#els'); + domEvents.dispatch(document.querySelector('#els'), 'foo'); + }); + QUnit.test('custom events with hyphens work', function (assert) { + assert.expect(1); + this.fixture.appendChild(fragment('
      ')); + var FooBar = Control.extend({ + 'span custom-event': function () { + assert.ok(true, 'Custom event was fired.'); + } + }); + new FooBar('#customEvent'); + domEvents.dispatch(document.querySelector('#customEvent span'), 'custom-event'); + }); + QUnit.test('inherit defaults', function (assert) { + var BASE = Control.extend({ defaults: { foo: 'bar' } }, {}); + var INHERIT = BASE.extend({ defaults: { newProp: 'newVal' } }, {}); + assert.ok(INHERIT.defaults.foo === 'bar', 'Class must inherit defaults from the parent class'); + assert.ok(INHERIT.defaults.newProp === 'newVal', 'Class must have own defaults'); + var inst = new INHERIT(document.createElement('div'), {}); + assert.ok(inst.options.foo === 'bar', 'Instance must inherit defaults from the parent class'); + assert.ok(inst.options.newProp === 'newVal', 'Instance must have defaults of it`s class'); + }); + QUnit.test('on rebinding', function (assert) { + assert.expect(2); + var first = true; + var Rebinder = Control.extend({ + '{item} foo': function (item, ev) { + if (first) { + assert.equal(item.get('id'), 1, 'first item'); + first = false; + } else { + assert.equal(item.get('id'), 2, 'first item'); + } + } + }); + var item1 = new SimpleMap({ id: 1 }), item2 = new SimpleMap({ id: 2 }), rb = new Rebinder(document.createElement('div'), { item: item1 }); + item1.dispatch('foo'); + rb.options = { item: item2 }; + rb.on(); + item2.dispatch('foo'); + }); + QUnit.test('actions provide method names', function (assert) { + var item1 = new SimpleMap({}); + var item2 = new SimpleMap({}); + var Tester = Control.extend({ + '{item1} foo': 'food', + '{item2} bar': 'food', + food: function (item, ev, data) { + assert.ok(true, 'food called'); + assert.ok(item === item1 || item === item2, 'called with an item'); + } + }); + new Tester(document.createElement('div'), { + item1: item1, + item2: item2 + }); + item1.dispatch('foo'); + item2.dispatch('bar'); + }); + QUnit.test('Don\'t bind if there are undefined values in templates', function (assert) { + var C = Control.extend({}, { + '{noExistStuff} proc': function () { + } + }); + var c = new C(document.createElement('div')); + assert.equal(c._bindings.user.length, 1, 'There is only one binding'); + var C2 = Control.extend({ + '{noExistStuff} click': function () { + assert.ok(false, 'should not fall through to click handler'); + } + }); + var div = document.createElement('div'); + new C2(div, {}); + domEvents.dispatch(div, 'click'); + }); + QUnit.test('Multiple calls to destroy', function (assert) { + assert.expect(2); + var C = Control.extend({ + destroy: function () { + assert.ok(true); + Control.prototype.destroy.call(this); + } + }), div = document.createElement('div'), c = new C(div); + c.destroy(); + c.destroy(); + }); + QUnit.test('drag and drop events', function (assert) { + assert.expect(7); + var DragDrop = Control.extend('', { + ' dragstart': function () { + assert.ok(true, 'dragstart called'); + }, + ' dragenter': function () { + assert.ok(true, 'dragenter called'); + }, + ' dragover': function () { + assert.ok(true, 'dragover called'); + }, + ' dragleave': function () { + assert.ok(true, 'dragleave called'); + }, + ' drag': function () { + assert.ok(true, 'drag called'); + }, + ' drop': function () { + assert.ok(true, 'drop called'); + }, + ' dragend': function () { + assert.ok(true, 'dragend called'); + } + }); + this.fixture.appendChild(fragment('
      ')); + new DragDrop('#draggable'); + var draggable = document.getElementById('draggable'); + domEvents.dispatch(draggable, 'dragstart'); + domEvents.dispatch(draggable, 'dragenter'); + domEvents.dispatch(draggable, 'dragover'); + domEvents.dispatch(draggable, 'dragleave'); + domEvents.dispatch(draggable, 'drag'); + domEvents.dispatch(draggable, 'drop'); + domEvents.dispatch(draggable, 'dragend'); + }); + QUnit.test('beforeremove event', function (assert) { + assert.expect(1); + var Foo = Control.extend('', { + 'beforeremove': function () { + assert.ok(true, 'beforeremove called'); + } + }); + var el = fragment('
      '); + new Foo(el); + domEvents.dispatch(el, 'beforeremove'); + }); + if (System.env.indexOf('production') < 0) { + QUnit.test('Control is logging information in dev mode', function (assert) { + assert.expect(2); + var oldlog = dev.log; + var oldwarn = dev.warn; + dev.log = function (text) { + assert.equal(text, 'can-control: No property found for handling {dummy} change', 'Text logged as expected'); + }; + var C = Control.extend({ + '{dummy} change': function () { + } + }); + var instance = new C(document.createElement('div')); + dev.warn = function (text) { + assert.equal(text, 'can-control: Control already destroyed', 'control destroyed warning'); + }; + instance.destroy(); + instance.destroy(); + dev.warn = oldwarn; + dev.log = oldlog; + }); + } + QUnit.test('event handlers should rebind when target is replaced', function (assert) { + var nameChanges = 0; + var MyControl = Control.extend('MyControl', { + '{person.name} first': function () { + nameChanges++; + }, + name: function (name) { + this.options.person.set('name', name); + } + }); + var c = new MyControl(document.createElement('div'), { person: new SimpleMap({ name: new SimpleMap({ first: 'Kevin' }) }) }); + c.options.person.get('name').set('first', 'Tracy'); + c.name(new SimpleMap({ first: 'Kim' })); + c.options.person.get('name').get('first', 'Max'); + assert.equal(nameChanges, 2); + }); + QUnit.test('{element} event handling', function (assert) { + assert.expect(3); + var done = assert.async(); + var MyControl = Control.extend({ + '{element} click': function (element) { + if (element === this.element) { + assert.ok(true, '`{element} click` should catch clicking on the element'); + } else { + assert.ok(true, '`{element} click` should catch clicking on a child of the element'); + } + }, + '{element} p click': function () { + assert.ok(true, '`{element} p click` works'); + done(); + } + }); + var div = document.createElement('div'); + var p = document.createElement('p'); + div.appendChild(p); + new MyControl(div, { foo: 'bar' }); + domEvents.dispatch(div, 'click'); + domEvents.dispatch(p, 'click'); + }); + QUnit.test('Passing a Map as options works', function (assert) { + assert.expect(2); + var done = assert.async(); + var MyControl = Control.extend({ defaults: { testEndEvent: 'mouseleave' } }, { + '{element} {eventType}': function () { + assert.ok(true, 'catches handler from options'); + }, + '{element} {testEndEvent}': function () { + assert.ok(true, 'catches handler from defaults'); + done(); + } + }); + var map = new SimpleMap({ eventType: 'click' }); + var div = document.createElement('div'); + new MyControl(div, map); + map.attr('eventType', 'mouseenter'); + domEvents.dispatch(div, 'mouseenter'); + domEvents.dispatch(div, 'mouseleave'); + }); + QUnit.test('Passing a DefineMap as options works', function (assert) { + assert.expect(2); + var done = assert.async(); + var MyControl = Control.extend({ defaults: { testEndEvent: 'mouseleave' } }, { + '{element} {eventType}': function () { + assert.ok(true, 'catches handler from options'); + }, + '{element} {testEndEvent}': function () { + assert.ok(true, 'catches handler from defaults'); + done(); + } + }); + var MyMap = DefineMap.extend({ + eventType: 'string', + testEndEvent: 'string' + }); + var map = new MyMap(); + map.eventType = 'click'; + var div = document.createElement('div'); + new MyControl(div, map); + map.eventType = 'mousenter'; + domEvents.dispatch(div, 'mousenter'); + domEvents.dispatch(div, 'mouseleave'); + }); + QUnit.test('Creating an instance of a named control without passing an element', function (assert) { + var MyControl = Control.extend('MyControl'); + try { + new MyControl(); + } catch (e) { + assert.ok(true, 'Caught an exception'); + } + }); + QUnit.test('Creating an instance of a named control passing a selector', function (assert) { + this.fixture.appendChild(fragment('
      d
      ')); + var MyControl = Control.extend('MyControl'); + var myControlInstance = new MyControl('#my-control'); + assert.ok(myControlInstance.element.classList.contains('MyControl'), 'Element has the correct class name'); + }); + QUnit.test('can watch SimpleObservable', function (assert) { + var MyControl = Control.extend({ + '{simple}': function (simple, newVal) { + assert.equal(newVal, 6); + } + }); + var div = document.createElement('div'); + var simple = new SimpleObservable(5); + new MyControl(div, { simple: simple }); + simple.set(6); + }); + QUnit.test('get controls using a symbol (#128)', function (assert) { + var MyControl = Control.extend({}); + var div = document.createElement('div'); + var instance = new MyControl(div, {}); + assert.deepEqual(div[canSymbol.for('can.controls')], [instance], 'right instance'); + }); + QUnit.test('Able to handle the documentElement being removed', function (assert) { + var done = assert.async(); + var doc = document.implementation.createHTMLDocument('Test'); + var div = doc.createElement('div'); + doc.body.appendChild(div); + new Control(div, {}); + globals.setKeyValue('document', doc); + var teardown = domMutate.onNodeRemoval(div, function () { + teardown(); + globals.setKeyValue('document', document); + assert.ok(true, 'it worked'); + done(); + }); + doc.removeChild(doc.documentElement); + }); + QUnit.test('Tearing down while batched does not cause issues', function (assert) { + var div = document.createElement('div'); + var MyControl = Control.extend({ + '{viewModel.items} remove': function () { + } + }); + var vm = new (DefineMap.extend({ + items: { + Type: DefineMap, + get default() { + return { xyzzzy: 'xyzzzzy' }; + } + } + }))(); + new MyControl(div, { viewModel: vm }); + document.body.appendChild(div); + queues.batch.start(); + vm.items = {}; + queues.domQueue.enqueue(function () { + document.body.removeChild(div); + domMutate.flushRecords(); + }, null, [], { element: document.body }); + try { + queues.batch.stop(); + assert.ok(true, 'Succeeded without error'); + } catch (e) { + assert.ok(false, 'Error caught'); + } + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-define-lazy-value@1.1.1#define-lazy-value-test*/ +define('can-define-lazy-value@1.1.1#define-lazy-value-test', [ + 'steal-qunit@2.0.0#steal-qunit', + 'can-define-lazy-value@1.1.1#define-lazy-value' +], function (_stealQunit, _canDefineLazyValue) { + 'use strict'; + var _stealQunit2 = _interopRequireDefault(_stealQunit); + var _canDefineLazyValue2 = _interopRequireDefault(_canDefineLazyValue); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + _stealQunit2.default.module('can-define-lazy-value'); + _stealQunit2.default.test('docs', function (assert) { + var _id = 1; + function getId() { + return _id++; + } + function MyObj(name) { + this.name = name; + } + (0, _canDefineLazyValue2.default)(MyObj.prototype, 'id', getId); + var obj1 = new MyObj('obj1'); + var obj2 = new MyObj('obj2'); + assert.equal(obj2.id, 1, 'first object read should get id 1'); + assert.equal(obj1.id, 2, 'second object read should get id 2'); + try { + obj1.id = 3; + } catch (e) { + assert.ok(true, 'obj1.id should not be writable by default'); + } + (0, _canDefineLazyValue2.default)(MyObj.prototype, 'id', getId, true); + var obj3 = new MyObj('obj3'); + assert.equal(obj3.id, 3, 'obj3 should have id'); + obj3.id = 4; + assert.equal(obj3.id, 4, 'obj3.id should be writeable'); + }); +}); +/*can-deparam@1.2.3#can-deparam*/ +define('can-deparam@1.2.3#can-deparam', [ + 'require', + 'exports', + 'module', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var digitTest = /^\d+$/, keyBreaker = /([^\[\]]+)|(\[\])/g, paramTest = /([^?#]*)(#.*)?$/, entityRegex = /%([^0-9a-f][0-9a-f]|[0-9a-f][^0-9a-f]|[^0-9a-f][^0-9a-f])/i, startChars = { + '#': true, + '?': true + }, prep = function (str) { + if (startChars[str.charAt(0)] === true) { + str = str.substr(1); + } + str = str.replace(/\+/g, ' '); + try { + return decodeURIComponent(str); + } catch (e) { + return decodeURIComponent(str.replace(entityRegex, function (match, hex) { + return '%25' + hex; + })); + } + }; + function isArrayLikeName(name) { + return digitTest.test(name) || name === '[]'; + } + function idenity(value) { + return value; + } + module.exports = namespace.deparam = function (params, valueDeserializer) { + valueDeserializer = valueDeserializer || idenity; + var data = {}, pairs, lastPart; + if (params && paramTest.test(params)) { + pairs = params.split('&'); + pairs.forEach(function (pair) { + var parts = pair.split('='), key = prep(parts.shift()), value = prep(parts.join('=')), current = data; + if (key) { + parts = key.match(keyBreaker); + for (var j = 0, l = parts.length - 1; j < l; j++) { + var currentName = parts[j], nextName = parts[j + 1], currentIsArray = isArrayLikeName(currentName) && current instanceof Array; + if (!current[currentName]) { + if (currentIsArray) { + current.push(isArrayLikeName(nextName) ? [] : {}); + } else { + current[currentName] = isArrayLikeName(nextName) ? [] : {}; + } + } + if (currentIsArray) { + current = current[current.length - 1]; + } else { + current = current[currentName]; + } + } + lastPart = parts.pop(); + if (isArrayLikeName(lastPart)) { + current.push(valueDeserializer(value)); + } else { + current[lastPart] = valueDeserializer(value); + } + } + }); + } + return data; + }; +}); +/*can-deparam@1.2.3#can-deparam-test*/ +define('can-deparam@1.2.3#can-deparam-test', [ + 'require', + 'exports', + 'module', + './can-deparam', + 'steal-qunit', + 'can-string-to-any' +], function (require, exports, module) { + var deparam = require('./can-deparam'); + var QUnit = require('steal-qunit'); + var stringToAny = require('can-string-to-any'); + QUnit.module('can-deparam'); + QUnit.test('Nested deparam', function (assert) { + var data = deparam('a[b]=1&a[c]=2'); + assert.equal(data.a.b, 1); + assert.equal(data.a.c, 2); + data = deparam('a[]=1&a[]=2'); + assert.equal(data.a[0], 1); + assert.equal(data.a[1], 2); + data = deparam('a[b][]=1&a[b][]=2'); + assert.equal(data.a.b[0], 1); + assert.equal(data.a.b[1], 2); + data = deparam('a[0]=1&a[1]=2'); + assert.equal(data.a[0], 1); + assert.equal(data.a[1], 2); + }); + QUnit.test('Remaining ampersand', function (assert) { + var data = deparam('a[b]=1&a[c]=2&'); + assert.deepEqual(data, { + a: { + b: '1', + c: '2' + } + }); + }); + QUnit.test('Invalid encoding', function (assert) { + var data = deparam('foo=%0g'); + assert.deepEqual(data, { foo: '%0g' }); + }); + QUnit.test('deparam deep', function (assert) { + assert.deepEqual(deparam('age[or][][lte]=5&age[or][]=null'), { + age: { + or: [ + { lte: '5' }, + 'null' + ] + } + }); + }); + QUnit.test('takes value deserializer', function (assert) { + assert.deepEqual(deparam('age[or][][lte]=5&age[or][]=null', stringToAny), { + age: { + or: [ + { lte: 5 }, + null + ] + } + }); + assert.deepEqual(deparam('undefined=undefined&null=null&NaN=NaN&true=true&false=false', stringToAny), { + 'undefined': undefined, + 'null': null, + 'NaN': NaN, + 'true': true, + 'false': false + }); + }); + QUnit.test(' handle \'?\' and \'#\' ', function (assert) { + var result = deparam('?foo=bar&number=1234', stringToAny); + assert.deepEqual(result, { + 'foo': 'bar', + 'number': 1234 + }); + result = deparam('#foo[]=bar&foo[]=baz'); + assert.deepEqual(result, { + 'foo': [ + 'bar', + 'baz' + ] + }); + }); +}); +/*can-dom-events@1.3.11#helpers/make-event-registry-test*/ +define('can-dom-events@1.3.11#helpers/make-event-registry-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './make-event-registry' +], function (require, exports, module) { + var unit = require('steal-qunit'); + var makeEventRegistry = require('./make-event-registry'); + unit.module('make-event-registry'); + unit.test('add should register the event with the given eventType', function (assert) { + var eventType = 'boi'; + var registry = makeEventRegistry(); + var exampleEvent = { + defaultEventType: 'cake', + addEventListener: function () { + }, + removeEventListener: function () { + } + }; + registry.add(exampleEvent, eventType); + assert.equal(registry.has(eventType), true, 'event should be registered at "' + eventType + '"'); + }); + unit.test('add should use the event\'s defaultEventType unless eventType is provided', function (assert) { + var eventType = 'boi'; + var registry = makeEventRegistry(); + var exampleEvent = { + defaultEventType: eventType, + addEventListener: function () { + }, + removeEventListener: function () { + } + }; + registry.add(exampleEvent); + assert.equal(registry.has(eventType), true, 'event should be registered at "' + eventType + '"'); + }); + unit.test('has should return whether an event is registered', function (assert) { + var eventType = 'boi'; + var exampleEvent = { + defaultEventType: eventType, + addEventListener: function () { + }, + removeEventListener: function () { + } + }; + var registry = makeEventRegistry(); + assert.equal(registry.has(eventType), false, 'initial registry should not have the event'); + var remove = registry.add(exampleEvent); + assert.equal(registry.has(eventType), true, 'updated registry should have the event'); + remove(); + assert.equal(registry.has(eventType), false, 'empty registry should not have the event'); + }); + unit.test('get should return the register event', function (assert) { + var eventType = 'boi'; + var exampleEvent = { + defaultEventType: eventType, + addEventListener: function () { + }, + removeEventListener: function () { + } + }; + var registry = makeEventRegistry(); + assert.equal(registry.get(eventType), undefined, 'initial registry should not have the event'); + var remove = registry.add(exampleEvent); + assert.equal(registry.get(eventType), exampleEvent, 'updated registry should have the event'); + remove(); + assert.equal(registry.get(eventType), undefined, 'empty registry should not have the event'); + }); +}); +/*can-dom-events@1.3.11#helpers/add-event-compat*/ +define('can-dom-events@1.3.11#helpers/add-event-compat', [ + 'require', + 'exports', + 'module', + './util' +], function (require, exports, module) { + 'use strict'; + var util = require('./util'); + var addDomContext = util.addDomContext; + var removeDomContext = util.removeDomContext; + function isDomEvents(obj) { + return !!(obj && obj.addEventListener && obj.removeEventListener && obj.dispatch); + } + function isNewEvents(obj) { + return typeof obj.addEvent === 'function'; + } + module.exports = function addEventCompat(domEvents, customEvent, customEventType) { + if (!isDomEvents(domEvents)) { + throw new Error('addEventCompat() must be passed can-dom-events or can-util/dom/events/events'); + } + customEventType = customEventType || customEvent.defaultEventType; + if (isNewEvents(domEvents)) { + return domEvents.addEvent(customEvent, customEventType); + } + var registry = domEvents._compatRegistry; + if (!registry) { + registry = domEvents._compatRegistry = {}; + } + if (registry[customEventType]) { + return function noopRemoveOverride() { + }; + } + registry[customEventType] = customEvent; + var newEvents = { + addEventListener: function () { + var data = removeDomContext(this, arguments); + return domEvents.addEventListener.apply(data.context, data.args); + }, + removeEventListener: function () { + var data = removeDomContext(this, arguments); + return domEvents.removeEventListener.apply(data.context, data.args); + }, + dispatch: function () { + var data = removeDomContext(this, arguments); + var eventData = data.args[0]; + var eventArgs = typeof eventData === 'object' ? eventData.args : []; + data.args.splice(1, 0, eventArgs); + return domEvents.dispatch.apply(data.context, data.args); + } + }; + var isOverriding = true; + var oldAddEventListener = domEvents.addEventListener; + var addEventListener = domEvents.addEventListener = function addEventListener(eventName) { + if (isOverriding && eventName === customEventType) { + var args = addDomContext(this, arguments); + customEvent.addEventListener.apply(newEvents, args); + } + return oldAddEventListener.apply(this, arguments); + }; + var oldRemoveEventListener = domEvents.removeEventListener; + var removeEventListener = domEvents.removeEventListener = function removeEventListener(eventName) { + if (isOverriding && eventName === customEventType) { + var args = addDomContext(this, arguments); + customEvent.removeEventListener.apply(newEvents, args); + } + return oldRemoveEventListener.apply(this, arguments); + }; + return function removeOverride() { + isOverriding = false; + registry[customEventType] = null; + if (domEvents.addEventListener === addEventListener) { + domEvents.addEventListener = oldAddEventListener; + } + if (domEvents.removeEventListener === removeEventListener) { + domEvents.removeEventListener = oldRemoveEventListener; + } + }; + }; +}); +/*can-dom-events@1.3.11#helpers/add-event-compat-test*/ +define('can-dom-events@1.3.11#helpers/add-event-compat-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './add-event-compat', + '../can-dom-events' +], function (require, exports, module) { + var unit = require('steal-qunit'); + var addEvent = require('./add-event-compat'); + var domEvents = require('../can-dom-events'); + var oldDomEventsMock = function (addSpy, removeSpy) { + return { + addEventListener: function () { + addSpy(this, arguments); + this.addEventListener.apply(this, arguments); + }, + removeEventListener: function () { + removeSpy(this, arguments); + this.removeEventListener.apply(this, arguments); + }, + dispatch: function () { + } + }; + }; + unit.module('add-event-compat'); + var mockEvent = function (addSpy, removeSpy) { + return { + defaultEventType: 'boi', + addEventListener: function (target, eventName, handler) { + addSpy(this, arguments); + this.addEventListener(target, 'boi2', handler); + }, + removeEventListener: function (target, eventName, handler) { + removeSpy(this, arguments); + this.removeEventListener(target, 'boi2', handler); + } + }; + }; + unit.test('should work with the can-dom-events', function (assert) { + assert.expect(1 + 2 * 4); + var input = document.createElement('input'); + var handler = function () { + assert.ok(true, 'handler should be called'); + }; + var customEventType = 'boi3'; + var hookSpy = function (context, args) { + assert.equal(context, domEvents, 'real domEvents should be context'); + var target = args[0]; + var eventType = args[1]; + var callback = args[2]; + assert.equal(target, input, 'input should be the target'); + assert.equal(eventType, customEventType, 'event type should match custom event type'); + assert.equal(callback, handler, 'callback should be the passed handler'); + }; + var event = mockEvent(hookSpy, hookSpy); + var removeEvent = addEvent(domEvents, event, customEventType); + domEvents.addEventListener(input, customEventType, handler); + domEvents.dispatch(input, 'boi2'); + domEvents.removeEventListener(input, customEventType, handler); + removeEvent(); + }); + unit.test('should work with the can-dom-events (no custom event type)', function (assert) { + assert.expect(1 + 2 * 4); + var input = document.createElement('input'); + var handler = function () { + assert.ok(true, 'handler should be called'); + }; + var customEventType = 'boi'; + var hookSpy = function (context, args) { + assert.equal(context, domEvents, 'real domEvents should be context'); + var target = args[0]; + var eventType = args[1]; + var callback = args[2]; + assert.equal(target, input, 'input should be the target'); + assert.equal(eventType, customEventType, 'event type should match custom event type'); + assert.equal(callback, handler, 'callback should be the passed handler'); + }; + var event = mockEvent(hookSpy, hookSpy); + var removeEvent = addEvent(domEvents, event); + domEvents.addEventListener(input, customEventType, handler); + domEvents.dispatch(input, 'boi2'); + domEvents.removeEventListener(input, customEventType, handler); + removeEvent(); + }); + unit.test('should work with the can-util/dom/events', function (assert) { + assert.expect(1 + 2 * (2 + 3)); + var input = document.createElement('input'); + var handler = function () { + assert.ok(true, 'handler should be called'); + }; + var customEventType = 'boi3'; + var eventsSpy = function (context, args) { + var target = context; + var eventType = args[0]; + var callback = args[1]; + if (eventType === customEventType) { + assert.equal(target, input, 'input should be the target'); + assert.equal(callback, handler, 'callback should be the passed handler'); + } + }; + var oldEvents = oldDomEventsMock(eventsSpy, eventsSpy); + var hookSpy = function (context, args) { + var target = args[0]; + var eventType = args[1]; + var callback = args[2]; + assert.equal(target, input, 'input should be the target'); + assert.equal(eventType, customEventType, 'event type should match custom event type'); + assert.equal(callback, handler, 'callback should be the passed handler'); + }; + var event = mockEvent(hookSpy, hookSpy); + var removeEvent = addEvent(oldEvents, event, customEventType); + oldEvents.addEventListener.call(input, customEventType, handler); + domEvents.dispatch(input, 'boi2'); + oldEvents.removeEventListener.call(input, customEventType, handler); + removeEvent(); + }); + unit.test('should work with the can-util/dom/events (no custom event type)', function (assert) { + assert.expect(1 + 2 * (2 + 3)); + var input = document.createElement('input'); + var handler = function () { + assert.ok(true, 'handler should be called'); + }; + var customEventType = 'boi'; + var eventsSpy = function (context, args) { + var target = context; + var eventType = args[0]; + var callback = args[1]; + if (eventType === customEventType) { + assert.equal(target, input, 'input should be the target'); + assert.equal(callback, handler, 'callback should be the passed handler'); + } + }; + var oldEvents = oldDomEventsMock(eventsSpy, eventsSpy); + var hookSpy = function (context, args) { + var target = args[0]; + var eventType = args[1]; + var callback = args[2]; + assert.equal(target, input, 'input should be the target'); + assert.equal(eventType, customEventType, 'event type should match custom event type'); + assert.equal(callback, handler, 'callback should be the passed handler'); + }; + var event = mockEvent(hookSpy, hookSpy); + var removeEvent = addEvent(oldEvents, event); + oldEvents.addEventListener.call(input, customEventType, handler); + domEvents.dispatch(input, 'boi2'); + oldEvents.removeEventListener.call(input, customEventType, handler); + removeEvent(); + }); + unit.test('should not override can-util/dom/events twice for the same eventType', function (assert) { + var done = assert.async(); + var input = document.createElement('input'); + var event = { + addEventListener: function (target, eventType, handler) { + target.addEventListener(eventType, handler); + }, + removeEventListener: function (target, eventType, handler) { + target.removeEventListener(eventType, handler); + } + }; + var eventsSpy = function () { + }; + var oldEvents = oldDomEventsMock(eventsSpy, eventsSpy); + var removeEvent1 = addEvent(oldEvents, event, 'foo'); + var removeEvent2 = addEvent(oldEvents, event, 'foo'); + var handler = function () { + removeEvent1(); + removeEvent2(); + assert.ok(true, 'This handler should only be called once'); + done(); + }; + oldEvents.addEventListener.call(input, 'foo', handler); + domEvents.dispatch(input, 'foo'); + oldEvents.removeEventListener.call(input, 'foo', handler); + }); +}); +/*jquery@3.6.0#dist/jquery*/ +(function (global, factory) { + 'use strict'; + if (typeof module === 'object' && typeof module.exports === 'object') { + module.exports = global.document ? factory(global, true) : function (w) { + if (!w.document) { + throw new Error('jQuery requires a window with a document'); + } + return factory(w); + }; + } else { + factory(global); + } +}(typeof window !== 'undefined' ? window : this, function (window, noGlobal) { + 'use strict'; + var arr = []; + var getProto = Object.getPrototypeOf; + var slice = arr.slice; + var flat = arr.flat ? function (array) { + return arr.flat.call(array); + } : function (array) { + return arr.concat.apply([], array); + }; + var push = arr.push; + var indexOf = arr.indexOf; + var class2type = {}; + var toString = class2type.toString; + var hasOwn = class2type.hasOwnProperty; + var fnToString = hasOwn.toString; + var ObjectFunctionString = fnToString.call(Object); + var support = {}; + var isFunction = function isFunction(obj) { + return typeof obj === 'function' && typeof obj.nodeType !== 'number' && typeof obj.item !== 'function'; + }; + var isWindow = function isWindow(obj) { + return obj != null && obj === obj.window; + }; + var document = window.document; + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + function DOMEval(code, node, doc) { + doc = doc || document; + var i, val, script = doc.createElement('script'); + script.text = code; + if (node) { + for (i in preservedScriptAttributes) { + val = node[i] || node.getAttribute && node.getAttribute(i); + if (val) { + script.setAttribute(i, val); + } + } + } + doc.head.appendChild(script).parentNode.removeChild(script); + } + function toType(obj) { + if (obj == null) { + return obj + ''; + } + return typeof obj === 'object' || typeof obj === 'function' ? class2type[toString.call(obj)] || 'object' : typeof obj; + } + var version = '3.6.0', jQuery = function (selector, context) { + return new jQuery.fn.init(selector, context); + }; + jQuery.fn = jQuery.prototype = { + jquery: version, + constructor: jQuery, + length: 0, + toArray: function () { + return slice.call(this); + }, + get: function (num) { + if (num == null) { + return slice.call(this); + } + return num < 0 ? this[num + this.length] : this[num]; + }, + pushStack: function (elems) { + var ret = jQuery.merge(this.constructor(), elems); + ret.prevObject = this; + return ret; + }, + each: function (callback) { + return jQuery.each(this, callback); + }, + map: function (callback) { + return this.pushStack(jQuery.map(this, function (elem, i) { + return callback.call(elem, i, elem); + })); + }, + slice: function () { + return this.pushStack(slice.apply(this, arguments)); + }, + first: function () { + return this.eq(0); + }, + last: function () { + return this.eq(-1); + }, + even: function () { + return this.pushStack(jQuery.grep(this, function (_elem, i) { + return (i + 1) % 2; + })); + }, + odd: function () { + return this.pushStack(jQuery.grep(this, function (_elem, i) { + return i % 2; + })); + }, + eq: function (i) { + var len = this.length, j = +i + (i < 0 ? len : 0); + return this.pushStack(j >= 0 && j < len ? [this[j]] : []); + }, + end: function () { + return this.prevObject || this.constructor(); + }, + push: push, + sort: arr.sort, + splice: arr.splice + }; + jQuery.extend = jQuery.fn.extend = function () { + var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; + if (typeof target === 'boolean') { + deep = target; + target = arguments[i] || {}; + i++; + } + if (typeof target !== 'object' && !isFunction(target)) { + target = {}; + } + if (i === length) { + target = this; + i--; + } + for (; i < length; i++) { + if ((options = arguments[i]) != null) { + for (name in options) { + copy = options[name]; + if (name === '__proto__' || target === copy) { + continue; + } + if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) { + src = target[name]; + if (copyIsArray && !Array.isArray(src)) { + clone = []; + } else if (!copyIsArray && !jQuery.isPlainObject(src)) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + target[name] = jQuery.extend(deep, clone, copy); + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + return target; + }; + jQuery.extend({ + expando: 'jQuery' + (version + Math.random()).replace(/\D/g, ''), + isReady: true, + error: function (msg) { + throw new Error(msg); + }, + noop: function () { + }, + isPlainObject: function (obj) { + var proto, Ctor; + if (!obj || toString.call(obj) !== '[object Object]') { + return false; + } + proto = getProto(obj); + if (!proto) { + return true; + } + Ctor = hasOwn.call(proto, 'constructor') && proto.constructor; + return typeof Ctor === 'function' && fnToString.call(Ctor) === ObjectFunctionString; + }, + isEmptyObject: function (obj) { + var name; + for (name in obj) { + return false; + } + return true; + }, + globalEval: function (code, options, doc) { + DOMEval(code, { nonce: options && options.nonce }, doc); + }, + each: function (obj, callback) { + var length, i = 0; + if (isArrayLike(obj)) { + length = obj.length; + for (; i < length; i++) { + if (callback.call(obj[i], i, obj[i]) === false) { + break; + } + } + } else { + for (i in obj) { + if (callback.call(obj[i], i, obj[i]) === false) { + break; + } + } + } + return obj; + }, + makeArray: function (arr, results) { + var ret = results || []; + if (arr != null) { + if (isArrayLike(Object(arr))) { + jQuery.merge(ret, typeof arr === 'string' ? [arr] : arr); + } else { + push.call(ret, arr); + } + } + return ret; + }, + inArray: function (elem, arr, i) { + return arr == null ? -1 : indexOf.call(arr, elem, i); + }, + merge: function (first, second) { + var len = +second.length, j = 0, i = first.length; + for (; j < len; j++) { + first[i++] = second[j]; + } + first.length = i; + return first; + }, + grep: function (elems, callback, invert) { + var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; + for (; i < length; i++) { + callbackInverse = !callback(elems[i], i); + if (callbackInverse !== callbackExpect) { + matches.push(elems[i]); + } + } + return matches; + }, + map: function (elems, callback, arg) { + var length, value, i = 0, ret = []; + if (isArrayLike(elems)) { + length = elems.length; + for (; i < length; i++) { + value = callback(elems[i], i, arg); + if (value != null) { + ret.push(value); + } + } + } else { + for (i in elems) { + value = callback(elems[i], i, arg); + if (value != null) { + ret.push(value); + } + } + } + return flat(ret); + }, + guid: 1, + support: support + }); + if (typeof Symbol === 'function') { + jQuery.fn[Symbol.iterator] = arr[Symbol.iterator]; + } + jQuery.each('Boolean Number String Function Array Date RegExp Object Error Symbol'.split(' '), function (_i, name) { + class2type['[object ' + name + ']'] = name.toLowerCase(); + }); + function isArrayLike(obj) { + var length = !!obj && 'length' in obj && obj.length, type = toType(obj); + if (isFunction(obj) || isWindow(obj)) { + return false; + } + return type === 'array' || length === 0 || typeof length === 'number' && length > 0 && length - 1 in obj; + } + var Sizzle = function (window) { + var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, expando = 'sizzle' + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), nonnativeSelectorCache = createCache(), sortOrder = function (a, b) { + if (a === b) { + hasDuplicate = true; + } + return 0; + }, hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, pushNative = arr.push, push = arr.push, slice = arr.slice, indexOf = function (list, elem) { + var i = 0, len = list.length; + for (; i < len; i++) { + if (list[i] === elem) { + return i; + } + } + return -1; + }, booleans = 'checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|' + 'ismap|loop|multiple|open|readonly|required|scoped', whitespace = '[\\x20\\t\\r\\n\\f]', identifier = '(?:\\\\[\\da-fA-F]{1,6}' + whitespace + '?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+', attributes = '\\[' + whitespace + '*(' + identifier + ')(?:' + whitespace + '*([*^$|!~]?=)' + whitespace + '*(?:\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)"|(' + identifier + '))|)' + whitespace + '*\\]', pseudos = ':(' + identifier + ')(?:\\((' + '(\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)")|' + '((?:\\\\.|[^\\\\()[\\]]|' + attributes + ')*)|' + '.*' + ')\\)|)', rwhitespace = new RegExp(whitespace + '+', 'g'), rtrim = new RegExp('^' + whitespace + '+|((?:^|[^\\\\])(?:\\\\.)*)' + whitespace + '+$', 'g'), rcomma = new RegExp('^' + whitespace + '*,' + whitespace + '*'), rcombinators = new RegExp('^' + whitespace + '*([>+~]|' + whitespace + ')' + whitespace + '*'), rdescend = new RegExp(whitespace + '|>'), rpseudo = new RegExp(pseudos), ridentifier = new RegExp('^' + identifier + '$'), matchExpr = { + 'ID': new RegExp('^#(' + identifier + ')'), + 'CLASS': new RegExp('^\\.(' + identifier + ')'), + 'TAG': new RegExp('^(' + identifier + '|[*])'), + 'ATTR': new RegExp('^' + attributes), + 'PSEUDO': new RegExp('^' + pseudos), + 'CHILD': new RegExp('^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(' + whitespace + '*(even|odd|(([+-]|)(\\d*)n|)' + whitespace + '*(?:([+-]|)' + whitespace + '*(\\d+)|))' + whitespace + '*\\)|)', 'i'), + 'bool': new RegExp('^(?:' + booleans + ')$', 'i'), + 'needsContext': new RegExp('^' + whitespace + '*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(' + whitespace + '*((?:-\\d)?\\d*)' + whitespace + '*\\)|)(?=[^-]|$)', 'i') + }, rhtml = /HTML$/i, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, runescape = new RegExp('\\\\[\\da-fA-F]{1,6}' + whitespace + '?|\\\\([^\\r\\n\\f])', 'g'), funescape = function (escape, nonHex) { + var high = '0x' + escape.slice(1) - 65536; + return nonHex ? nonHex : high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320); + }, rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function (ch, asCodePoint) { + if (asCodePoint) { + if (ch === '\0') { + return '\uFFFD'; + } + return ch.slice(0, -1) + '\\' + ch.charCodeAt(ch.length - 1).toString(16) + ' '; + } + return '\\' + ch; + }, unloadHandler = function () { + setDocument(); + }, inDisabledFieldset = addCombinator(function (elem) { + return elem.disabled === true && elem.nodeName.toLowerCase() === 'fieldset'; + }, { + dir: 'parentNode', + next: 'legend' + }); + try { + push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); + arr[preferredDoc.childNodes.length].nodeType; + } catch (e) { + push = { + apply: arr.length ? function (target, els) { + pushNative.apply(target, slice.call(els)); + } : function (target, els) { + var j = target.length, i = 0; + while (target[j++] = els[i++]) { + } + target.length = j - 1; + } + }; + } + function Sizzle(selector, context, results, seed) { + var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, nodeType = context ? context.nodeType : 9; + results = results || []; + if (typeof selector !== 'string' || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) { + return results; + } + if (!seed) { + setDocument(context); + context = context || document; + if (documentIsHTML) { + if (nodeType !== 11 && (match = rquickExpr.exec(selector))) { + if (m = match[1]) { + if (nodeType === 9) { + if (elem = context.getElementById(m)) { + if (elem.id === m) { + results.push(elem); + return results; + } + } else { + return results; + } + } else { + if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) { + results.push(elem); + return results; + } + } + } else if (match[2]) { + push.apply(results, context.getElementsByTagName(selector)); + return results; + } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) { + push.apply(results, context.getElementsByClassName(m)); + return results; + } + } + if (support.qsa && !nonnativeSelectorCache[selector + ' '] && (!rbuggyQSA || !rbuggyQSA.test(selector)) && (nodeType !== 1 || context.nodeName.toLowerCase() !== 'object')) { + newSelector = selector; + newContext = context; + if (nodeType === 1 && (rdescend.test(selector) || rcombinators.test(selector))) { + newContext = rsibling.test(selector) && testContext(context.parentNode) || context; + if (newContext !== context || !support.scope) { + if (nid = context.getAttribute('id')) { + nid = nid.replace(rcssescape, fcssescape); + } else { + context.setAttribute('id', nid = expando); + } + } + groups = tokenize(selector); + i = groups.length; + while (i--) { + groups[i] = (nid ? '#' + nid : ':scope') + ' ' + toSelector(groups[i]); + } + newSelector = groups.join(','); + } + try { + push.apply(results, newContext.querySelectorAll(newSelector)); + return results; + } catch (qsaError) { + nonnativeSelectorCache(selector, true); + } finally { + if (nid === expando) { + context.removeAttribute('id'); + } + } + } + } + } + return select(selector.replace(rtrim, '$1'), context, results, seed); + } + function createCache() { + var keys = []; + function cache(key, value) { + if (keys.push(key + ' ') > Expr.cacheLength) { + delete cache[keys.shift()]; + } + return cache[key + ' '] = value; + } + return cache; + } + function markFunction(fn) { + fn[expando] = true; + return fn; + } + function assert(fn) { + var el = document.createElement('fieldset'); + try { + return !!fn(el); + } catch (e) { + return false; + } finally { + if (el.parentNode) { + el.parentNode.removeChild(el); + } + el = null; + } + } + function addHandle(attrs, handler) { + var arr = attrs.split('|'), i = arr.length; + while (i--) { + Expr.attrHandle[arr[i]] = handler; + } + } + function siblingCheck(a, b) { + var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; + if (diff) { + return diff; + } + if (cur) { + while (cur = cur.nextSibling) { + if (cur === b) { + return -1; + } + } + } + return a ? 1 : -1; + } + function createInputPseudo(type) { + return function (elem) { + var name = elem.nodeName.toLowerCase(); + return name === 'input' && elem.type === type; + }; + } + function createButtonPseudo(type) { + return function (elem) { + var name = elem.nodeName.toLowerCase(); + return (name === 'input' || name === 'button') && elem.type === type; + }; + } + function createDisabledPseudo(disabled) { + return function (elem) { + if ('form' in elem) { + if (elem.parentNode && elem.disabled === false) { + if ('label' in elem) { + if ('label' in elem.parentNode) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + return elem.isDisabled === disabled || elem.isDisabled !== !disabled && inDisabledFieldset(elem) === disabled; + } + return elem.disabled === disabled; + } else if ('label' in elem) { + return elem.disabled === disabled; + } + return false; + }; + } + function createPositionalPseudo(fn) { + return markFunction(function (argument) { + argument = +argument; + return markFunction(function (seed, matches) { + var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length; + while (i--) { + if (seed[j = matchIndexes[i]]) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); + } + function testContext(context) { + return context && typeof context.getElementsByTagName !== 'undefined' && context; + } + support = Sizzle.support = {}; + isXML = Sizzle.isXML = function (elem) { + var namespace = elem && elem.namespaceURI, docElem = elem && (elem.ownerDocument || elem).documentElement; + return !rhtml.test(namespace || docElem && docElem.nodeName || 'HTML'); + }; + setDocument = Sizzle.setDocument = function (node) { + var hasCompare, subWindow, doc = node ? node.ownerDocument || node : preferredDoc; + if (doc == document || doc.nodeType !== 9 || !doc.documentElement) { + return document; + } + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML(document); + if (preferredDoc != document && (subWindow = document.defaultView) && subWindow.top !== subWindow) { + if (subWindow.addEventListener) { + subWindow.addEventListener('unload', unloadHandler, false); + } else if (subWindow.attachEvent) { + subWindow.attachEvent('onunload', unloadHandler); + } + } + support.scope = assert(function (el) { + docElem.appendChild(el).appendChild(document.createElement('div')); + return typeof el.querySelectorAll !== 'undefined' && !el.querySelectorAll(':scope fieldset div').length; + }); + support.attributes = assert(function (el) { + el.className = 'i'; + return !el.getAttribute('className'); + }); + support.getElementsByTagName = assert(function (el) { + el.appendChild(document.createComment('')); + return !el.getElementsByTagName('*').length; + }); + support.getElementsByClassName = rnative.test(document.getElementsByClassName); + support.getById = assert(function (el) { + docElem.appendChild(el).id = expando; + return !document.getElementsByName || !document.getElementsByName(expando).length; + }); + if (support.getById) { + Expr.filter['ID'] = function (id) { + var attrId = id.replace(runescape, funescape); + return function (elem) { + return elem.getAttribute('id') === attrId; + }; + }; + Expr.find['ID'] = function (id, context) { + if (typeof context.getElementById !== 'undefined' && documentIsHTML) { + var elem = context.getElementById(id); + return elem ? [elem] : []; + } + }; + } else { + Expr.filter['ID'] = function (id) { + var attrId = id.replace(runescape, funescape); + return function (elem) { + var node = typeof elem.getAttributeNode !== 'undefined' && elem.getAttributeNode('id'); + return node && node.value === attrId; + }; + }; + Expr.find['ID'] = function (id, context) { + if (typeof context.getElementById !== 'undefined' && documentIsHTML) { + var node, i, elems, elem = context.getElementById(id); + if (elem) { + node = elem.getAttributeNode('id'); + if (node && node.value === id) { + return [elem]; + } + elems = context.getElementsByName(id); + i = 0; + while (elem = elems[i++]) { + node = elem.getAttributeNode('id'); + if (node && node.value === id) { + return [elem]; + } + } + } + return []; + } + }; + } + Expr.find['TAG'] = support.getElementsByTagName ? function (tag, context) { + if (typeof context.getElementsByTagName !== 'undefined') { + return context.getElementsByTagName(tag); + } else if (support.qsa) { + return context.querySelectorAll(tag); + } + } : function (tag, context) { + var elem, tmp = [], i = 0, results = context.getElementsByTagName(tag); + if (tag === '*') { + while (elem = results[i++]) { + if (elem.nodeType === 1) { + tmp.push(elem); + } + } + return tmp; + } + return results; + }; + Expr.find['CLASS'] = support.getElementsByClassName && function (className, context) { + if (typeof context.getElementsByClassName !== 'undefined' && documentIsHTML) { + return context.getElementsByClassName(className); + } + }; + rbuggyMatches = []; + rbuggyQSA = []; + if (support.qsa = rnative.test(document.querySelectorAll)) { + assert(function (el) { + var input; + docElem.appendChild(el).innerHTML = '' + ''; + if (el.querySelectorAll('[msallowcapture^=\'\']').length) { + rbuggyQSA.push('[*^$]=' + whitespace + '*(?:\'\'|"")'); + } + if (!el.querySelectorAll('[selected]').length) { + rbuggyQSA.push('\\[' + whitespace + '*(?:value|' + booleans + ')'); + } + if (!el.querySelectorAll('[id~=' + expando + '-]').length) { + rbuggyQSA.push('~='); + } + input = document.createElement('input'); + input.setAttribute('name', ''); + el.appendChild(input); + if (!el.querySelectorAll('[name=\'\']').length) { + rbuggyQSA.push('\\[' + whitespace + '*name' + whitespace + '*=' + whitespace + '*(?:\'\'|"")'); + } + if (!el.querySelectorAll(':checked').length) { + rbuggyQSA.push(':checked'); + } + if (!el.querySelectorAll('a#' + expando + '+*').length) { + rbuggyQSA.push('.#.+[+~]'); + } + el.querySelectorAll('\\\f'); + rbuggyQSA.push('[\\r\\n\\f]'); + }); + assert(function (el) { + el.innerHTML = '' + ''; + var input = document.createElement('input'); + input.setAttribute('type', 'hidden'); + el.appendChild(input).setAttribute('name', 'D'); + if (el.querySelectorAll('[name=d]').length) { + rbuggyQSA.push('name' + whitespace + '*[*^$|!~]?='); + } + if (el.querySelectorAll(':enabled').length !== 2) { + rbuggyQSA.push(':enabled', ':disabled'); + } + docElem.appendChild(el).disabled = true; + if (el.querySelectorAll(':disabled').length !== 2) { + rbuggyQSA.push(':enabled', ':disabled'); + } + el.querySelectorAll('*,:x'); + rbuggyQSA.push(',.*:'); + }); + } + if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) { + assert(function (el) { + support.disconnectedMatch = matches.call(el, '*'); + matches.call(el, '[s!=\'\']:x'); + rbuggyMatches.push('!=', pseudos); + }); + } + rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join('|')); + rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join('|')); + hasCompare = rnative.test(docElem.compareDocumentPosition); + contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) { + var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; + return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16)); + } : function (a, b) { + if (b) { + while (b = b.parentNode) { + if (b === a) { + return true; + } + } + } + return false; + }; + sortOrder = hasCompare ? function (a, b) { + if (a === b) { + hasDuplicate = true; + return 0; + } + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if (compare) { + return compare; + } + compare = (a.ownerDocument || a) == (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1; + if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) { + if (a == document || a.ownerDocument == preferredDoc && contains(preferredDoc, a)) { + return -1; + } + if (b == document || b.ownerDocument == preferredDoc && contains(preferredDoc, b)) { + return 1; + } + return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; + } + return compare & 4 ? -1 : 1; + } : function (a, b) { + if (a === b) { + hasDuplicate = true; + return 0; + } + var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b]; + if (!aup || !bup) { + return a == document ? -1 : b == document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; + } else if (aup === bup) { + return siblingCheck(a, b); + } + cur = a; + while (cur = cur.parentNode) { + ap.unshift(cur); + } + cur = b; + while (cur = cur.parentNode) { + bp.unshift(cur); + } + while (ap[i] === bp[i]) { + i++; + } + return i ? siblingCheck(ap[i], bp[i]) : ap[i] == preferredDoc ? -1 : bp[i] == preferredDoc ? 1 : 0; + }; + return document; + }; + Sizzle.matches = function (expr, elements) { + return Sizzle(expr, null, null, elements); + }; + Sizzle.matchesSelector = function (elem, expr) { + setDocument(elem); + if (support.matchesSelector && documentIsHTML && !nonnativeSelectorCache[expr + ' '] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) { + try { + var ret = matches.call(elem, expr); + if (ret || support.disconnectedMatch || elem.document && elem.document.nodeType !== 11) { + return ret; + } + } catch (e) { + nonnativeSelectorCache(expr, true); + } + } + return Sizzle(expr, document, null, [elem]).length > 0; + }; + Sizzle.contains = function (context, elem) { + if ((context.ownerDocument || context) != document) { + setDocument(context); + } + return contains(context, elem); + }; + Sizzle.attr = function (elem, name) { + if ((elem.ownerDocument || elem) != document) { + setDocument(elem); + } + var fn = Expr.attrHandle[name.toLowerCase()], val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined; + return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; + }; + Sizzle.escape = function (sel) { + return (sel + '').replace(rcssescape, fcssescape); + }; + Sizzle.error = function (msg) { + throw new Error('Syntax error, unrecognized expression: ' + msg); + }; + Sizzle.uniqueSort = function (results) { + var elem, duplicates = [], j = 0, i = 0; + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice(0); + results.sort(sortOrder); + if (hasDuplicate) { + while (elem = results[i++]) { + if (elem === results[i]) { + j = duplicates.push(i); + } + } + while (j--) { + results.splice(duplicates[j], 1); + } + } + sortInput = null; + return results; + }; + getText = Sizzle.getText = function (elem) { + var node, ret = '', i = 0, nodeType = elem.nodeType; + if (!nodeType) { + while (node = elem[i++]) { + ret += getText(node); + } + } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) { + if (typeof elem.textContent === 'string') { + return elem.textContent; + } else { + for (elem = elem.firstChild; elem; elem = elem.nextSibling) { + ret += getText(elem); + } + } + } else if (nodeType === 3 || nodeType === 4) { + return elem.nodeValue; + } + return ret; + }; + Expr = Sizzle.selectors = { + cacheLength: 50, + createPseudo: markFunction, + match: matchExpr, + attrHandle: {}, + find: {}, + relative: { + '>': { + dir: 'parentNode', + first: true + }, + ' ': { dir: 'parentNode' }, + '+': { + dir: 'previousSibling', + first: true + }, + '~': { dir: 'previousSibling' } + }, + preFilter: { + 'ATTR': function (match) { + match[1] = match[1].replace(runescape, funescape); + match[3] = (match[3] || match[4] || match[5] || '').replace(runescape, funescape); + if (match[2] === '~=') { + match[3] = ' ' + match[3] + ' '; + } + return match.slice(0, 4); + }, + 'CHILD': function (match) { + match[1] = match[1].toLowerCase(); + if (match[1].slice(0, 3) === 'nth') { + if (!match[3]) { + Sizzle.error(match[0]); + } + match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === 'even' || match[3] === 'odd')); + match[5] = +(match[7] + match[8] || match[3] === 'odd'); + } else if (match[3]) { + Sizzle.error(match[0]); + } + return match; + }, + 'PSEUDO': function (match) { + var excess, unquoted = !match[6] && match[2]; + if (matchExpr['CHILD'].test(match[0])) { + return null; + } + if (match[3]) { + match[2] = match[4] || match[5] || ''; + } else if (unquoted && rpseudo.test(unquoted) && (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(')', unquoted.length - excess) - unquoted.length)) { + match[0] = match[0].slice(0, excess); + match[2] = unquoted.slice(0, excess); + } + return match.slice(0, 3); + } + }, + filter: { + 'TAG': function (nodeNameSelector) { + var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase(); + return nodeNameSelector === '*' ? function () { + return true; + } : function (elem) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + 'CLASS': function (className) { + var pattern = classCache[className + ' ']; + return pattern || (pattern = new RegExp('(^|' + whitespace + ')' + className + '(' + whitespace + '|$)')) && classCache(className, function (elem) { + return pattern.test(typeof elem.className === 'string' && elem.className || typeof elem.getAttribute !== 'undefined' && elem.getAttribute('class') || ''); + }); + }, + 'ATTR': function (name, operator, check) { + return function (elem) { + var result = Sizzle.attr(elem, name); + if (result == null) { + return operator === '!='; + } + if (!operator) { + return true; + } + result += ''; + return operator === '=' ? result === check : operator === '!=' ? result !== check : operator === '^=' ? check && result.indexOf(check) === 0 : operator === '*=' ? check && result.indexOf(check) > -1 : operator === '$=' ? check && result.slice(-check.length) === check : operator === '~=' ? (' ' + result.replace(rwhitespace, ' ') + ' ').indexOf(check) > -1 : operator === '|=' ? result === check || result.slice(0, check.length + 1) === check + '-' : false; + }; + }, + 'CHILD': function (type, what, _argument, first, last) { + var simple = type.slice(0, 3) !== 'nth', forward = type.slice(-4) !== 'last', ofType = what === 'of-type'; + return first === 1 && last === 0 ? function (elem) { + return !!elem.parentNode; + } : function (elem, _context, xml) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? 'nextSibling' : 'previousSibling', parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; + if (parent) { + if (simple) { + while (dir) { + node = elem; + while (node = node[dir]) { + if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) { + return false; + } + } + start = dir = type === 'only' && !start && 'nextSibling'; + } + return true; + } + start = [forward ? parent.firstChild : parent.lastChild]; + if (forward && useCache) { + node = parent; + outerCache = node[expando] || (node[expando] = {}); + uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); + cache = uniqueCache[type] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = nodeIndex && cache[2]; + node = nodeIndex && parent.childNodes[nodeIndex]; + while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { + if (node.nodeType === 1 && ++diff && node === elem) { + uniqueCache[type] = [ + dirruns, + nodeIndex, + diff + ]; + break; + } + } + } else { + if (useCache) { + node = elem; + outerCache = node[expando] || (node[expando] = {}); + uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); + cache = uniqueCache[type] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = nodeIndex; + } + if (diff === false) { + while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) { + if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) { + if (useCache) { + outerCache = node[expando] || (node[expando] = {}); + uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {}); + uniqueCache[type] = [ + dirruns, + diff + ]; + } + if (node === elem) { + break; + } + } + } + } + } + diff -= last; + return diff === first || diff % first === 0 && diff / first >= 0; + } + }; + }, + 'PSEUDO': function (pseudo, argument) { + var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error('unsupported pseudo: ' + pseudo); + if (fn[expando]) { + return fn(argument); + } + if (fn.length > 1) { + args = [ + pseudo, + pseudo, + '', + argument + ]; + return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) { + var idx, matched = fn(seed, argument), i = matched.length; + while (i--) { + idx = indexOf(seed, matched[i]); + seed[idx] = !(matches[idx] = matched[i]); + } + }) : function (elem) { + return fn(elem, 0, args); + }; + } + return fn; + } + }, + pseudos: { + 'not': markFunction(function (selector) { + var input = [], results = [], matcher = compile(selector.replace(rtrim, '$1')); + return matcher[expando] ? markFunction(function (seed, matches, _context, xml) { + var elem, unmatched = matcher(seed, null, xml, []), i = seed.length; + while (i--) { + if (elem = unmatched[i]) { + seed[i] = !(matches[i] = elem); + } + } + }) : function (elem, _context, xml) { + input[0] = elem; + matcher(input, null, xml, results); + input[0] = null; + return !results.pop(); + }; + }), + 'has': markFunction(function (selector) { + return function (elem) { + return Sizzle(selector, elem).length > 0; + }; + }), + 'contains': markFunction(function (text) { + text = text.replace(runescape, funescape); + return function (elem) { + return (elem.textContent || getText(elem)).indexOf(text) > -1; + }; + }), + 'lang': markFunction(function (lang) { + if (!ridentifier.test(lang || '')) { + Sizzle.error('unsupported lang: ' + lang); + } + lang = lang.replace(runescape, funescape).toLowerCase(); + return function (elem) { + var elemLang; + do { + if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute('xml:lang') || elem.getAttribute('lang')) { + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf(lang + '-') === 0; + } + } while ((elem = elem.parentNode) && elem.nodeType === 1); + return false; + }; + }), + 'target': function (elem) { + var hash = window.location && window.location.hash; + return hash && hash.slice(1) === elem.id; + }, + 'root': function (elem) { + return elem === docElem; + }, + 'focus': function (elem) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + 'enabled': createDisabledPseudo(false), + 'disabled': createDisabledPseudo(true), + 'checked': function (elem) { + var nodeName = elem.nodeName.toLowerCase(); + return nodeName === 'input' && !!elem.checked || nodeName === 'option' && !!elem.selected; + }, + 'selected': function (elem) { + if (elem.parentNode) { + elem.parentNode.selectedIndex; + } + return elem.selected === true; + }, + 'empty': function (elem) { + for (elem = elem.firstChild; elem; elem = elem.nextSibling) { + if (elem.nodeType < 6) { + return false; + } + } + return true; + }, + 'parent': function (elem) { + return !Expr.pseudos['empty'](elem); + }, + 'header': function (elem) { + return rheader.test(elem.nodeName); + }, + 'input': function (elem) { + return rinputs.test(elem.nodeName); + }, + 'button': function (elem) { + var name = elem.nodeName.toLowerCase(); + return name === 'input' && elem.type === 'button' || name === 'button'; + }, + 'text': function (elem) { + var attr; + return elem.nodeName.toLowerCase() === 'input' && elem.type === 'text' && ((attr = elem.getAttribute('type')) == null || attr.toLowerCase() === 'text'); + }, + 'first': createPositionalPseudo(function () { + return [0]; + }), + 'last': createPositionalPseudo(function (_matchIndexes, length) { + return [length - 1]; + }), + 'eq': createPositionalPseudo(function (_matchIndexes, length, argument) { + return [argument < 0 ? argument + length : argument]; + }), + 'even': createPositionalPseudo(function (matchIndexes, length) { + var i = 0; + for (; i < length; i += 2) { + matchIndexes.push(i); + } + return matchIndexes; + }), + 'odd': createPositionalPseudo(function (matchIndexes, length) { + var i = 1; + for (; i < length; i += 2) { + matchIndexes.push(i); + } + return matchIndexes; + }), + 'lt': createPositionalPseudo(function (matchIndexes, length, argument) { + var i = argument < 0 ? argument + length : argument > length ? length : argument; + for (; --i >= 0;) { + matchIndexes.push(i); + } + return matchIndexes; + }), + 'gt': createPositionalPseudo(function (matchIndexes, length, argument) { + var i = argument < 0 ? argument + length : argument; + for (; ++i < length;) { + matchIndexes.push(i); + } + return matchIndexes; + }) + } + }; + Expr.pseudos['nth'] = Expr.pseudos['eq']; + for (i in { + radio: true, + checkbox: true, + file: true, + password: true, + image: true + }) { + Expr.pseudos[i] = createInputPseudo(i); + } + for (i in { + submit: true, + reset: true + }) { + Expr.pseudos[i] = createButtonPseudo(i); + } + function setFilters() { + } + setFilters.prototype = Expr.filters = Expr.pseudos; + Expr.setFilters = new setFilters(); + tokenize = Sizzle.tokenize = function (selector, parseOnly) { + var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + ' ']; + if (cached) { + return parseOnly ? 0 : cached.slice(0); + } + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + while (soFar) { + if (!matched || (match = rcomma.exec(soFar))) { + if (match) { + soFar = soFar.slice(match[0].length) || soFar; + } + groups.push(tokens = []); + } + matched = false; + if (match = rcombinators.exec(soFar)) { + matched = match.shift(); + tokens.push({ + value: matched, + type: match[0].replace(rtrim, ' ') + }); + soFar = soFar.slice(matched.length); + } + for (type in Expr.filter) { + if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice(matched.length); + } + } + if (!matched) { + break; + } + } + return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : tokenCache(selector, groups).slice(0); + }; + function toSelector(tokens) { + var i = 0, len = tokens.length, selector = ''; + for (; i < len; i++) { + selector += tokens[i].value; + } + return selector; + } + function addCombinator(matcher, combinator, base) { + var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === 'parentNode', doneName = done++; + return combinator.first ? function (elem, context, xml) { + while (elem = elem[dir]) { + if (elem.nodeType === 1 || checkNonElements) { + return matcher(elem, context, xml); + } + } + return false; + } : function (elem, context, xml) { + var oldCache, uniqueCache, outerCache, newCache = [ + dirruns, + doneName + ]; + if (xml) { + while (elem = elem[dir]) { + if (elem.nodeType === 1 || checkNonElements) { + if (matcher(elem, context, xml)) { + return true; + } + } + } + } else { + while (elem = elem[dir]) { + if (elem.nodeType === 1 || checkNonElements) { + outerCache = elem[expando] || (elem[expando] = {}); + uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {}); + if (skip && skip === elem.nodeName.toLowerCase()) { + elem = elem[dir] || elem; + } else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) { + return newCache[2] = oldCache[2]; + } else { + uniqueCache[key] = newCache; + if (newCache[2] = matcher(elem, context, xml)) { + return true; + } + } + } + } + } + return false; + }; + } + function elementMatcher(matchers) { + return matchers.length > 1 ? function (elem, context, xml) { + var i = matchers.length; + while (i--) { + if (!matchers[i](elem, context, xml)) { + return false; + } + } + return true; + } : matchers[0]; + } + function multipleContexts(selector, contexts, results) { + var i = 0, len = contexts.length; + for (; i < len; i++) { + Sizzle(selector, contexts[i], results); + } + return results; + } + function condense(unmatched, map, filter, context, xml) { + var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; + for (; i < len; i++) { + if (elem = unmatched[i]) { + if (!filter || filter(elem, context, xml)) { + newUnmatched.push(elem); + if (mapped) { + map.push(i); + } + } + } + } + return newUnmatched; + } + function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) { + if (postFilter && !postFilter[expando]) { + postFilter = setMatcher(postFilter); + } + if (postFinder && !postFinder[expando]) { + postFinder = setMatcher(postFinder, postSelector); + } + return markFunction(function (seed, results, context, xml) { + var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, elems = seed || multipleContexts(selector || '*', context.nodeType ? [context] : context, []), matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, matcherOut = matcher ? postFinder || (seed ? preFilter : preexisting || postFilter) ? [] : results : matcherIn; + if (matcher) { + matcher(matcherIn, matcherOut, context, xml); + } + if (postFilter) { + temp = condense(matcherOut, postMap); + postFilter(temp, [], context, xml); + i = temp.length; + while (i--) { + if (elem = temp[i]) { + matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem); + } + } + } + if (seed) { + if (postFinder || preFilter) { + if (postFinder) { + temp = []; + i = matcherOut.length; + while (i--) { + if (elem = matcherOut[i]) { + temp.push(matcherIn[i] = elem); + } + } + postFinder(null, matcherOut = [], temp, xml); + } + i = matcherOut.length; + while (i--) { + if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) { + seed[temp] = !(results[temp] = elem); + } + } + } + } else { + matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut); + if (postFinder) { + postFinder(null, results, matcherOut, xml); + } else { + push.apply(results, matcherOut); + } + } + }); + } + function matcherFromTokens(tokens) { + var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative || Expr.relative[' '], i = leadingRelative ? 1 : 0, matchContext = addCombinator(function (elem) { + return elem === checkContext; + }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) { + return indexOf(checkContext, elem) > -1; + }, implicitRelative, true), matchers = [function (elem, context, xml) { + var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); + checkContext = null; + return ret; + }]; + for (; i < len; i++) { + if (matcher = Expr.relative[tokens[i].type]) { + matchers = [addCombinator(elementMatcher(matchers), matcher)]; + } else { + matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); + if (matcher[expando]) { + j = ++i; + for (; j < len; j++) { + if (Expr.relative[tokens[j].type]) { + break; + } + } + return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === ' ' ? '*' : '' })).replace(rtrim, '$1'), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens)); + } + matchers.push(matcher); + } + } + return elementMatcher(matchers); + } + function matcherFromGroupMatchers(elementMatchers, setMatchers) { + var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function (seed, context, xml, results, outermost) { + var elem, j, matcher, matchedCount = 0, i = '0', unmatched = seed && [], setMatched = [], contextBackup = outermostContext, elems = seed || byElement && Expr.find['TAG']('*', outermost), dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, len = elems.length; + if (outermost) { + outermostContext = context == document || context || outermost; + } + for (; i !== len && (elem = elems[i]) != null; i++) { + if (byElement && elem) { + j = 0; + if (!context && elem.ownerDocument != document) { + setDocument(elem); + xml = !documentIsHTML; + } + while (matcher = elementMatchers[j++]) { + if (matcher(elem, context || document, xml)) { + results.push(elem); + break; + } + } + if (outermost) { + dirruns = dirrunsUnique; + } + } + if (bySet) { + if (elem = !matcher && elem) { + matchedCount--; + } + if (seed) { + unmatched.push(elem); + } + } + } + matchedCount += i; + if (bySet && i !== matchedCount) { + j = 0; + while (matcher = setMatchers[j++]) { + matcher(unmatched, setMatched, context, xml); + } + if (seed) { + if (matchedCount > 0) { + while (i--) { + if (!(unmatched[i] || setMatched[i])) { + setMatched[i] = pop.call(results); + } + } + } + setMatched = condense(setMatched); + } + push.apply(results, setMatched); + if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) { + Sizzle.uniqueSort(results); + } + } + if (outermost) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + return unmatched; + }; + return bySet ? markFunction(superMatcher) : superMatcher; + } + compile = Sizzle.compile = function (selector, match) { + var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + ' ']; + if (!cached) { + if (!match) { + match = tokenize(selector); + } + i = match.length; + while (i--) { + cached = matcherFromTokens(match[i]); + if (cached[expando]) { + setMatchers.push(cached); + } else { + elementMatchers.push(cached); + } + } + cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); + cached.selector = selector; + } + return cached; + }; + select = Sizzle.select = function (selector, context, results, seed) { + var i, tokens, token, type, find, compiled = typeof selector === 'function' && selector, match = !seed && tokenize(selector = compiled.selector || selector); + results = results || []; + if (match.length === 1) { + tokens = match[0] = match[0].slice(0); + if (tokens.length > 2 && (token = tokens[0]).type === 'ID' && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) { + context = (Expr.find['ID'](token.matches[0].replace(runescape, funescape), context) || [])[0]; + if (!context) { + return results; + } else if (compiled) { + context = context.parentNode; + } + selector = selector.slice(tokens.shift().value.length); + } + i = matchExpr['needsContext'].test(selector) ? 0 : tokens.length; + while (i--) { + token = tokens[i]; + if (Expr.relative[type = token.type]) { + break; + } + if (find = Expr.find[type]) { + if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) { + tokens.splice(i, 1); + selector = seed.length && toSelector(tokens); + if (!selector) { + push.apply(results, seed); + return results; + } + break; + } + } + } + } + (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context); + return results; + }; + support.sortStable = expando.split('').sort(sortOrder).join('') === expando; + support.detectDuplicates = !!hasDuplicate; + setDocument(); + support.sortDetached = assert(function (el) { + return el.compareDocumentPosition(document.createElement('fieldset')) & 1; + }); + if (!assert(function (el) { + el.innerHTML = ''; + return el.firstChild.getAttribute('href') === '#'; + })) { + addHandle('type|href|height|width', function (elem, name, isXML) { + if (!isXML) { + return elem.getAttribute(name, name.toLowerCase() === 'type' ? 1 : 2); + } + }); + } + if (!support.attributes || !assert(function (el) { + el.innerHTML = ''; + el.firstChild.setAttribute('value', ''); + return el.firstChild.getAttribute('value') === ''; + })) { + addHandle('value', function (elem, _name, isXML) { + if (!isXML && elem.nodeName.toLowerCase() === 'input') { + return elem.defaultValue; + } + }); + } + if (!assert(function (el) { + return el.getAttribute('disabled') == null; + })) { + addHandle(booleans, function (elem, name, isXML) { + var val; + if (!isXML) { + return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null; + } + }); + } + return Sizzle; + }(window); + jQuery.find = Sizzle; + jQuery.expr = Sizzle.selectors; + jQuery.expr[':'] = jQuery.expr.pseudos; + jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; + jQuery.text = Sizzle.getText; + jQuery.isXMLDoc = Sizzle.isXML; + jQuery.contains = Sizzle.contains; + jQuery.escapeSelector = Sizzle.escape; + var dir = function (elem, dir, until) { + var matched = [], truncate = until !== undefined; + while ((elem = elem[dir]) && elem.nodeType !== 9) { + if (elem.nodeType === 1) { + if (truncate && jQuery(elem).is(until)) { + break; + } + matched.push(elem); + } + } + return matched; + }; + var siblings = function (n, elem) { + var matched = []; + for (; n; n = n.nextSibling) { + if (n.nodeType === 1 && n !== elem) { + matched.push(n); + } + } + return matched; + }; + var rneedsContext = jQuery.expr.match.needsContext; + function nodeName(elem, name) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + } + var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; + function winnow(elements, qualifier, not) { + if (isFunction(qualifier)) { + return jQuery.grep(elements, function (elem, i) { + return !!qualifier.call(elem, i, elem) !== not; + }); + } + if (qualifier.nodeType) { + return jQuery.grep(elements, function (elem) { + return elem === qualifier !== not; + }); + } + if (typeof qualifier !== 'string') { + return jQuery.grep(elements, function (elem) { + return indexOf.call(qualifier, elem) > -1 !== not; + }); + } + return jQuery.filter(qualifier, elements, not); + } + jQuery.filter = function (expr, elems, not) { + var elem = elems[0]; + if (not) { + expr = ':not(' + expr + ')'; + } + if (elems.length === 1 && elem.nodeType === 1) { + return jQuery.find.matchesSelector(elem, expr) ? [elem] : []; + } + return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) { + return elem.nodeType === 1; + })); + }; + jQuery.fn.extend({ + find: function (selector) { + var i, ret, len = this.length, self = this; + if (typeof selector !== 'string') { + return this.pushStack(jQuery(selector).filter(function () { + for (i = 0; i < len; i++) { + if (jQuery.contains(self[i], this)) { + return true; + } + } + })); + } + ret = this.pushStack([]); + for (i = 0; i < len; i++) { + jQuery.find(selector, self[i], ret); + } + return len > 1 ? jQuery.uniqueSort(ret) : ret; + }, + filter: function (selector) { + return this.pushStack(winnow(this, selector || [], false)); + }, + not: function (selector) { + return this.pushStack(winnow(this, selector || [], true)); + }, + is: function (selector) { + return !!winnow(this, typeof selector === 'string' && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length; + } + }); + var rootjQuery, rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function (selector, context, root) { + var match, elem; + if (!selector) { + return this; + } + root = root || rootjQuery; + if (typeof selector === 'string') { + if (selector[0] === '<' && selector[selector.length - 1] === '>' && selector.length >= 3) { + match = [ + null, + selector, + null + ]; + } else { + match = rquickExpr.exec(selector); + } + if (match && (match[1] || !context)) { + if (match[1]) { + context = context instanceof jQuery ? context[0] : context; + jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true)); + if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) { + for (match in context) { + if (isFunction(this[match])) { + this[match](context[match]); + } else { + this.attr(match, context[match]); + } + } + } + return this; + } else { + elem = document.getElementById(match[2]); + if (elem) { + this[0] = elem; + this.length = 1; + } + return this; + } + } else if (!context || context.jquery) { + return (context || root).find(selector); + } else { + return this.constructor(context).find(selector); + } + } else if (selector.nodeType) { + this[0] = selector; + this.length = 1; + return this; + } else if (isFunction(selector)) { + return root.ready !== undefined ? root.ready(selector) : selector(jQuery); + } + return jQuery.makeArray(selector, this); + }; + init.prototype = jQuery.fn; + rootjQuery = jQuery(document); + var rparentsprev = /^(?:parents|prev(?:Until|All))/, guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + jQuery.fn.extend({ + has: function (target) { + var targets = jQuery(target, this), l = targets.length; + return this.filter(function () { + var i = 0; + for (; i < l; i++) { + if (jQuery.contains(this, targets[i])) { + return true; + } + } + }); + }, + closest: function (selectors, context) { + var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== 'string' && jQuery(selectors); + if (!rneedsContext.test(selectors)) { + for (; i < l; i++) { + for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) { + if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 : cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) { + matched.push(cur); + break; + } + } + } + } + return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched); + }, + index: function (elem) { + if (!elem) { + return this[0] && this[0].parentNode ? this.first().prevAll().length : -1; + } + if (typeof elem === 'string') { + return indexOf.call(jQuery(elem), this[0]); + } + return indexOf.call(this, elem.jquery ? elem[0] : elem); + }, + add: function (selector, context) { + return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context)))); + }, + addBack: function (selector) { + return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector)); + } + }); + function sibling(cur, dir) { + while ((cur = cur[dir]) && cur.nodeType !== 1) { + } + return cur; + } + jQuery.each({ + parent: function (elem) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function (elem) { + return dir(elem, 'parentNode'); + }, + parentsUntil: function (elem, _i, until) { + return dir(elem, 'parentNode', until); + }, + next: function (elem) { + return sibling(elem, 'nextSibling'); + }, + prev: function (elem) { + return sibling(elem, 'previousSibling'); + }, + nextAll: function (elem) { + return dir(elem, 'nextSibling'); + }, + prevAll: function (elem) { + return dir(elem, 'previousSibling'); + }, + nextUntil: function (elem, _i, until) { + return dir(elem, 'nextSibling', until); + }, + prevUntil: function (elem, _i, until) { + return dir(elem, 'previousSibling', until); + }, + siblings: function (elem) { + return siblings((elem.parentNode || {}).firstChild, elem); + }, + children: function (elem) { + return siblings(elem.firstChild); + }, + contents: function (elem) { + if (elem.contentDocument != null && getProto(elem.contentDocument)) { + return elem.contentDocument; + } + if (nodeName(elem, 'template')) { + elem = elem.content || elem; + } + return jQuery.merge([], elem.childNodes); + } + }, function (name, fn) { + jQuery.fn[name] = function (until, selector) { + var matched = jQuery.map(this, fn, until); + if (name.slice(-5) !== 'Until') { + selector = until; + } + if (selector && typeof selector === 'string') { + matched = jQuery.filter(selector, matched); + } + if (this.length > 1) { + if (!guaranteedUnique[name]) { + jQuery.uniqueSort(matched); + } + if (rparentsprev.test(name)) { + matched.reverse(); + } + } + return this.pushStack(matched); + }; + }); + var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; + function createOptions(options) { + var object = {}; + jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) { + object[flag] = true; + }); + return object; + } + jQuery.Callbacks = function (options) { + options = typeof options === 'string' ? createOptions(options) : jQuery.extend({}, options); + var firing, memory, fired, locked, list = [], queue = [], firingIndex = -1, fire = function () { + locked = locked || options.once; + fired = firing = true; + for (; queue.length; firingIndex = -1) { + memory = queue.shift(); + while (++firingIndex < list.length) { + if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) { + firingIndex = list.length; + memory = false; + } + } + } + if (!options.memory) { + memory = false; + } + firing = false; + if (locked) { + if (memory) { + list = []; + } else { + list = ''; + } + } + }, self = { + add: function () { + if (list) { + if (memory && !firing) { + firingIndex = list.length - 1; + queue.push(memory); + } + (function add(args) { + jQuery.each(args, function (_, arg) { + if (isFunction(arg)) { + if (!options.unique || !self.has(arg)) { + list.push(arg); + } + } else if (arg && arg.length && toType(arg) !== 'string') { + add(arg); + } + }); + }(arguments)); + if (memory && !firing) { + fire(); + } + } + return this; + }, + remove: function () { + jQuery.each(arguments, function (_, arg) { + var index; + while ((index = jQuery.inArray(arg, list, index)) > -1) { + list.splice(index, 1); + if (index <= firingIndex) { + firingIndex--; + } + } + }); + return this; + }, + has: function (fn) { + return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0; + }, + empty: function () { + if (list) { + list = []; + } + return this; + }, + disable: function () { + locked = queue = []; + list = memory = ''; + return this; + }, + disabled: function () { + return !list; + }, + lock: function () { + locked = queue = []; + if (!memory && !firing) { + list = memory = ''; + } + return this; + }, + locked: function () { + return !!locked; + }, + fireWith: function (context, args) { + if (!locked) { + args = args || []; + args = [ + context, + args.slice ? args.slice() : args + ]; + queue.push(args); + if (!firing) { + fire(); + } + } + return this; + }, + fire: function () { + self.fireWith(this, arguments); + return this; + }, + fired: function () { + return !!fired; + } + }; + return self; + }; + function Identity(v) { + return v; + } + function Thrower(ex) { + throw ex; + } + function adoptValue(value, resolve, reject, noValue) { + var method; + try { + if (value && isFunction(method = value.promise)) { + method.call(value).done(resolve).fail(reject); + } else if (value && isFunction(method = value.then)) { + method.call(value, resolve, reject); + } else { + resolve.apply(undefined, [value].slice(noValue)); + } + } catch (value) { + reject.apply(undefined, [value]); + } + } + jQuery.extend({ + Deferred: function (func) { + var tuples = [ + [ + 'notify', + 'progress', + jQuery.Callbacks('memory'), + jQuery.Callbacks('memory'), + 2 + ], + [ + 'resolve', + 'done', + jQuery.Callbacks('once memory'), + jQuery.Callbacks('once memory'), + 0, + 'resolved' + ], + [ + 'reject', + 'fail', + jQuery.Callbacks('once memory'), + jQuery.Callbacks('once memory'), + 1, + 'rejected' + ] + ], state = 'pending', promise = { + state: function () { + return state; + }, + always: function () { + deferred.done(arguments).fail(arguments); + return this; + }, + 'catch': function (fn) { + return promise.then(null, fn); + }, + pipe: function () { + var fns = arguments; + return jQuery.Deferred(function (newDefer) { + jQuery.each(tuples, function (_i, tuple) { + var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; + deferred[tuple[1]](function () { + var returned = fn && fn.apply(this, arguments); + if (returned && isFunction(returned.promise)) { + returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject); + } else { + newDefer[tuple[0] + 'With'](this, fn ? [returned] : arguments); + } + }); + }); + fns = null; + }).promise(); + }, + then: function (onFulfilled, onRejected, onProgress) { + var maxDepth = 0; + function resolve(depth, deferred, handler, special) { + return function () { + var that = this, args = arguments, mightThrow = function () { + var returned, then; + if (depth < maxDepth) { + return; + } + returned = handler.apply(that, args); + if (returned === deferred.promise()) { + throw new TypeError('Thenable self-resolution'); + } + then = returned && (typeof returned === 'object' || typeof returned === 'function') && returned.then; + if (isFunction(then)) { + if (special) { + then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special)); + } else { + maxDepth++; + then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith)); + } + } else { + if (handler !== Identity) { + that = undefined; + args = [returned]; + } + (special || deferred.resolveWith)(that, args); + } + }, process = special ? mightThrow : function () { + try { + mightThrow(); + } catch (e) { + if (jQuery.Deferred.exceptionHook) { + jQuery.Deferred.exceptionHook(e, process.stackTrace); + } + if (depth + 1 >= maxDepth) { + if (handler !== Thrower) { + that = undefined; + args = [e]; + } + deferred.rejectWith(that, args); + } + } + }; + if (depth) { + process(); + } else { + if (jQuery.Deferred.getStackHook) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout(process); + } + }; + } + return jQuery.Deferred(function (newDefer) { + tuples[0][3].add(resolve(0, newDefer, isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith)); + tuples[1][3].add(resolve(0, newDefer, isFunction(onFulfilled) ? onFulfilled : Identity)); + tuples[2][3].add(resolve(0, newDefer, isFunction(onRejected) ? onRejected : Thrower)); + }).promise(); + }, + promise: function (obj) { + return obj != null ? jQuery.extend(obj, promise) : promise; + } + }, deferred = {}; + jQuery.each(tuples, function (i, tuple) { + var list = tuple[2], stateString = tuple[5]; + promise[tuple[1]] = list.add; + if (stateString) { + list.add(function () { + state = stateString; + }, tuples[3 - i][2].disable, tuples[3 - i][3].disable, tuples[0][2].lock, tuples[0][3].lock); + } + list.add(tuple[3].fire); + deferred[tuple[0]] = function () { + deferred[tuple[0] + 'With'](this === deferred ? undefined : this, arguments); + return this; + }; + deferred[tuple[0] + 'With'] = list.fireWith; + }); + promise.promise(deferred); + if (func) { + func.call(deferred, deferred); + } + return deferred; + }, + when: function (singleValue) { + var remaining = arguments.length, i = remaining, resolveContexts = Array(i), resolveValues = slice.call(arguments), primary = jQuery.Deferred(), updateFunc = function (i) { + return function (value) { + resolveContexts[i] = this; + resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value; + if (!--remaining) { + primary.resolveWith(resolveContexts, resolveValues); + } + }; + }; + if (remaining <= 1) { + adoptValue(singleValue, primary.done(updateFunc(i)).resolve, primary.reject, !remaining); + if (primary.state() === 'pending' || isFunction(resolveValues[i] && resolveValues[i].then)) { + return primary.then(); + } + } + while (i--) { + adoptValue(resolveValues[i], updateFunc(i), primary.reject); + } + return primary.promise(); + } + }); + var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + jQuery.Deferred.exceptionHook = function (error, stack) { + if (window.console && window.console.warn && error && rerrorNames.test(error.name)) { + window.console.warn('jQuery.Deferred exception: ' + error.message, error.stack, stack); + } + }; + jQuery.readyException = function (error) { + window.setTimeout(function () { + throw error; + }); + }; + var readyList = jQuery.Deferred(); + jQuery.fn.ready = function (fn) { + readyList.then(fn).catch(function (error) { + jQuery.readyException(error); + }); + return this; + }; + jQuery.extend({ + isReady: false, + readyWait: 1, + ready: function (wait) { + if (wait === true ? --jQuery.readyWait : jQuery.isReady) { + return; + } + jQuery.isReady = true; + if (wait !== true && --jQuery.readyWait > 0) { + return; + } + readyList.resolveWith(document, [jQuery]); + } + }); + jQuery.ready.then = readyList.then; + function completed() { + document.removeEventListener('DOMContentLoaded', completed); + window.removeEventListener('load', completed); + jQuery.ready(); + } + if (document.readyState === 'complete' || document.readyState !== 'loading' && !document.documentElement.doScroll) { + window.setTimeout(jQuery.ready); + } else { + document.addEventListener('DOMContentLoaded', completed); + window.addEventListener('load', completed); + } + var access = function (elems, fn, key, value, chainable, emptyGet, raw) { + var i = 0, len = elems.length, bulk = key == null; + if (toType(key) === 'object') { + chainable = true; + for (i in key) { + access(elems, fn, i, key[i], true, emptyGet, raw); + } + } else if (value !== undefined) { + chainable = true; + if (!isFunction(value)) { + raw = true; + } + if (bulk) { + if (raw) { + fn.call(elems, value); + fn = null; + } else { + bulk = fn; + fn = function (elem, _key, value) { + return bulk.call(jQuery(elem), value); + }; + } + } + if (fn) { + for (; i < len; i++) { + fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key))); + } + } + } + if (chainable) { + return elems; + } + if (bulk) { + return fn.call(elems); + } + return len ? fn(elems[0], key) : emptyGet; + }; + var rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g; + function fcamelCase(_all, letter) { + return letter.toUpperCase(); + } + function camelCase(string) { + return string.replace(rmsPrefix, 'ms-').replace(rdashAlpha, fcamelCase); + } + var acceptData = function (owner) { + return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType; + }; + function Data() { + this.expando = jQuery.expando + Data.uid++; + } + Data.uid = 1; + Data.prototype = { + cache: function (owner) { + var value = owner[this.expando]; + if (!value) { + value = {}; + if (acceptData(owner)) { + if (owner.nodeType) { + owner[this.expando] = value; + } else { + Object.defineProperty(owner, this.expando, { + value: value, + configurable: true + }); + } + } + } + return value; + }, + set: function (owner, data, value) { + var prop, cache = this.cache(owner); + if (typeof data === 'string') { + cache[camelCase(data)] = value; + } else { + for (prop in data) { + cache[camelCase(prop)] = data[prop]; + } + } + return cache; + }, + get: function (owner, key) { + return key === undefined ? this.cache(owner) : owner[this.expando] && owner[this.expando][camelCase(key)]; + }, + access: function (owner, key, value) { + if (key === undefined || key && typeof key === 'string' && value === undefined) { + return this.get(owner, key); + } + this.set(owner, key, value); + return value !== undefined ? value : key; + }, + remove: function (owner, key) { + var i, cache = owner[this.expando]; + if (cache === undefined) { + return; + } + if (key !== undefined) { + if (Array.isArray(key)) { + key = key.map(camelCase); + } else { + key = camelCase(key); + key = key in cache ? [key] : key.match(rnothtmlwhite) || []; + } + i = key.length; + while (i--) { + delete cache[key[i]]; + } + } + if (key === undefined || jQuery.isEmptyObject(cache)) { + if (owner.nodeType) { + owner[this.expando] = undefined; + } else { + delete owner[this.expando]; + } + } + }, + hasData: function (owner) { + var cache = owner[this.expando]; + return cache !== undefined && !jQuery.isEmptyObject(cache); + } + }; + var dataPriv = new Data(); + var dataUser = new Data(); + var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; + function getData(data) { + if (data === 'true') { + return true; + } + if (data === 'false') { + return false; + } + if (data === 'null') { + return null; + } + if (data === +data + '') { + return +data; + } + if (rbrace.test(data)) { + return JSON.parse(data); + } + return data; + } + function dataAttr(elem, key, data) { + var name; + if (data === undefined && elem.nodeType === 1) { + name = 'data-' + key.replace(rmultiDash, '-$&').toLowerCase(); + data = elem.getAttribute(name); + if (typeof data === 'string') { + try { + data = getData(data); + } catch (e) { + } + dataUser.set(elem, key, data); + } else { + data = undefined; + } + } + return data; + } + jQuery.extend({ + hasData: function (elem) { + return dataUser.hasData(elem) || dataPriv.hasData(elem); + }, + data: function (elem, name, data) { + return dataUser.access(elem, name, data); + }, + removeData: function (elem, name) { + dataUser.remove(elem, name); + }, + _data: function (elem, name, data) { + return dataPriv.access(elem, name, data); + }, + _removeData: function (elem, name) { + dataPriv.remove(elem, name); + } + }); + jQuery.fn.extend({ + data: function (key, value) { + var i, name, data, elem = this[0], attrs = elem && elem.attributes; + if (key === undefined) { + if (this.length) { + data = dataUser.get(elem); + if (elem.nodeType === 1 && !dataPriv.get(elem, 'hasDataAttrs')) { + i = attrs.length; + while (i--) { + if (attrs[i]) { + name = attrs[i].name; + if (name.indexOf('data-') === 0) { + name = camelCase(name.slice(5)); + dataAttr(elem, name, data[name]); + } + } + } + dataPriv.set(elem, 'hasDataAttrs', true); + } + } + return data; + } + if (typeof key === 'object') { + return this.each(function () { + dataUser.set(this, key); + }); + } + return access(this, function (value) { + var data; + if (elem && value === undefined) { + data = dataUser.get(elem, key); + if (data !== undefined) { + return data; + } + data = dataAttr(elem, key); + if (data !== undefined) { + return data; + } + return; + } + this.each(function () { + dataUser.set(this, key, value); + }); + }, null, value, arguments.length > 1, null, true); + }, + removeData: function (key) { + return this.each(function () { + dataUser.remove(this, key); + }); + } + }); + jQuery.extend({ + queue: function (elem, type, data) { + var queue; + if (elem) { + type = (type || 'fx') + 'queue'; + queue = dataPriv.get(elem, type); + if (data) { + if (!queue || Array.isArray(data)) { + queue = dataPriv.access(elem, type, jQuery.makeArray(data)); + } else { + queue.push(data); + } + } + return queue || []; + } + }, + dequeue: function (elem, type) { + type = type || 'fx'; + var queue = jQuery.queue(elem, type), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks(elem, type), next = function () { + jQuery.dequeue(elem, type); + }; + if (fn === 'inprogress') { + fn = queue.shift(); + startLength--; + } + if (fn) { + if (type === 'fx') { + queue.unshift('inprogress'); + } + delete hooks.stop; + fn.call(elem, next, hooks); + } + if (!startLength && hooks) { + hooks.empty.fire(); + } + }, + _queueHooks: function (elem, type) { + var key = type + 'queueHooks'; + return dataPriv.get(elem, key) || dataPriv.access(elem, key, { + empty: jQuery.Callbacks('once memory').add(function () { + dataPriv.remove(elem, [ + type + 'queue', + key + ]); + }) + }); + } + }); + jQuery.fn.extend({ + queue: function (type, data) { + var setter = 2; + if (typeof type !== 'string') { + data = type; + type = 'fx'; + setter--; + } + if (arguments.length < setter) { + return jQuery.queue(this[0], type); + } + return data === undefined ? this : this.each(function () { + var queue = jQuery.queue(this, type, data); + jQuery._queueHooks(this, type); + if (type === 'fx' && queue[0] !== 'inprogress') { + jQuery.dequeue(this, type); + } + }); + }, + dequeue: function (type) { + return this.each(function () { + jQuery.dequeue(this, type); + }); + }, + clearQueue: function (type) { + return this.queue(type || 'fx', []); + }, + promise: function (type, obj) { + var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function () { + if (!--count) { + defer.resolveWith(elements, [elements]); + } + }; + if (typeof type !== 'string') { + obj = type; + type = undefined; + } + type = type || 'fx'; + while (i--) { + tmp = dataPriv.get(elements[i], type + 'queueHooks'); + if (tmp && tmp.empty) { + count++; + tmp.empty.add(resolve); + } + } + resolve(); + return defer.promise(obj); + } + }); + var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source; + var rcssNum = new RegExp('^(?:([+-])=|)(' + pnum + ')([a-z%]*)$', 'i'); + var cssExpand = [ + 'Top', + 'Right', + 'Bottom', + 'Left' + ]; + var documentElement = document.documentElement; + var isAttached = function (elem) { + return jQuery.contains(elem.ownerDocument, elem); + }, composed = { composed: true }; + if (documentElement.getRootNode) { + isAttached = function (elem) { + return jQuery.contains(elem.ownerDocument, elem) || elem.getRootNode(composed) === elem.ownerDocument; + }; + } + var isHiddenWithinTree = function (elem, el) { + elem = el || elem; + return elem.style.display === 'none' || elem.style.display === '' && isAttached(elem) && jQuery.css(elem, 'display') === 'none'; + }; + function adjustCSS(elem, prop, valueParts, tween) { + var adjusted, scale, maxIterations = 20, currentValue = tween ? function () { + return tween.cur(); + } : function () { + return jQuery.css(elem, prop, ''); + }, initial = currentValue(), unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? '' : 'px'), initialInUnit = elem.nodeType && (jQuery.cssNumber[prop] || unit !== 'px' && +initial) && rcssNum.exec(jQuery.css(elem, prop)); + if (initialInUnit && initialInUnit[3] !== unit) { + initial = initial / 2; + unit = unit || initialInUnit[3]; + initialInUnit = +initial || 1; + while (maxIterations--) { + jQuery.style(elem, prop, initialInUnit + unit); + if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + } + initialInUnit = initialInUnit * 2; + jQuery.style(elem, prop, initialInUnit + unit); + valueParts = valueParts || []; + } + if (valueParts) { + initialInUnit = +initialInUnit || +initial || 0; + adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2]; + if (tween) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; + } + var defaultDisplayMap = {}; + function getDefaultDisplay(elem) { + var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[nodeName]; + if (display) { + return display; + } + temp = doc.body.appendChild(doc.createElement(nodeName)); + display = jQuery.css(temp, 'display'); + temp.parentNode.removeChild(temp); + if (display === 'none') { + display = 'block'; + } + defaultDisplayMap[nodeName] = display; + return display; + } + function showHide(elements, show) { + var display, elem, values = [], index = 0, length = elements.length; + for (; index < length; index++) { + elem = elements[index]; + if (!elem.style) { + continue; + } + display = elem.style.display; + if (show) { + if (display === 'none') { + values[index] = dataPriv.get(elem, 'display') || null; + if (!values[index]) { + elem.style.display = ''; + } + } + if (elem.style.display === '' && isHiddenWithinTree(elem)) { + values[index] = getDefaultDisplay(elem); + } + } else { + if (display !== 'none') { + values[index] = 'none'; + dataPriv.set(elem, 'display', display); + } + } + } + for (index = 0; index < length; index++) { + if (values[index] != null) { + elements[index].style.display = values[index]; + } + } + return elements; + } + jQuery.fn.extend({ + show: function () { + return showHide(this, true); + }, + hide: function () { + return showHide(this); + }, + toggle: function (state) { + if (typeof state === 'boolean') { + return state ? this.show() : this.hide(); + } + return this.each(function () { + if (isHiddenWithinTree(this)) { + jQuery(this).show(); + } else { + jQuery(this).hide(); + } + }); + } + }); + var rcheckableType = /^(?:checkbox|radio)$/i; + var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i; + var rscriptType = /^$|^module$|\/(?:java|ecma)script/i; + (function () { + var fragment = document.createDocumentFragment(), div = fragment.appendChild(document.createElement('div')), input = document.createElement('input'); + input.setAttribute('type', 'radio'); + input.setAttribute('checked', 'checked'); + input.setAttribute('name', 't'); + div.appendChild(input); + support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; + div.innerHTML = ''; + support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; + div.innerHTML = ''; + support.option = !!div.lastChild; + }()); + var wrapMap = { + thead: [ + 1, + '', + '
      ' + ], + col: [ + 2, + '', + '
      ' + ], + tr: [ + 2, + '', + '
      ' + ], + td: [ + 3, + '', + '
      ' + ], + _default: [ + 0, + '', + '' + ] + }; + wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; + wrapMap.th = wrapMap.td; + if (!support.option) { + wrapMap.optgroup = wrapMap.option = [ + 1, + '' + ]; + } + function getAll(context, tag) { + var ret; + if (typeof context.getElementsByTagName !== 'undefined') { + ret = context.getElementsByTagName(tag || '*'); + } else if (typeof context.querySelectorAll !== 'undefined') { + ret = context.querySelectorAll(tag || '*'); + } else { + ret = []; + } + if (tag === undefined || tag && nodeName(context, tag)) { + return jQuery.merge([context], ret); + } + return ret; + } + function setGlobalEval(elems, refElements) { + var i = 0, l = elems.length; + for (; i < l; i++) { + dataPriv.set(elems[i], 'globalEval', !refElements || dataPriv.get(refElements[i], 'globalEval')); + } + } + var rhtml = /<|&#?\w+;/; + function buildFragment(elems, context, scripts, selection, ignored) { + var elem, tmp, tag, wrap, attached, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; + for (; i < l; i++) { + elem = elems[i]; + if (elem || elem === 0) { + if (toType(elem) === 'object') { + jQuery.merge(nodes, elem.nodeType ? [elem] : elem); + } else if (!rhtml.test(elem)) { + nodes.push(context.createTextNode(elem)); + } else { + tmp = tmp || fragment.appendChild(context.createElement('div')); + tag = (rtagName.exec(elem) || [ + '', + '' + ])[1].toLowerCase(); + wrap = wrapMap[tag] || wrapMap._default; + tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; + j = wrap[0]; + while (j--) { + tmp = tmp.lastChild; + } + jQuery.merge(nodes, tmp.childNodes); + tmp = fragment.firstChild; + tmp.textContent = ''; + } + } + } + fragment.textContent = ''; + i = 0; + while (elem = nodes[i++]) { + if (selection && jQuery.inArray(elem, selection) > -1) { + if (ignored) { + ignored.push(elem); + } + continue; + } + attached = isAttached(elem); + tmp = getAll(fragment.appendChild(elem), 'script'); + if (attached) { + setGlobalEval(tmp); + } + if (scripts) { + j = 0; + while (elem = tmp[j++]) { + if (rscriptType.test(elem.type || '')) { + scripts.push(elem); + } + } + } + } + return fragment; + } + var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + function returnTrue() { + return true; + } + function returnFalse() { + return false; + } + function expectSync(elem, type) { + return elem === safeActiveElement() === (type === 'focus'); + } + function safeActiveElement() { + try { + return document.activeElement; + } catch (err) { + } + } + function on(elem, types, selector, data, fn, one) { + var origFn, type; + if (typeof types === 'object') { + if (typeof selector !== 'string') { + data = data || selector; + selector = undefined; + } + for (type in types) { + on(elem, type, selector, data, types[type], one); + } + return elem; + } + if (data == null && fn == null) { + fn = selector; + data = selector = undefined; + } else if (fn == null) { + if (typeof selector === 'string') { + fn = data; + data = undefined; + } else { + fn = data; + data = selector; + selector = undefined; + } + } + if (fn === false) { + fn = returnFalse; + } else if (!fn) { + return elem; + } + if (one === 1) { + origFn = fn; + fn = function (event) { + jQuery().off(event); + return origFn.apply(this, arguments); + }; + fn.guid = origFn.guid || (origFn.guid = jQuery.guid++); + } + return elem.each(function () { + jQuery.event.add(this, types, fn, data, selector); + }); + } + jQuery.event = { + global: {}, + add: function (elem, types, handler, data, selector) { + var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get(elem); + if (!acceptData(elem)) { + return; + } + if (handler.handler) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + if (selector) { + jQuery.find.matchesSelector(documentElement, selector); + } + if (!handler.guid) { + handler.guid = jQuery.guid++; + } + if (!(events = elemData.events)) { + events = elemData.events = Object.create(null); + } + if (!(eventHandle = elemData.handle)) { + eventHandle = elemData.handle = function (e) { + return typeof jQuery !== 'undefined' && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined; + }; + } + types = (types || '').match(rnothtmlwhite) || ['']; + t = types.length; + while (t--) { + tmp = rtypenamespace.exec(types[t]) || []; + type = origType = tmp[1]; + namespaces = (tmp[2] || '').split('.').sort(); + if (!type) { + continue; + } + special = jQuery.event.special[type] || {}; + type = (selector ? special.delegateType : special.bindType) || type; + special = jQuery.event.special[type] || {}; + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test(selector), + namespace: namespaces.join('.') + }, handleObjIn); + if (!(handlers = events[type])) { + handlers = events[type] = []; + handlers.delegateCount = 0; + if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) { + if (elem.addEventListener) { + elem.addEventListener(type, eventHandle); + } + } + } + if (special.add) { + special.add.call(elem, handleObj); + if (!handleObj.handler.guid) { + handleObj.handler.guid = handler.guid; + } + } + if (selector) { + handlers.splice(handlers.delegateCount++, 0, handleObj); + } else { + handlers.push(handleObj); + } + jQuery.event.global[type] = true; + } + }, + remove: function (elem, types, handler, selector, mappedTypes) { + var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData(elem) && dataPriv.get(elem); + if (!elemData || !(events = elemData.events)) { + return; + } + types = (types || '').match(rnothtmlwhite) || ['']; + t = types.length; + while (t--) { + tmp = rtypenamespace.exec(types[t]) || []; + type = origType = tmp[1]; + namespaces = (tmp[2] || '').split('.').sort(); + if (!type) { + for (type in events) { + jQuery.event.remove(elem, type + types[t], handler, selector, true); + } + continue; + } + special = jQuery.event.special[type] || {}; + type = (selector ? special.delegateType : special.bindType) || type; + handlers = events[type] || []; + tmp = tmp[2] && new RegExp('(^|\\.)' + namespaces.join('\\.(?:.*\\.|)') + '(\\.|$)'); + origCount = j = handlers.length; + while (j--) { + handleObj = handlers[j]; + if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === '**' && handleObj.selector)) { + handlers.splice(j, 1); + if (handleObj.selector) { + handlers.delegateCount--; + } + if (special.remove) { + special.remove.call(elem, handleObj); + } + } + } + if (origCount && !handlers.length) { + if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) { + jQuery.removeEvent(elem, type, elemData.handle); + } + delete events[type]; + } + } + if (jQuery.isEmptyObject(events)) { + dataPriv.remove(elem, 'handle events'); + } + }, + dispatch: function (nativeEvent) { + var i, j, ret, matched, handleObj, handlerQueue, args = new Array(arguments.length), event = jQuery.event.fix(nativeEvent), handlers = (dataPriv.get(this, 'events') || Object.create(null))[event.type] || [], special = jQuery.event.special[event.type] || {}; + args[0] = event; + for (i = 1; i < arguments.length; i++) { + args[i] = arguments[i]; + } + event.delegateTarget = this; + if (special.preDispatch && special.preDispatch.call(this, event) === false) { + return; + } + handlerQueue = jQuery.event.handlers.call(this, event, handlers); + i = 0; + while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) { + event.currentTarget = matched.elem; + j = 0; + while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) { + if (!event.rnamespace || handleObj.namespace === false || event.rnamespace.test(handleObj.namespace)) { + event.handleObj = handleObj; + event.data = handleObj.data; + ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args); + if (ret !== undefined) { + if ((event.result = ret) === false) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + if (special.postDispatch) { + special.postDispatch.call(this, event); + } + return event.result; + }, + handlers: function (event, handlers) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; + if (delegateCount && cur.nodeType && !(event.type === 'click' && event.button >= 1)) { + for (; cur !== this; cur = cur.parentNode || this) { + if (cur.nodeType === 1 && !(event.type === 'click' && cur.disabled === true)) { + matchedHandlers = []; + matchedSelectors = {}; + for (i = 0; i < delegateCount; i++) { + handleObj = handlers[i]; + sel = handleObj.selector + ' '; + if (matchedSelectors[sel] === undefined) { + matchedSelectors[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length; + } + if (matchedSelectors[sel]) { + matchedHandlers.push(handleObj); + } + } + if (matchedHandlers.length) { + handlerQueue.push({ + elem: cur, + handlers: matchedHandlers + }); + } + } + } + } + cur = this; + if (delegateCount < handlers.length) { + handlerQueue.push({ + elem: cur, + handlers: handlers.slice(delegateCount) + }); + } + return handlerQueue; + }, + addProp: function (name, hook) { + Object.defineProperty(jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + get: isFunction(hook) ? function () { + if (this.originalEvent) { + return hook(this.originalEvent); + } + } : function () { + if (this.originalEvent) { + return this.originalEvent[name]; + } + }, + set: function (value) { + Object.defineProperty(this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + }); + } + }); + }, + fix: function (originalEvent) { + return originalEvent[jQuery.expando] ? originalEvent : new jQuery.Event(originalEvent); + }, + special: { + load: { noBubble: true }, + click: { + setup: function (data) { + var el = this || data; + if (rcheckableType.test(el.type) && el.click && nodeName(el, 'input')) { + leverageNative(el, 'click', returnTrue); + } + return false; + }, + trigger: function (data) { + var el = this || data; + if (rcheckableType.test(el.type) && el.click && nodeName(el, 'input')) { + leverageNative(el, 'click'); + } + return true; + }, + _default: function (event) { + var target = event.target; + return rcheckableType.test(target.type) && target.click && nodeName(target, 'input') && dataPriv.get(target, 'click') || nodeName(target, 'a'); + } + }, + beforeunload: { + postDispatch: function (event) { + if (event.result !== undefined && event.originalEvent) { + event.originalEvent.returnValue = event.result; + } + } + } + } + }; + function leverageNative(el, type, expectSync) { + if (!expectSync) { + if (dataPriv.get(el, type) === undefined) { + jQuery.event.add(el, type, returnTrue); + } + return; + } + dataPriv.set(el, type, false); + jQuery.event.add(el, type, { + namespace: false, + handler: function (event) { + var notAsync, result, saved = dataPriv.get(this, type); + if (event.isTrigger & 1 && this[type]) { + if (!saved.length) { + saved = slice.call(arguments); + dataPriv.set(this, type, saved); + notAsync = expectSync(this, type); + this[type](); + result = dataPriv.get(this, type); + if (saved !== result || notAsync) { + dataPriv.set(this, type, false); + } else { + result = {}; + } + if (saved !== result) { + event.stopImmediatePropagation(); + event.preventDefault(); + return result && result.value; + } + } else if ((jQuery.event.special[type] || {}).delegateType) { + event.stopPropagation(); + } + } else if (saved.length) { + dataPriv.set(this, type, { value: jQuery.event.trigger(jQuery.extend(saved[0], jQuery.Event.prototype), saved.slice(1), this) }); + event.stopImmediatePropagation(); + } + } + }); + } + jQuery.removeEvent = function (elem, type, handle) { + if (elem.removeEventListener) { + elem.removeEventListener(type, handle); + } + }; + jQuery.Event = function (src, props) { + if (!(this instanceof jQuery.Event)) { + return new jQuery.Event(src, props); + } + if (src && src.type) { + this.originalEvent = src; + this.type = src.type; + this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && src.returnValue === false ? returnTrue : returnFalse; + this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target; + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + } else { + this.type = src; + } + if (props) { + jQuery.extend(this, props); + } + this.timeStamp = src && src.timeStamp || Date.now(); + this[jQuery.expando] = true; + }; + jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + preventDefault: function () { + var e = this.originalEvent; + this.isDefaultPrevented = returnTrue; + if (e && !this.isSimulated) { + e.preventDefault(); + } + }, + stopPropagation: function () { + var e = this.originalEvent; + this.isPropagationStopped = returnTrue; + if (e && !this.isSimulated) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function () { + var e = this.originalEvent; + this.isImmediatePropagationStopped = returnTrue; + if (e && !this.isSimulated) { + e.stopImmediatePropagation(); + } + this.stopPropagation(); + } + }; + jQuery.each({ + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + 'char': true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true + }, jQuery.event.addProp); + jQuery.each({ + focus: 'focusin', + blur: 'focusout' + }, function (type, delegateType) { + jQuery.event.special[type] = { + setup: function () { + leverageNative(this, type, expectSync); + return false; + }, + trigger: function () { + leverageNative(this, type); + return true; + }, + _default: function () { + return true; + }, + delegateType: delegateType + }; + }); + jQuery.each({ + mouseenter: 'mouseover', + mouseleave: 'mouseout', + pointerenter: 'pointerover', + pointerleave: 'pointerout' + }, function (orig, fix) { + jQuery.event.special[orig] = { + delegateType: fix, + bindType: fix, + handle: function (event) { + var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; + if (!related || related !== target && !jQuery.contains(target, related)) { + event.type = handleObj.origType; + ret = handleObj.handler.apply(this, arguments); + event.type = fix; + } + return ret; + } + }; + }); + jQuery.fn.extend({ + on: function (types, selector, data, fn) { + return on(this, types, selector, data, fn); + }, + one: function (types, selector, data, fn) { + return on(this, types, selector, data, fn, 1); + }, + off: function (types, selector, fn) { + var handleObj, type; + if (types && types.preventDefault && types.handleObj) { + handleObj = types.handleObj; + jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + '.' + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler); + return this; + } + if (typeof types === 'object') { + for (type in types) { + this.off(type, selector, types[type]); + } + return this; + } + if (selector === false || typeof selector === 'function') { + fn = selector; + selector = undefined; + } + if (fn === false) { + fn = returnFalse; + } + return this.each(function () { + jQuery.event.remove(this, types, fn, selector); + }); + } + }); + var rnoInnerhtml = /\s*$/g; + function manipulationTarget(elem, content) { + if (nodeName(elem, 'table') && nodeName(content.nodeType !== 11 ? content : content.firstChild, 'tr')) { + return jQuery(elem).children('tbody')[0] || elem; + } + return elem; + } + function disableScript(elem) { + elem.type = (elem.getAttribute('type') !== null) + '/' + elem.type; + return elem; + } + function restoreScript(elem) { + if ((elem.type || '').slice(0, 5) === 'true/') { + elem.type = elem.type.slice(5); + } else { + elem.removeAttribute('type'); + } + return elem; + } + function cloneCopyEvent(src, dest) { + var i, l, type, pdataOld, udataOld, udataCur, events; + if (dest.nodeType !== 1) { + return; + } + if (dataPriv.hasData(src)) { + pdataOld = dataPriv.get(src); + events = pdataOld.events; + if (events) { + dataPriv.remove(dest, 'handle events'); + for (type in events) { + for (i = 0, l = events[type].length; i < l; i++) { + jQuery.event.add(dest, type, events[type][i]); + } + } + } + } + if (dataUser.hasData(src)) { + udataOld = dataUser.access(src); + udataCur = jQuery.extend({}, udataOld); + dataUser.set(dest, udataCur); + } + } + function fixInput(src, dest) { + var nodeName = dest.nodeName.toLowerCase(); + if (nodeName === 'input' && rcheckableType.test(src.type)) { + dest.checked = src.checked; + } else if (nodeName === 'input' || nodeName === 'textarea') { + dest.defaultValue = src.defaultValue; + } + } + function domManip(collection, args, callback, ignored) { + args = flat(args); + var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[0], valueIsFunction = isFunction(value); + if (valueIsFunction || l > 1 && typeof value === 'string' && !support.checkClone && rchecked.test(value)) { + return collection.each(function (index) { + var self = collection.eq(index); + if (valueIsFunction) { + args[0] = value.call(this, index, self.html()); + } + domManip(self, args, callback, ignored); + }); + } + if (l) { + fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored); + first = fragment.firstChild; + if (fragment.childNodes.length === 1) { + fragment = first; + } + if (first || ignored) { + scripts = jQuery.map(getAll(fragment, 'script'), disableScript); + hasScripts = scripts.length; + for (; i < l; i++) { + node = fragment; + if (i !== iNoClone) { + node = jQuery.clone(node, true, true); + if (hasScripts) { + jQuery.merge(scripts, getAll(node, 'script')); + } + } + callback.call(collection[i], node, i); + } + if (hasScripts) { + doc = scripts[scripts.length - 1].ownerDocument; + jQuery.map(scripts, restoreScript); + for (i = 0; i < hasScripts; i++) { + node = scripts[i]; + if (rscriptType.test(node.type || '') && !dataPriv.access(node, 'globalEval') && jQuery.contains(doc, node)) { + if (node.src && (node.type || '').toLowerCase() !== 'module') { + if (jQuery._evalUrl && !node.noModule) { + jQuery._evalUrl(node.src, { nonce: node.nonce || node.getAttribute('nonce') }, doc); + } + } else { + DOMEval(node.textContent.replace(rcleanScript, ''), node, doc); + } + } + } + } + } + } + return collection; + } + function remove(elem, selector, keepData) { + var node, nodes = selector ? jQuery.filter(selector, elem) : elem, i = 0; + for (; (node = nodes[i]) != null; i++) { + if (!keepData && node.nodeType === 1) { + jQuery.cleanData(getAll(node)); + } + if (node.parentNode) { + if (keepData && isAttached(node)) { + setGlobalEval(getAll(node, 'script')); + } + node.parentNode.removeChild(node); + } + } + return elem; + } + jQuery.extend({ + htmlPrefilter: function (html) { + return html; + }, + clone: function (elem, dataAndEvents, deepDataAndEvents) { + var i, l, srcElements, destElements, clone = elem.cloneNode(true), inPage = isAttached(elem); + if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) { + destElements = getAll(clone); + srcElements = getAll(elem); + for (i = 0, l = srcElements.length; i < l; i++) { + fixInput(srcElements[i], destElements[i]); + } + } + if (dataAndEvents) { + if (deepDataAndEvents) { + srcElements = srcElements || getAll(elem); + destElements = destElements || getAll(clone); + for (i = 0, l = srcElements.length; i < l; i++) { + cloneCopyEvent(srcElements[i], destElements[i]); + } + } else { + cloneCopyEvent(elem, clone); + } + } + destElements = getAll(clone, 'script'); + if (destElements.length > 0) { + setGlobalEval(destElements, !inPage && getAll(elem, 'script')); + } + return clone; + }, + cleanData: function (elems) { + var data, elem, type, special = jQuery.event.special, i = 0; + for (; (elem = elems[i]) !== undefined; i++) { + if (acceptData(elem)) { + if (data = elem[dataPriv.expando]) { + if (data.events) { + for (type in data.events) { + if (special[type]) { + jQuery.event.remove(elem, type); + } else { + jQuery.removeEvent(elem, type, data.handle); + } + } + } + elem[dataPriv.expando] = undefined; + } + if (elem[dataUser.expando]) { + elem[dataUser.expando] = undefined; + } + } + } + } + }); + jQuery.fn.extend({ + detach: function (selector) { + return remove(this, selector, true); + }, + remove: function (selector) { + return remove(this, selector); + }, + text: function (value) { + return access(this, function (value) { + return value === undefined ? jQuery.text(this) : this.empty().each(function () { + if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { + this.textContent = value; + } + }); + }, null, value, arguments.length); + }, + append: function () { + return domManip(this, arguments, function (elem) { + if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { + var target = manipulationTarget(this, elem); + target.appendChild(elem); + } + }); + }, + prepend: function () { + return domManip(this, arguments, function (elem) { + if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) { + var target = manipulationTarget(this, elem); + target.insertBefore(elem, target.firstChild); + } + }); + }, + before: function () { + return domManip(this, arguments, function (elem) { + if (this.parentNode) { + this.parentNode.insertBefore(elem, this); + } + }); + }, + after: function () { + return domManip(this, arguments, function (elem) { + if (this.parentNode) { + this.parentNode.insertBefore(elem, this.nextSibling); + } + }); + }, + empty: function () { + var elem, i = 0; + for (; (elem = this[i]) != null; i++) { + if (elem.nodeType === 1) { + jQuery.cleanData(getAll(elem, false)); + elem.textContent = ''; + } + } + return this; + }, + clone: function (dataAndEvents, deepDataAndEvents) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + return this.map(function () { + return jQuery.clone(this, dataAndEvents, deepDataAndEvents); + }); + }, + html: function (value) { + return access(this, function (value) { + var elem = this[0] || {}, i = 0, l = this.length; + if (value === undefined && elem.nodeType === 1) { + return elem.innerHTML; + } + if (typeof value === 'string' && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || [ + '', + '' + ])[1].toLowerCase()]) { + value = jQuery.htmlPrefilter(value); + try { + for (; i < l; i++) { + elem = this[i] || {}; + if (elem.nodeType === 1) { + jQuery.cleanData(getAll(elem, false)); + elem.innerHTML = value; + } + } + elem = 0; + } catch (e) { + } + } + if (elem) { + this.empty().append(value); + } + }, null, value, arguments.length); + }, + replaceWith: function () { + var ignored = []; + return domManip(this, arguments, function (elem) { + var parent = this.parentNode; + if (jQuery.inArray(this, ignored) < 0) { + jQuery.cleanData(getAll(this)); + if (parent) { + parent.replaceChild(elem, this); + } + } + }, ignored); + } + }); + jQuery.each({ + appendTo: 'append', + prependTo: 'prepend', + insertBefore: 'before', + insertAfter: 'after', + replaceAll: 'replaceWith' + }, function (name, original) { + jQuery.fn[name] = function (selector) { + var elems, ret = [], insert = jQuery(selector), last = insert.length - 1, i = 0; + for (; i <= last; i++) { + elems = i === last ? this : this.clone(true); + jQuery(insert[i])[original](elems); + push.apply(ret, elems.get()); + } + return this.pushStack(ret); + }; + }); + var rnumnonpx = new RegExp('^(' + pnum + ')(?!px)[a-z%]+$', 'i'); + var getStyles = function (elem) { + var view = elem.ownerDocument.defaultView; + if (!view || !view.opener) { + view = window; + } + return view.getComputedStyle(elem); + }; + var swap = function (elem, options, callback) { + var ret, name, old = {}; + for (name in options) { + old[name] = elem.style[name]; + elem.style[name] = options[name]; + } + ret = callback.call(elem); + for (name in options) { + elem.style[name] = old[name]; + } + return ret; + }; + var rboxStyle = new RegExp(cssExpand.join('|'), 'i'); + (function () { + function computeStyleTests() { + if (!div) { + return; + } + container.style.cssText = 'position:absolute;left:-11111px;width:60px;' + 'margin-top:1px;padding:0;border:0'; + div.style.cssText = 'position:relative;display:block;box-sizing:border-box;overflow:scroll;' + 'margin:auto;border:1px;padding:1px;' + 'width:60%;top:1%'; + documentElement.appendChild(container).appendChild(div); + var divStyle = window.getComputedStyle(div); + pixelPositionVal = divStyle.top !== '1%'; + reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; + div.style.right = '60%'; + pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; + boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; + div.style.position = 'absolute'; + scrollboxSizeVal = roundPixelMeasures(div.offsetWidth / 3) === 12; + documentElement.removeChild(container); + div = null; + } + function roundPixelMeasures(measure) { + return Math.round(parseFloat(measure)); + } + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, reliableTrDimensionsVal, reliableMarginLeftVal, container = document.createElement('div'), div = document.createElement('div'); + if (!div.style) { + return; + } + div.style.backgroundClip = 'content-box'; + div.cloneNode(true).style.backgroundClip = ''; + support.clearCloneStyle = div.style.backgroundClip === 'content-box'; + jQuery.extend(support, { + boxSizingReliable: function () { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function () { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function () { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function () { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function () { + computeStyleTests(); + return scrollboxSizeVal; + }, + reliableTrDimensions: function () { + var table, tr, trChild, trStyle; + if (reliableTrDimensionsVal == null) { + table = document.createElement('table'); + tr = document.createElement('tr'); + trChild = document.createElement('div'); + table.style.cssText = 'position:absolute;left:-11111px;border-collapse:separate'; + tr.style.cssText = 'border:1px solid'; + tr.style.height = '1px'; + trChild.style.height = '9px'; + trChild.style.display = 'block'; + documentElement.appendChild(table).appendChild(tr).appendChild(trChild); + trStyle = window.getComputedStyle(tr); + reliableTrDimensionsVal = parseInt(trStyle.height, 10) + parseInt(trStyle.borderTopWidth, 10) + parseInt(trStyle.borderBottomWidth, 10) === tr.offsetHeight; + documentElement.removeChild(table); + } + return reliableTrDimensionsVal; + } + }); + }()); + function curCSS(elem, name, computed) { + var width, minWidth, maxWidth, ret, style = elem.style; + computed = computed || getStyles(elem); + if (computed) { + ret = computed.getPropertyValue(name) || computed[name]; + if (ret === '' && !isAttached(elem)) { + ret = jQuery.style(elem, name); + } + if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + return ret !== undefined ? ret + '' : ret; + } + function addGetHookIf(conditionFn, hookFn) { + return { + get: function () { + if (conditionFn()) { + delete this.get; + return; + } + return (this.get = hookFn).apply(this, arguments); + } + }; + } + var cssPrefixes = [ + 'Webkit', + 'Moz', + 'ms' + ], emptyStyle = document.createElement('div').style, vendorProps = {}; + function vendorPropName(name) { + var capName = name[0].toUpperCase() + name.slice(1), i = cssPrefixes.length; + while (i--) { + name = cssPrefixes[i] + capName; + if (name in emptyStyle) { + return name; + } + } + } + function finalPropName(name) { + var final = jQuery.cssProps[name] || vendorProps[name]; + if (final) { + return final; + } + if (name in emptyStyle) { + return name; + } + return vendorProps[name] = vendorPropName(name) || name; + } + var rdisplayswap = /^(none|table(?!-c[ea]).+)/, rcustomProp = /^--/, cssShow = { + position: 'absolute', + visibility: 'hidden', + display: 'block' + }, cssNormalTransform = { + letterSpacing: '0', + fontWeight: '400' + }; + function setPositiveNumber(_elem, value, subtract) { + var matches = rcssNum.exec(value); + return matches ? Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || 'px') : value; + } + function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) { + var i = dimension === 'width' ? 1 : 0, extra = 0, delta = 0; + if (box === (isBorderBox ? 'border' : 'content')) { + return 0; + } + for (; i < 4; i += 2) { + if (box === 'margin') { + delta += jQuery.css(elem, box + cssExpand[i], true, styles); + } + if (!isBorderBox) { + delta += jQuery.css(elem, 'padding' + cssExpand[i], true, styles); + if (box !== 'padding') { + delta += jQuery.css(elem, 'border' + cssExpand[i] + 'Width', true, styles); + } else { + extra += jQuery.css(elem, 'border' + cssExpand[i] + 'Width', true, styles); + } + } else { + if (box === 'content') { + delta -= jQuery.css(elem, 'padding' + cssExpand[i], true, styles); + } + if (box !== 'margin') { + delta -= jQuery.css(elem, 'border' + cssExpand[i] + 'Width', true, styles); + } + } + } + if (!isBorderBox && computedVal >= 0) { + delta += Math.max(0, Math.ceil(elem['offset' + dimension[0].toUpperCase() + dimension.slice(1)] - computedVal - delta - extra - 0.5)) || 0; + } + return delta; + } + function getWidthOrHeight(elem, dimension, extra) { + var styles = getStyles(elem), boxSizingNeeded = !support.boxSizingReliable() || extra, isBorderBox = boxSizingNeeded && jQuery.css(elem, 'boxSizing', false, styles) === 'border-box', valueIsBorderBox = isBorderBox, val = curCSS(elem, dimension, styles), offsetProp = 'offset' + dimension[0].toUpperCase() + dimension.slice(1); + if (rnumnonpx.test(val)) { + if (!extra) { + return val; + } + val = 'auto'; + } + if ((!support.boxSizingReliable() && isBorderBox || !support.reliableTrDimensions() && nodeName(elem, 'tr') || val === 'auto' || !parseFloat(val) && jQuery.css(elem, 'display', false, styles) === 'inline') && elem.getClientRects().length) { + isBorderBox = jQuery.css(elem, 'boxSizing', false, styles) === 'border-box'; + valueIsBorderBox = offsetProp in elem; + if (valueIsBorderBox) { + val = elem[offsetProp]; + } + } + val = parseFloat(val) || 0; + return val + boxModelAdjustment(elem, dimension, extra || (isBorderBox ? 'border' : 'content'), valueIsBorderBox, styles, val) + 'px'; + } + jQuery.extend({ + cssHooks: { + opacity: { + get: function (elem, computed) { + if (computed) { + var ret = curCSS(elem, 'opacity'); + return ret === '' ? '1' : ret; + } + } + } + }, + cssNumber: { + 'animationIterationCount': true, + 'columnCount': true, + 'fillOpacity': true, + 'flexGrow': true, + 'flexShrink': true, + 'fontWeight': true, + 'gridArea': true, + 'gridColumn': true, + 'gridColumnEnd': true, + 'gridColumnStart': true, + 'gridRow': true, + 'gridRowEnd': true, + 'gridRowStart': true, + 'lineHeight': true, + 'opacity': true, + 'order': true, + 'orphans': true, + 'widows': true, + 'zIndex': true, + 'zoom': true + }, + cssProps: {}, + style: function (elem, name, value, extra) { + if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { + return; + } + var ret, type, hooks, origName = camelCase(name), isCustomProp = rcustomProp.test(name), style = elem.style; + if (!isCustomProp) { + name = finalPropName(origName); + } + hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; + if (value !== undefined) { + type = typeof value; + if (type === 'string' && (ret = rcssNum.exec(value)) && ret[1]) { + value = adjustCSS(elem, name, ret); + type = 'number'; + } + if (value == null || value !== value) { + return; + } + if (type === 'number' && !isCustomProp) { + value += ret && ret[3] || (jQuery.cssNumber[origName] ? '' : 'px'); + } + if (!support.clearCloneStyle && value === '' && name.indexOf('background') === 0) { + style[name] = 'inherit'; + } + if (!hooks || !('set' in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) { + if (isCustomProp) { + style.setProperty(name, value); + } else { + style[name] = value; + } + } + } else { + if (hooks && 'get' in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) { + return ret; + } + return style[name]; + } + }, + css: function (elem, name, extra, styles) { + var val, num, hooks, origName = camelCase(name), isCustomProp = rcustomProp.test(name); + if (!isCustomProp) { + name = finalPropName(origName); + } + hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; + if (hooks && 'get' in hooks) { + val = hooks.get(elem, true, extra); + } + if (val === undefined) { + val = curCSS(elem, name, styles); + } + if (val === 'normal' && name in cssNormalTransform) { + val = cssNormalTransform[name]; + } + if (extra === '' || extra) { + num = parseFloat(val); + return extra === true || isFinite(num) ? num || 0 : val; + } + return val; + } + }); + jQuery.each([ + 'height', + 'width' + ], function (_i, dimension) { + jQuery.cssHooks[dimension] = { + get: function (elem, computed, extra) { + if (computed) { + return rdisplayswap.test(jQuery.css(elem, 'display')) && (!elem.getClientRects().length || !elem.getBoundingClientRect().width) ? swap(elem, cssShow, function () { + return getWidthOrHeight(elem, dimension, extra); + }) : getWidthOrHeight(elem, dimension, extra); + } + }, + set: function (elem, value, extra) { + var matches, styles = getStyles(elem), scrollboxSizeBuggy = !support.scrollboxSize() && styles.position === 'absolute', boxSizingNeeded = scrollboxSizeBuggy || extra, isBorderBox = boxSizingNeeded && jQuery.css(elem, 'boxSizing', false, styles) === 'border-box', subtract = extra ? boxModelAdjustment(elem, dimension, extra, isBorderBox, styles) : 0; + if (isBorderBox && scrollboxSizeBuggy) { + subtract -= Math.ceil(elem['offset' + dimension[0].toUpperCase() + dimension.slice(1)] - parseFloat(styles[dimension]) - boxModelAdjustment(elem, dimension, 'border', false, styles) - 0.5); + } + if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || 'px') !== 'px') { + elem.style[dimension] = value; + value = jQuery.css(elem, dimension); + } + return setPositiveNumber(elem, value, subtract); + } + }; + }); + jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) { + if (computed) { + return (parseFloat(curCSS(elem, 'marginLeft')) || elem.getBoundingClientRect().left - swap(elem, { marginLeft: 0 }, function () { + return elem.getBoundingClientRect().left; + })) + 'px'; + } + }); + jQuery.each({ + margin: '', + padding: '', + border: 'Width' + }, function (prefix, suffix) { + jQuery.cssHooks[prefix + suffix] = { + expand: function (value) { + var i = 0, expanded = {}, parts = typeof value === 'string' ? value.split(' ') : [value]; + for (; i < 4; i++) { + expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0]; + } + return expanded; + } + }; + if (prefix !== 'margin') { + jQuery.cssHooks[prefix + suffix].set = setPositiveNumber; + } + }); + jQuery.fn.extend({ + css: function (name, value) { + return access(this, function (elem, name, value) { + var styles, len, map = {}, i = 0; + if (Array.isArray(name)) { + styles = getStyles(elem); + len = name.length; + for (; i < len; i++) { + map[name[i]] = jQuery.css(elem, name[i], false, styles); + } + return map; + } + return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name); + }, name, value, arguments.length > 1); + } + }); + function Tween(elem, options, prop, end, easing) { + return new Tween.prototype.init(elem, options, prop, end, easing); + } + jQuery.Tween = Tween; + Tween.prototype = { + constructor: Tween, + init: function (elem, options, prop, end, easing, unit) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || (jQuery.cssNumber[prop] ? '' : 'px'); + }, + cur: function () { + var hooks = Tween.propHooks[this.prop]; + return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this); + }, + run: function (percent) { + var eased, hooks = Tween.propHooks[this.prop]; + if (this.options.duration) { + this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration); + } else { + this.pos = eased = percent; + } + this.now = (this.end - this.start) * eased + this.start; + if (this.options.step) { + this.options.step.call(this.elem, this.now, this); + } + if (hooks && hooks.set) { + hooks.set(this); + } else { + Tween.propHooks._default.set(this); + } + return this; + } + }; + Tween.prototype.init.prototype = Tween.prototype; + Tween.propHooks = { + _default: { + get: function (tween) { + var result; + if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) { + return tween.elem[tween.prop]; + } + result = jQuery.css(tween.elem, tween.prop, ''); + return !result || result === 'auto' ? 0 : result; + }, + set: function (tween) { + if (jQuery.fx.step[tween.prop]) { + jQuery.fx.step[tween.prop](tween); + } else if (tween.elem.nodeType === 1 && (jQuery.cssHooks[tween.prop] || tween.elem.style[finalPropName(tween.prop)] != null)) { + jQuery.style(tween.elem, tween.prop, tween.now + tween.unit); + } else { + tween.elem[tween.prop] = tween.now; + } + } + } + }; + Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function (tween) { + if (tween.elem.nodeType && tween.elem.parentNode) { + tween.elem[tween.prop] = tween.now; + } + } + }; + jQuery.easing = { + linear: function (p) { + return p; + }, + swing: function (p) { + return 0.5 - Math.cos(p * Math.PI) / 2; + }, + _default: 'swing' + }; + jQuery.fx = Tween.prototype.init; + jQuery.fx.step = {}; + var fxNow, inProgress, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; + function schedule() { + if (inProgress) { + if (document.hidden === false && window.requestAnimationFrame) { + window.requestAnimationFrame(schedule); + } else { + window.setTimeout(schedule, jQuery.fx.interval); + } + jQuery.fx.tick(); + } + } + function createFxNow() { + window.setTimeout(function () { + fxNow = undefined; + }); + return fxNow = Date.now(); + } + function genFx(type, includeWidth) { + var which, i = 0, attrs = { height: type }; + includeWidth = includeWidth ? 1 : 0; + for (; i < 4; i += 2 - includeWidth) { + which = cssExpand[i]; + attrs['margin' + which] = attrs['padding' + which] = type; + } + if (includeWidth) { + attrs.opacity = attrs.width = type; + } + return attrs; + } + function createTween(value, prop, animation) { + var tween, collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners['*']), index = 0, length = collection.length; + for (; index < length; index++) { + if (tween = collection[index].call(animation, prop, value)) { + return tween; + } + } + } + function defaultPrefilter(elem, props, opts) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = 'width' in props || 'height' in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree(elem), dataShow = dataPriv.get(elem, 'fxshow'); + if (!opts.queue) { + hooks = jQuery._queueHooks(elem, 'fx'); + if (hooks.unqueued == null) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function () { + if (!hooks.unqueued) { + oldfire(); + } + }; + } + hooks.unqueued++; + anim.always(function () { + anim.always(function () { + hooks.unqueued--; + if (!jQuery.queue(elem, 'fx').length) { + hooks.empty.fire(); + } + }); + }); + } + for (prop in props) { + value = props[prop]; + if (rfxtypes.test(value)) { + delete props[prop]; + toggle = toggle || value === 'toggle'; + if (value === (hidden ? 'hide' : 'show')) { + if (value === 'show' && dataShow && dataShow[prop] !== undefined) { + hidden = true; + } else { + continue; + } + } + orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop); + } + } + propTween = !jQuery.isEmptyObject(props); + if (!propTween && jQuery.isEmptyObject(orig)) { + return; + } + if (isBox && elem.nodeType === 1) { + opts.overflow = [ + style.overflow, + style.overflowX, + style.overflowY + ]; + restoreDisplay = dataShow && dataShow.display; + if (restoreDisplay == null) { + restoreDisplay = dataPriv.get(elem, 'display'); + } + display = jQuery.css(elem, 'display'); + if (display === 'none') { + if (restoreDisplay) { + display = restoreDisplay; + } else { + showHide([elem], true); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css(elem, 'display'); + showHide([elem]); + } + } + if (display === 'inline' || display === 'inline-block' && restoreDisplay != null) { + if (jQuery.css(elem, 'float') === 'none') { + if (!propTween) { + anim.done(function () { + style.display = restoreDisplay; + }); + if (restoreDisplay == null) { + display = style.display; + restoreDisplay = display === 'none' ? '' : display; + } + } + style.display = 'inline-block'; + } + } + } + if (opts.overflow) { + style.overflow = 'hidden'; + anim.always(function () { + style.overflow = opts.overflow[0]; + style.overflowX = opts.overflow[1]; + style.overflowY = opts.overflow[2]; + }); + } + propTween = false; + for (prop in orig) { + if (!propTween) { + if (dataShow) { + if ('hidden' in dataShow) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access(elem, 'fxshow', { display: restoreDisplay }); + } + if (toggle) { + dataShow.hidden = !hidden; + } + if (hidden) { + showHide([elem], true); + } + anim.done(function () { + if (!hidden) { + showHide([elem]); + } + dataPriv.remove(elem, 'fxshow'); + for (prop in orig) { + jQuery.style(elem, prop, orig[prop]); + } + }); + } + propTween = createTween(hidden ? dataShow[prop] : 0, prop, anim); + if (!(prop in dataShow)) { + dataShow[prop] = propTween.start; + if (hidden) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } + } + function propFilter(props, specialEasing) { + var index, name, easing, value, hooks; + for (index in props) { + name = camelCase(index); + easing = specialEasing[name]; + value = props[index]; + if (Array.isArray(value)) { + easing = value[1]; + value = props[index] = value[0]; + } + if (index !== name) { + props[name] = value; + delete props[index]; + } + hooks = jQuery.cssHooks[name]; + if (hooks && 'expand' in hooks) { + value = hooks.expand(value); + delete props[name]; + for (index in value) { + if (!(index in props)) { + props[index] = value[index]; + specialEasing[index] = easing; + } + } + } else { + specialEasing[name] = easing; + } + } + } + function Animation(elem, properties, options) { + var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always(function () { + delete tick.elem; + }), tick = function () { + if (stopped) { + return false; + } + var currentTime = fxNow || createFxNow(), remaining = Math.max(0, animation.startTime + animation.duration - currentTime), temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; + for (; index < length; index++) { + animation.tweens[index].run(percent); + } + deferred.notifyWith(elem, [ + animation, + percent, + remaining + ]); + if (percent < 1 && length) { + return remaining; + } + if (!length) { + deferred.notifyWith(elem, [ + animation, + 1, + 0 + ]); + } + deferred.resolveWith(elem, [animation]); + return false; + }, animation = deferred.promise({ + elem: elem, + props: jQuery.extend({}, properties), + opts: jQuery.extend(true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function (prop, end) { + var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing); + animation.tweens.push(tween); + return tween; + }, + stop: function (gotoEnd) { + var index = 0, length = gotoEnd ? animation.tweens.length : 0; + if (stopped) { + return this; + } + stopped = true; + for (; index < length; index++) { + animation.tweens[index].run(1); + } + if (gotoEnd) { + deferred.notifyWith(elem, [ + animation, + 1, + 0 + ]); + deferred.resolveWith(elem, [ + animation, + gotoEnd + ]); + } else { + deferred.rejectWith(elem, [ + animation, + gotoEnd + ]); + } + return this; + } + }), props = animation.props; + propFilter(props, animation.opts.specialEasing); + for (; index < length; index++) { + result = Animation.prefilters[index].call(animation, elem, props, animation.opts); + if (result) { + if (isFunction(result.stop)) { + jQuery._queueHooks(animation.elem, animation.opts.queue).stop = result.stop.bind(result); + } + return result; + } + } + jQuery.map(props, createTween, animation); + if (isFunction(animation.opts.start)) { + animation.opts.start.call(elem, animation); + } + animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always); + jQuery.fx.timer(jQuery.extend(tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + })); + return animation; + } + jQuery.Animation = jQuery.extend(Animation, { + tweeners: { + '*': [function (prop, value) { + var tween = this.createTween(prop, value); + adjustCSS(tween.elem, prop, rcssNum.exec(value), tween); + return tween; + }] + }, + tweener: function (props, callback) { + if (isFunction(props)) { + callback = props; + props = ['*']; + } else { + props = props.match(rnothtmlwhite); + } + var prop, index = 0, length = props.length; + for (; index < length; index++) { + prop = props[index]; + Animation.tweeners[prop] = Animation.tweeners[prop] || []; + Animation.tweeners[prop].unshift(callback); + } + }, + prefilters: [defaultPrefilter], + prefilter: function (callback, prepend) { + if (prepend) { + Animation.prefilters.unshift(callback); + } else { + Animation.prefilters.push(callback); + } + } + }); + jQuery.speed = function (speed, easing, fn) { + var opt = speed && typeof speed === 'object' ? jQuery.extend({}, speed) : { + complete: fn || !fn && easing || isFunction(speed) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction(easing) && easing + }; + if (jQuery.fx.off) { + opt.duration = 0; + } else { + if (typeof opt.duration !== 'number') { + if (opt.duration in jQuery.fx.speeds) { + opt.duration = jQuery.fx.speeds[opt.duration]; + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + if (opt.queue == null || opt.queue === true) { + opt.queue = 'fx'; + } + opt.old = opt.complete; + opt.complete = function () { + if (isFunction(opt.old)) { + opt.old.call(this); + } + if (opt.queue) { + jQuery.dequeue(this, opt.queue); + } + }; + return opt; + }; + jQuery.fn.extend({ + fadeTo: function (speed, to, easing, callback) { + return this.filter(isHiddenWithinTree).css('opacity', 0).show().end().animate({ opacity: to }, speed, easing, callback); + }, + animate: function (prop, speed, easing, callback) { + var empty = jQuery.isEmptyObject(prop), optall = jQuery.speed(speed, easing, callback), doAnimation = function () { + var anim = Animation(this, jQuery.extend({}, prop), optall); + if (empty || dataPriv.get(this, 'finish')) { + anim.stop(true); + } + }; + doAnimation.finish = doAnimation; + return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation); + }, + stop: function (type, clearQueue, gotoEnd) { + var stopQueue = function (hooks) { + var stop = hooks.stop; + delete hooks.stop; + stop(gotoEnd); + }; + if (typeof type !== 'string') { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if (clearQueue) { + this.queue(type || 'fx', []); + } + return this.each(function () { + var dequeue = true, index = type != null && type + 'queueHooks', timers = jQuery.timers, data = dataPriv.get(this); + if (index) { + if (data[index] && data[index].stop) { + stopQueue(data[index]); + } + } else { + for (index in data) { + if (data[index] && data[index].stop && rrun.test(index)) { + stopQueue(data[index]); + } + } + } + for (index = timers.length; index--;) { + if (timers[index].elem === this && (type == null || timers[index].queue === type)) { + timers[index].anim.stop(gotoEnd); + dequeue = false; + timers.splice(index, 1); + } + } + if (dequeue || !gotoEnd) { + jQuery.dequeue(this, type); + } + }); + }, + finish: function (type) { + if (type !== false) { + type = type || 'fx'; + } + return this.each(function () { + var index, data = dataPriv.get(this), queue = data[type + 'queue'], hooks = data[type + 'queueHooks'], timers = jQuery.timers, length = queue ? queue.length : 0; + data.finish = true; + jQuery.queue(this, type, []); + if (hooks && hooks.stop) { + hooks.stop.call(this, true); + } + for (index = timers.length; index--;) { + if (timers[index].elem === this && timers[index].queue === type) { + timers[index].anim.stop(true); + timers.splice(index, 1); + } + } + for (index = 0; index < length; index++) { + if (queue[index] && queue[index].finish) { + queue[index].finish.call(this); + } + } + delete data.finish; + }); + } + }); + jQuery.each([ + 'toggle', + 'show', + 'hide' + ], function (_i, name) { + var cssFn = jQuery.fn[name]; + jQuery.fn[name] = function (speed, easing, callback) { + return speed == null || typeof speed === 'boolean' ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback); + }; + }); + jQuery.each({ + slideDown: genFx('show'), + slideUp: genFx('hide'), + slideToggle: genFx('toggle'), + fadeIn: { opacity: 'show' }, + fadeOut: { opacity: 'hide' }, + fadeToggle: { opacity: 'toggle' } + }, function (name, props) { + jQuery.fn[name] = function (speed, easing, callback) { + return this.animate(props, speed, easing, callback); + }; + }); + jQuery.timers = []; + jQuery.fx.tick = function () { + var timer, i = 0, timers = jQuery.timers; + fxNow = Date.now(); + for (; i < timers.length; i++) { + timer = timers[i]; + if (!timer() && timers[i] === timer) { + timers.splice(i--, 1); + } + } + if (!timers.length) { + jQuery.fx.stop(); + } + fxNow = undefined; + }; + jQuery.fx.timer = function (timer) { + jQuery.timers.push(timer); + jQuery.fx.start(); + }; + jQuery.fx.interval = 13; + jQuery.fx.start = function () { + if (inProgress) { + return; + } + inProgress = true; + schedule(); + }; + jQuery.fx.stop = function () { + inProgress = null; + }; + jQuery.fx.speeds = { + slow: 600, + fast: 200, + _default: 400 + }; + jQuery.fn.delay = function (time, type) { + time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; + type = type || 'fx'; + return this.queue(type, function (next, hooks) { + var timeout = window.setTimeout(next, time); + hooks.stop = function () { + window.clearTimeout(timeout); + }; + }); + }; + (function () { + var input = document.createElement('input'), select = document.createElement('select'), opt = select.appendChild(document.createElement('option')); + input.type = 'checkbox'; + support.checkOn = input.value !== ''; + support.optSelected = opt.selected; + input = document.createElement('input'); + input.value = 't'; + input.type = 'radio'; + support.radioValue = input.value === 't'; + }()); + var boolHook, attrHandle = jQuery.expr.attrHandle; + jQuery.fn.extend({ + attr: function (name, value) { + return access(this, jQuery.attr, name, value, arguments.length > 1); + }, + removeAttr: function (name) { + return this.each(function () { + jQuery.removeAttr(this, name); + }); + } + }); + jQuery.extend({ + attr: function (elem, name, value) { + var ret, hooks, nType = elem.nodeType; + if (nType === 3 || nType === 8 || nType === 2) { + return; + } + if (typeof elem.getAttribute === 'undefined') { + return jQuery.prop(elem, name, value); + } + if (nType !== 1 || !jQuery.isXMLDoc(elem)) { + hooks = jQuery.attrHooks[name.toLowerCase()] || (jQuery.expr.match.bool.test(name) ? boolHook : undefined); + } + if (value !== undefined) { + if (value === null) { + jQuery.removeAttr(elem, name); + return; + } + if (hooks && 'set' in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { + return ret; + } + elem.setAttribute(name, value + ''); + return value; + } + if (hooks && 'get' in hooks && (ret = hooks.get(elem, name)) !== null) { + return ret; + } + ret = jQuery.find.attr(elem, name); + return ret == null ? undefined : ret; + }, + attrHooks: { + type: { + set: function (elem, value) { + if (!support.radioValue && value === 'radio' && nodeName(elem, 'input')) { + var val = elem.value; + elem.setAttribute('type', value); + if (val) { + elem.value = val; + } + return value; + } + } + } + }, + removeAttr: function (elem, value) { + var name, i = 0, attrNames = value && value.match(rnothtmlwhite); + if (attrNames && elem.nodeType === 1) { + while (name = attrNames[i++]) { + elem.removeAttribute(name); + } + } + } + }); + boolHook = { + set: function (elem, value, name) { + if (value === false) { + jQuery.removeAttr(elem, name); + } else { + elem.setAttribute(name, name); + } + return name; + } + }; + jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (_i, name) { + var getter = attrHandle[name] || jQuery.find.attr; + attrHandle[name] = function (elem, name, isXML) { + var ret, handle, lowercaseName = name.toLowerCase(); + if (!isXML) { + handle = attrHandle[lowercaseName]; + attrHandle[lowercaseName] = ret; + ret = getter(elem, name, isXML) != null ? lowercaseName : null; + attrHandle[lowercaseName] = handle; + } + return ret; + }; + }); + var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; + jQuery.fn.extend({ + prop: function (name, value) { + return access(this, jQuery.prop, name, value, arguments.length > 1); + }, + removeProp: function (name) { + return this.each(function () { + delete this[jQuery.propFix[name] || name]; + }); + } + }); + jQuery.extend({ + prop: function (elem, name, value) { + var ret, hooks, nType = elem.nodeType; + if (nType === 3 || nType === 8 || nType === 2) { + return; + } + if (nType !== 1 || !jQuery.isXMLDoc(elem)) { + name = jQuery.propFix[name] || name; + hooks = jQuery.propHooks[name]; + } + if (value !== undefined) { + if (hooks && 'set' in hooks && (ret = hooks.set(elem, value, name)) !== undefined) { + return ret; + } + return elem[name] = value; + } + if (hooks && 'get' in hooks && (ret = hooks.get(elem, name)) !== null) { + return ret; + } + return elem[name]; + }, + propHooks: { + tabIndex: { + get: function (elem) { + var tabindex = jQuery.find.attr(elem, 'tabindex'); + if (tabindex) { + return parseInt(tabindex, 10); + } + if (rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href) { + return 0; + } + return -1; + } + } + }, + propFix: { + 'for': 'htmlFor', + 'class': 'className' + } + }); + if (!support.optSelected) { + jQuery.propHooks.selected = { + get: function (elem) { + var parent = elem.parentNode; + if (parent && parent.parentNode) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function (elem) { + var parent = elem.parentNode; + if (parent) { + parent.selectedIndex; + if (parent.parentNode) { + parent.parentNode.selectedIndex; + } + } + } + }; + } + jQuery.each([ + 'tabIndex', + 'readOnly', + 'maxLength', + 'cellSpacing', + 'cellPadding', + 'rowSpan', + 'colSpan', + 'useMap', + 'frameBorder', + 'contentEditable' + ], function () { + jQuery.propFix[this.toLowerCase()] = this; + }); + function stripAndCollapse(value) { + var tokens = value.match(rnothtmlwhite) || []; + return tokens.join(' '); + } + function getClass(elem) { + return elem.getAttribute && elem.getAttribute('class') || ''; + } + function classesToArray(value) { + if (Array.isArray(value)) { + return value; + } + if (typeof value === 'string') { + return value.match(rnothtmlwhite) || []; + } + return []; + } + jQuery.fn.extend({ + addClass: function (value) { + var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; + if (isFunction(value)) { + return this.each(function (j) { + jQuery(this).addClass(value.call(this, j, getClass(this))); + }); + } + classes = classesToArray(value); + if (classes.length) { + while (elem = this[i++]) { + curValue = getClass(elem); + cur = elem.nodeType === 1 && ' ' + stripAndCollapse(curValue) + ' '; + if (cur) { + j = 0; + while (clazz = classes[j++]) { + if (cur.indexOf(' ' + clazz + ' ') < 0) { + cur += clazz + ' '; + } + } + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) { + elem.setAttribute('class', finalValue); + } + } + } + } + return this; + }, + removeClass: function (value) { + var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; + if (isFunction(value)) { + return this.each(function (j) { + jQuery(this).removeClass(value.call(this, j, getClass(this))); + }); + } + if (!arguments.length) { + return this.attr('class', ''); + } + classes = classesToArray(value); + if (classes.length) { + while (elem = this[i++]) { + curValue = getClass(elem); + cur = elem.nodeType === 1 && ' ' + stripAndCollapse(curValue) + ' '; + if (cur) { + j = 0; + while (clazz = classes[j++]) { + while (cur.indexOf(' ' + clazz + ' ') > -1) { + cur = cur.replace(' ' + clazz + ' ', ' '); + } + } + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) { + elem.setAttribute('class', finalValue); + } + } + } + } + return this; + }, + toggleClass: function (value, stateVal) { + var type = typeof value, isValidValue = type === 'string' || Array.isArray(value); + if (typeof stateVal === 'boolean' && isValidValue) { + return stateVal ? this.addClass(value) : this.removeClass(value); + } + if (isFunction(value)) { + return this.each(function (i) { + jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal); + }); + } + return this.each(function () { + var className, i, self, classNames; + if (isValidValue) { + i = 0; + self = jQuery(this); + classNames = classesToArray(value); + while (className = classNames[i++]) { + if (self.hasClass(className)) { + self.removeClass(className); + } else { + self.addClass(className); + } + } + } else if (value === undefined || type === 'boolean') { + className = getClass(this); + if (className) { + dataPriv.set(this, '__className__', className); + } + if (this.setAttribute) { + this.setAttribute('class', className || value === false ? '' : dataPriv.get(this, '__className__') || ''); + } + } + }); + }, + hasClass: function (selector) { + var className, elem, i = 0; + className = ' ' + selector + ' '; + while (elem = this[i++]) { + if (elem.nodeType === 1 && (' ' + stripAndCollapse(getClass(elem)) + ' ').indexOf(className) > -1) { + return true; + } + } + return false; + } + }); + var rreturn = /\r/g; + jQuery.fn.extend({ + val: function (value) { + var hooks, ret, valueIsFunction, elem = this[0]; + if (!arguments.length) { + if (elem) { + hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()]; + if (hooks && 'get' in hooks && (ret = hooks.get(elem, 'value')) !== undefined) { + return ret; + } + ret = elem.value; + if (typeof ret === 'string') { + return ret.replace(rreturn, ''); + } + return ret == null ? '' : ret; + } + return; + } + valueIsFunction = isFunction(value); + return this.each(function (i) { + var val; + if (this.nodeType !== 1) { + return; + } + if (valueIsFunction) { + val = value.call(this, i, jQuery(this).val()); + } else { + val = value; + } + if (val == null) { + val = ''; + } else if (typeof val === 'number') { + val += ''; + } else if (Array.isArray(val)) { + val = jQuery.map(val, function (value) { + return value == null ? '' : value + ''; + }); + } + hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; + if (!hooks || !('set' in hooks) || hooks.set(this, val, 'value') === undefined) { + this.value = val; + } + }); + } + }); + jQuery.extend({ + valHooks: { + option: { + get: function (elem) { + var val = jQuery.find.attr(elem, 'value'); + return val != null ? val : stripAndCollapse(jQuery.text(elem)); + } + }, + select: { + get: function (elem) { + var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === 'select-one', values = one ? null : [], max = one ? index + 1 : options.length; + if (index < 0) { + i = max; + } else { + i = one ? index : 0; + } + for (; i < max; i++) { + option = options[i]; + if ((option.selected || i === index) && !option.disabled && (!option.parentNode.disabled || !nodeName(option.parentNode, 'optgroup'))) { + value = jQuery(option).val(); + if (one) { + return value; + } + values.push(value); + } + } + return values; + }, + set: function (elem, value) { + var optionSet, option, options = elem.options, values = jQuery.makeArray(value), i = options.length; + while (i--) { + option = options[i]; + if (option.selected = jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) { + optionSet = true; + } + } + if (!optionSet) { + elem.selectedIndex = -1; + } + return values; + } + } + } + }); + jQuery.each([ + 'radio', + 'checkbox' + ], function () { + jQuery.valHooks[this] = { + set: function (elem, value) { + if (Array.isArray(value)) { + return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1; + } + } + }; + if (!support.checkOn) { + jQuery.valHooks[this].get = function (elem) { + return elem.getAttribute('value') === null ? 'on' : elem.value; + }; + } + }); + support.focusin = 'onfocusin' in window; + var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, stopPropagationCallback = function (e) { + e.stopPropagation(); + }; + jQuery.extend(jQuery.event, { + trigger: function (event, data, elem, onlyHandlers) { + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [elem || document], type = hasOwn.call(event, 'type') ? event.type : event, namespaces = hasOwn.call(event, 'namespace') ? event.namespace.split('.') : []; + cur = lastElement = tmp = elem = elem || document; + if (elem.nodeType === 3 || elem.nodeType === 8) { + return; + } + if (rfocusMorph.test(type + jQuery.event.triggered)) { + return; + } + if (type.indexOf('.') > -1) { + namespaces = type.split('.'); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(':') < 0 && 'on' + type; + event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === 'object' && event); + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join('.'); + event.rnamespace = event.namespace ? new RegExp('(^|\\.)' + namespaces.join('\\.(?:.*\\.|)') + '(\\.|$)') : null; + event.result = undefined; + if (!event.target) { + event.target = elem; + } + data = data == null ? [event] : jQuery.makeArray(data, [event]); + special = jQuery.event.special[type] || {}; + if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) { + return; + } + if (!onlyHandlers && !special.noBubble && !isWindow(elem)) { + bubbleType = special.delegateType || type; + if (!rfocusMorph.test(bubbleType + type)) { + cur = cur.parentNode; + } + for (; cur; cur = cur.parentNode) { + eventPath.push(cur); + tmp = cur; + } + if (tmp === (elem.ownerDocument || document)) { + eventPath.push(tmp.defaultView || tmp.parentWindow || window); + } + } + i = 0; + while ((cur = eventPath[i++]) && !event.isPropagationStopped()) { + lastElement = cur; + event.type = i > 1 ? bubbleType : special.bindType || type; + handle = (dataPriv.get(cur, 'events') || Object.create(null))[event.type] && dataPriv.get(cur, 'handle'); + if (handle) { + handle.apply(cur, data); + } + handle = ontype && cur[ontype]; + if (handle && handle.apply && acceptData(cur)) { + event.result = handle.apply(cur, data); + if (event.result === false) { + event.preventDefault(); + } + } + } + event.type = type; + if (!onlyHandlers && !event.isDefaultPrevented()) { + if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) { + if (ontype && isFunction(elem[type]) && !isWindow(elem)) { + tmp = elem[ontype]; + if (tmp) { + elem[ontype] = null; + } + jQuery.event.triggered = type; + if (event.isPropagationStopped()) { + lastElement.addEventListener(type, stopPropagationCallback); + } + elem[type](); + if (event.isPropagationStopped()) { + lastElement.removeEventListener(type, stopPropagationCallback); + } + jQuery.event.triggered = undefined; + if (tmp) { + elem[ontype] = tmp; + } + } + } + } + return event.result; + }, + simulate: function (type, elem, event) { + var e = jQuery.extend(new jQuery.Event(), event, { + type: type, + isSimulated: true + }); + jQuery.event.trigger(e, null, elem); + } + }); + jQuery.fn.extend({ + trigger: function (type, data) { + return this.each(function () { + jQuery.event.trigger(type, data, this); + }); + }, + triggerHandler: function (type, data) { + var elem = this[0]; + if (elem) { + return jQuery.event.trigger(type, data, elem, true); + } + } + }); + if (!support.focusin) { + jQuery.each({ + focus: 'focusin', + blur: 'focusout' + }, function (orig, fix) { + var handler = function (event) { + jQuery.event.simulate(fix, event.target, jQuery.event.fix(event)); + }; + jQuery.event.special[fix] = { + setup: function () { + var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access(doc, fix); + if (!attaches) { + doc.addEventListener(orig, handler, true); + } + dataPriv.access(doc, fix, (attaches || 0) + 1); + }, + teardown: function () { + var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access(doc, fix) - 1; + if (!attaches) { + doc.removeEventListener(orig, handler, true); + dataPriv.remove(doc, fix); + } else { + dataPriv.access(doc, fix, attaches); + } + } + }; + }); + } + var location = window.location; + var nonce = { guid: Date.now() }; + var rquery = /\?/; + jQuery.parseXML = function (data) { + var xml, parserErrorElem; + if (!data || typeof data !== 'string') { + return null; + } + try { + xml = new window.DOMParser().parseFromString(data, 'text/xml'); + } catch (e) { + } + parserErrorElem = xml && xml.getElementsByTagName('parsererror')[0]; + if (!xml || parserErrorElem) { + jQuery.error('Invalid XML: ' + (parserErrorElem ? jQuery.map(parserErrorElem.childNodes, function (el) { + return el.textContent; + }).join('\n') : data)); + } + return xml; + }; + var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; + function buildParams(prefix, obj, traditional, add) { + var name; + if (Array.isArray(obj)) { + jQuery.each(obj, function (i, v) { + if (traditional || rbracket.test(prefix)) { + add(prefix, v); + } else { + buildParams(prefix + '[' + (typeof v === 'object' && v != null ? i : '') + ']', v, traditional, add); + } + }); + } else if (!traditional && toType(obj) === 'object') { + for (name in obj) { + buildParams(prefix + '[' + name + ']', obj[name], traditional, add); + } + } else { + add(prefix, obj); + } + } + jQuery.param = function (a, traditional) { + var prefix, s = [], add = function (key, valueOrFunction) { + var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction; + s[s.length] = encodeURIComponent(key) + '=' + encodeURIComponent(value == null ? '' : value); + }; + if (a == null) { + return ''; + } + if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) { + jQuery.each(a, function () { + add(this.name, this.value); + }); + } else { + for (prefix in a) { + buildParams(prefix, a[prefix], traditional, add); + } + } + return s.join('&'); + }; + jQuery.fn.extend({ + serialize: function () { + return jQuery.param(this.serializeArray()); + }, + serializeArray: function () { + return this.map(function () { + var elements = jQuery.prop(this, 'elements'); + return elements ? jQuery.makeArray(elements) : this; + }).filter(function () { + var type = this.type; + return this.name && !jQuery(this).is(':disabled') && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type)); + }).map(function (_i, elem) { + var val = jQuery(this).val(); + if (val == null) { + return null; + } + if (Array.isArray(val)) { + return jQuery.map(val, function (val) { + return { + name: elem.name, + value: val.replace(rCRLF, '\r\n') + }; + }); + } + return { + name: elem.name, + value: val.replace(rCRLF, '\r\n') + }; + }).get(); + } + }); + var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, prefilters = {}, transports = {}, allTypes = '*/'.concat('*'), originAnchor = document.createElement('a'); + originAnchor.href = location.href; + function addToPrefiltersOrTransports(structure) { + return function (dataTypeExpression, func) { + if (typeof dataTypeExpression !== 'string') { + func = dataTypeExpression; + dataTypeExpression = '*'; + } + var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match(rnothtmlwhite) || []; + if (isFunction(func)) { + while (dataType = dataTypes[i++]) { + if (dataType[0] === '+') { + dataType = dataType.slice(1) || '*'; + (structure[dataType] = structure[dataType] || []).unshift(func); + } else { + (structure[dataType] = structure[dataType] || []).push(func); + } + } + } + }; + } + function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) { + var inspected = {}, seekingTransport = structure === transports; + function inspect(dataType) { + var selected; + inspected[dataType] = true; + jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) { + var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR); + if (typeof dataTypeOrTransport === 'string' && !seekingTransport && !inspected[dataTypeOrTransport]) { + options.dataTypes.unshift(dataTypeOrTransport); + inspect(dataTypeOrTransport); + return false; + } else if (seekingTransport) { + return !(selected = dataTypeOrTransport); + } + }); + return selected; + } + return inspect(options.dataTypes[0]) || !inspected['*'] && inspect('*'); + } + function ajaxExtend(target, src) { + var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for (key in src) { + if (src[key] !== undefined) { + (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key]; + } + } + if (deep) { + jQuery.extend(true, target, deep); + } + return target; + } + function ajaxHandleResponses(s, jqXHR, responses) { + var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; + while (dataTypes[0] === '*') { + dataTypes.shift(); + if (ct === undefined) { + ct = s.mimeType || jqXHR.getResponseHeader('Content-Type'); + } + } + if (ct) { + for (type in contents) { + if (contents[type] && contents[type].test(ct)) { + dataTypes.unshift(type); + break; + } + } + } + if (dataTypes[0] in responses) { + finalDataType = dataTypes[0]; + } else { + for (type in responses) { + if (!dataTypes[0] || s.converters[type + ' ' + dataTypes[0]]) { + finalDataType = type; + break; + } + if (!firstDataType) { + firstDataType = type; + } + } + finalDataType = finalDataType || firstDataType; + } + if (finalDataType) { + if (finalDataType !== dataTypes[0]) { + dataTypes.unshift(finalDataType); + } + return responses[finalDataType]; + } + } + function ajaxConvert(s, response, jqXHR, isSuccess) { + var conv2, current, conv, tmp, prev, converters = {}, dataTypes = s.dataTypes.slice(); + if (dataTypes[1]) { + for (conv in s.converters) { + converters[conv.toLowerCase()] = s.converters[conv]; + } + } + current = dataTypes.shift(); + while (current) { + if (s.responseFields[current]) { + jqXHR[s.responseFields[current]] = response; + } + if (!prev && isSuccess && s.dataFilter) { + response = s.dataFilter(response, s.dataType); + } + prev = current; + current = dataTypes.shift(); + if (current) { + if (current === '*') { + current = prev; + } else if (prev !== '*' && prev !== current) { + conv = converters[prev + ' ' + current] || converters['* ' + current]; + if (!conv) { + for (conv2 in converters) { + tmp = conv2.split(' '); + if (tmp[1] === current) { + conv = converters[prev + ' ' + tmp[0]] || converters['* ' + tmp[0]]; + if (conv) { + if (conv === true) { + conv = converters[conv2]; + } else if (converters[conv2] !== true) { + current = tmp[0]; + dataTypes.unshift(tmp[1]); + } + break; + } + } + } + } + if (conv !== true) { + if (conv && s.throws) { + response = conv(response); + } else { + try { + response = conv(response); + } catch (e) { + return { + state: 'parsererror', + error: conv ? e : 'No conversion from ' + prev + ' to ' + current + }; + } + } + } + } + } + } + return { + state: 'success', + data: response + }; + } + jQuery.extend({ + active: 0, + lastModified: {}, + etag: {}, + ajaxSettings: { + url: location.href, + type: 'GET', + isLocal: rlocalProtocol.test(location.protocol), + global: true, + processData: true, + async: true, + contentType: 'application/x-www-form-urlencoded; charset=UTF-8', + accepts: { + '*': allTypes, + text: 'text/plain', + html: 'text/html', + xml: 'application/xml, text/xml', + json: 'application/json, text/javascript' + }, + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + responseFields: { + xml: 'responseXML', + text: 'responseText', + json: 'responseJSON' + }, + converters: { + '* text': String, + 'text html': true, + 'text json': JSON.parse, + 'text xml': jQuery.parseXML + }, + flatOptions: { + url: true, + context: true + } + }, + ajaxSetup: function (target, settings) { + return settings ? ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) : ajaxExtend(jQuery.ajaxSettings, target); + }, + ajaxPrefilter: addToPrefiltersOrTransports(prefilters), + ajaxTransport: addToPrefiltersOrTransports(transports), + ajax: function (url, options) { + if (typeof url === 'object') { + options = url; + url = undefined; + } + options = options || {}; + var transport, cacheURL, responseHeadersString, responseHeaders, timeoutTimer, urlAnchor, completed, fireGlobals, i, uncached, s = jQuery.ajaxSetup({}, options), callbackContext = s.context || s, globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event, deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks('once memory'), statusCode = s.statusCode || {}, requestHeaders = {}, requestHeadersNames = {}, strAbort = 'canceled', jqXHR = { + readyState: 0, + getResponseHeader: function (key) { + var match; + if (completed) { + if (!responseHeaders) { + responseHeaders = {}; + while (match = rheaders.exec(responseHeadersString)) { + responseHeaders[match[1].toLowerCase() + ' '] = (responseHeaders[match[1].toLowerCase() + ' '] || []).concat(match[2]); + } + } + match = responseHeaders[key.toLowerCase() + ' ']; + } + return match == null ? null : match.join(', '); + }, + getAllResponseHeaders: function () { + return completed ? responseHeadersString : null; + }, + setRequestHeader: function (name, value) { + if (completed == null) { + name = requestHeadersNames[name.toLowerCase()] = requestHeadersNames[name.toLowerCase()] || name; + requestHeaders[name] = value; + } + return this; + }, + overrideMimeType: function (type) { + if (completed == null) { + s.mimeType = type; + } + return this; + }, + statusCode: function (map) { + var code; + if (map) { + if (completed) { + jqXHR.always(map[jqXHR.status]); + } else { + for (code in map) { + statusCode[code] = [ + statusCode[code], + map[code] + ]; + } + } + } + return this; + }, + abort: function (statusText) { + var finalText = statusText || strAbort; + if (transport) { + transport.abort(finalText); + } + done(0, finalText); + return this; + } + }; + deferred.promise(jqXHR); + s.url = ((url || s.url || location.href) + '').replace(rprotocol, location.protocol + '//'); + s.type = options.method || options.type || s.method || s.type; + s.dataTypes = (s.dataType || '*').toLowerCase().match(rnothtmlwhite) || ['']; + if (s.crossDomain == null) { + urlAnchor = document.createElement('a'); + try { + urlAnchor.href = s.url; + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + '//' + originAnchor.host !== urlAnchor.protocol + '//' + urlAnchor.host; + } catch (e) { + s.crossDomain = true; + } + } + if (s.data && s.processData && typeof s.data !== 'string') { + s.data = jQuery.param(s.data, s.traditional); + } + inspectPrefiltersOrTransports(prefilters, s, options, jqXHR); + if (completed) { + return jqXHR; + } + fireGlobals = jQuery.event && s.global; + if (fireGlobals && jQuery.active++ === 0) { + jQuery.event.trigger('ajaxStart'); + } + s.type = s.type.toUpperCase(); + s.hasContent = !rnoContent.test(s.type); + cacheURL = s.url.replace(rhash, ''); + if (!s.hasContent) { + uncached = s.url.slice(cacheURL.length); + if (s.data && (s.processData || typeof s.data === 'string')) { + cacheURL += (rquery.test(cacheURL) ? '&' : '?') + s.data; + delete s.data; + } + if (s.cache === false) { + cacheURL = cacheURL.replace(rantiCache, '$1'); + uncached = (rquery.test(cacheURL) ? '&' : '?') + '_=' + nonce.guid++ + uncached; + } + s.url = cacheURL + uncached; + } else if (s.data && s.processData && (s.contentType || '').indexOf('application/x-www-form-urlencoded') === 0) { + s.data = s.data.replace(r20, '+'); + } + if (s.ifModified) { + if (jQuery.lastModified[cacheURL]) { + jqXHR.setRequestHeader('If-Modified-Since', jQuery.lastModified[cacheURL]); + } + if (jQuery.etag[cacheURL]) { + jqXHR.setRequestHeader('If-None-Match', jQuery.etag[cacheURL]); + } + } + if (s.data && s.hasContent && s.contentType !== false || options.contentType) { + jqXHR.setRequestHeader('Content-Type', s.contentType); + } + jqXHR.setRequestHeader('Accept', s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== '*' ? ', ' + allTypes + '; q=0.01' : '') : s.accepts['*']); + for (i in s.headers) { + jqXHR.setRequestHeader(i, s.headers[i]); + } + if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || completed)) { + return jqXHR.abort(); + } + strAbort = 'abort'; + completeDeferred.add(s.complete); + jqXHR.done(s.success); + jqXHR.fail(s.error); + transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR); + if (!transport) { + done(-1, 'No Transport'); + } else { + jqXHR.readyState = 1; + if (fireGlobals) { + globalEventContext.trigger('ajaxSend', [ + jqXHR, + s + ]); + } + if (completed) { + return jqXHR; + } + if (s.async && s.timeout > 0) { + timeoutTimer = window.setTimeout(function () { + jqXHR.abort('timeout'); + }, s.timeout); + } + try { + completed = false; + transport.send(requestHeaders, done); + } catch (e) { + if (completed) { + throw e; + } + done(-1, e); + } + } + function done(status, nativeStatusText, responses, headers) { + var isSuccess, success, error, response, modified, statusText = nativeStatusText; + if (completed) { + return; + } + completed = true; + if (timeoutTimer) { + window.clearTimeout(timeoutTimer); + } + transport = undefined; + responseHeadersString = headers || ''; + jqXHR.readyState = status > 0 ? 4 : 0; + isSuccess = status >= 200 && status < 300 || status === 304; + if (responses) { + response = ajaxHandleResponses(s, jqXHR, responses); + } + if (!isSuccess && jQuery.inArray('script', s.dataTypes) > -1 && jQuery.inArray('json', s.dataTypes) < 0) { + s.converters['text script'] = function () { + }; + } + response = ajaxConvert(s, response, jqXHR, isSuccess); + if (isSuccess) { + if (s.ifModified) { + modified = jqXHR.getResponseHeader('Last-Modified'); + if (modified) { + jQuery.lastModified[cacheURL] = modified; + } + modified = jqXHR.getResponseHeader('etag'); + if (modified) { + jQuery.etag[cacheURL] = modified; + } + } + if (status === 204 || s.type === 'HEAD') { + statusText = 'nocontent'; + } else if (status === 304) { + statusText = 'notmodified'; + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + error = statusText; + if (status || !statusText) { + statusText = 'error'; + if (status < 0) { + status = 0; + } + } + } + jqXHR.status = status; + jqXHR.statusText = (nativeStatusText || statusText) + ''; + if (isSuccess) { + deferred.resolveWith(callbackContext, [ + success, + statusText, + jqXHR + ]); + } else { + deferred.rejectWith(callbackContext, [ + jqXHR, + statusText, + error + ]); + } + jqXHR.statusCode(statusCode); + statusCode = undefined; + if (fireGlobals) { + globalEventContext.trigger(isSuccess ? 'ajaxSuccess' : 'ajaxError', [ + jqXHR, + s, + isSuccess ? success : error + ]); + } + completeDeferred.fireWith(callbackContext, [ + jqXHR, + statusText + ]); + if (fireGlobals) { + globalEventContext.trigger('ajaxComplete', [ + jqXHR, + s + ]); + if (!--jQuery.active) { + jQuery.event.trigger('ajaxStop'); + } + } + } + return jqXHR; + }, + getJSON: function (url, data, callback) { + return jQuery.get(url, data, callback, 'json'); + }, + getScript: function (url, callback) { + return jQuery.get(url, undefined, callback, 'script'); + } + }); + jQuery.each([ + 'get', + 'post' + ], function (_i, method) { + jQuery[method] = function (url, data, callback, type) { + if (isFunction(data)) { + type = type || callback; + callback = data; + data = undefined; + } + return jQuery.ajax(jQuery.extend({ + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject(url) && url)); + }; + }); + jQuery.ajaxPrefilter(function (s) { + var i; + for (i in s.headers) { + if (i.toLowerCase() === 'content-type') { + s.contentType = s.headers[i] || ''; + } + } + }); + jQuery._evalUrl = function (url, options, doc) { + return jQuery.ajax({ + url: url, + type: 'GET', + dataType: 'script', + cache: true, + async: false, + global: false, + converters: { + 'text script': function () { + } + }, + dataFilter: function (response) { + jQuery.globalEval(response, options, doc); + } + }); + }; + jQuery.fn.extend({ + wrapAll: function (html) { + var wrap; + if (this[0]) { + if (isFunction(html)) { + html = html.call(this[0]); + } + wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true); + if (this[0].parentNode) { + wrap.insertBefore(this[0]); + } + wrap.map(function () { + var elem = this; + while (elem.firstElementChild) { + elem = elem.firstElementChild; + } + return elem; + }).append(this); + } + return this; + }, + wrapInner: function (html) { + if (isFunction(html)) { + return this.each(function (i) { + jQuery(this).wrapInner(html.call(this, i)); + }); + } + return this.each(function () { + var self = jQuery(this), contents = self.contents(); + if (contents.length) { + contents.wrapAll(html); + } else { + self.append(html); + } + }); + }, + wrap: function (html) { + var htmlIsFunction = isFunction(html); + return this.each(function (i) { + jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html); + }); + }, + unwrap: function (selector) { + this.parent(selector).not('body').each(function () { + jQuery(this).replaceWith(this.childNodes); + }); + return this; + } + }); + jQuery.expr.pseudos.hidden = function (elem) { + return !jQuery.expr.pseudos.visible(elem); + }; + jQuery.expr.pseudos.visible = function (elem) { + return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length); + }; + jQuery.ajaxSettings.xhr = function () { + try { + return new window.XMLHttpRequest(); + } catch (e) { + } + }; + var xhrSuccessStatus = { + 0: 200, + 1223: 204 + }, xhrSupported = jQuery.ajaxSettings.xhr(); + support.cors = !!xhrSupported && 'withCredentials' in xhrSupported; + support.ajax = xhrSupported = !!xhrSupported; + jQuery.ajaxTransport(function (options) { + var callback, errorCallback; + if (support.cors || xhrSupported && !options.crossDomain) { + return { + send: function (headers, complete) { + var i, xhr = options.xhr(); + xhr.open(options.type, options.url, options.async, options.username, options.password); + if (options.xhrFields) { + for (i in options.xhrFields) { + xhr[i] = options.xhrFields[i]; + } + } + if (options.mimeType && xhr.overrideMimeType) { + xhr.overrideMimeType(options.mimeType); + } + if (!options.crossDomain && !headers['X-Requested-With']) { + headers['X-Requested-With'] = 'XMLHttpRequest'; + } + for (i in headers) { + xhr.setRequestHeader(i, headers[i]); + } + callback = function (type) { + return function () { + if (callback) { + callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null; + if (type === 'abort') { + xhr.abort(); + } else if (type === 'error') { + if (typeof xhr.status !== 'number') { + complete(0, 'error'); + } else { + complete(xhr.status, xhr.statusText); + } + } else { + complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText, (xhr.responseType || 'text') !== 'text' || typeof xhr.responseText !== 'string' ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders()); + } + } + }; + }; + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback('error'); + if (xhr.onabort !== undefined) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + window.setTimeout(function () { + if (callback) { + errorCallback(); + } + }); + } + }; + } + callback = callback('abort'); + try { + xhr.send(options.hasContent && options.data || null); + } catch (e) { + if (callback) { + throw e; + } + } + }, + abort: function () { + if (callback) { + callback(); + } + } + }; + } + }); + jQuery.ajaxPrefilter(function (s) { + if (s.crossDomain) { + s.contents.script = false; + } + }); + jQuery.ajaxSetup({ + accepts: { script: 'text/javascript, application/javascript, ' + 'application/ecmascript, application/x-ecmascript' }, + contents: { script: /\b(?:java|ecma)script\b/ }, + converters: { + 'text script': function (text) { + jQuery.globalEval(text); + return text; + } + } + }); + jQuery.ajaxPrefilter('script', function (s) { + if (s.cache === undefined) { + s.cache = false; + } + if (s.crossDomain) { + s.type = 'GET'; + } + }); + jQuery.ajaxTransport('script', function (s) { + if (s.crossDomain || s.scriptAttrs) { + var script, callback; + return { + send: function (_, complete) { + script = jQuery('', 'script tag content serialized'); + }); +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/utils*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/utils', ['exports'], function (exports) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + var WSP = /[\t\n\f ]/; + var ALPHA = /[A-Za-z]/; + var CRLF = /\r\n?/g; + function isSpace(char) { + return WSP.test(char); + } + function isAlpha(char) { + return ALPHA.test(char); + } + function preprocessInput(input) { + return input.replace(CRLF, '\n'); + } + exports.isSpace = isSpace; + exports.isAlpha = isAlpha; + exports.preprocessInput = preprocessInput; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/evented-tokenizer*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/evented-tokenizer', [ + 'exports', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/utils' +], function (exports, _utils) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + function EventedTokenizer(delegate, entityParser) { + this.delegate = delegate; + this.entityParser = entityParser; + this.state = null; + this.input = null; + this.index = -1; + this.line = -1; + this.column = -1; + this.tagLine = -1; + this.tagColumn = -1; + this.reset(); + } + EventedTokenizer.prototype = { + reset: function reset() { + this.state = 'beforeData'; + this.input = ''; + this.index = 0; + this.line = 1; + this.column = 0; + this.tagLine = -1; + this.tagColumn = -1; + this.delegate.reset(); + }, + tokenize: function tokenize(input) { + this.reset(); + this.tokenizePart(input); + this.tokenizeEOF(); + }, + tokenizePart: function tokenizePart(input) { + this.input += (0, _utils.preprocessInput)(input); + while (this.index < this.input.length) { + this.states[this.state].call(this); + } + }, + tokenizeEOF: function tokenizeEOF() { + this.flushData(); + }, + flushData: function flushData() { + if (this.state === 'data') { + this.delegate.finishData(); + this.state = 'beforeData'; + } + }, + peek: function peek() { + return this.input.charAt(this.index); + }, + consume: function consume() { + var char = this.peek(); + this.index++; + if (char === '\n') { + this.line++; + this.column = 0; + } else { + this.column++; + } + return char; + }, + consumeCharRef: function consumeCharRef() { + var endIndex = this.input.indexOf(';', this.index); + if (endIndex === -1) { + return; + } + var entity = this.input.slice(this.index, endIndex); + var chars = this.entityParser.parse(entity); + if (chars) { + var count = entity.length; + while (count) { + this.consume(); + count--; + } + this.consume(); + return chars; + } + }, + markTagStart: function markTagStart() { + this.tagLine = this.line; + this.tagColumn = this.column; + if (this.delegate.tagOpen) { + this.delegate.tagOpen(); + } + }, + states: { + beforeData: function beforeData() { + var char = this.peek(); + if (char === '<') { + this.state = 'tagOpen'; + this.markTagStart(); + this.consume(); + } else { + this.state = 'data'; + this.delegate.beginData(); + } + }, + data: function data() { + var char = this.peek(); + if (char === '<') { + this.delegate.finishData(); + this.state = 'tagOpen'; + this.markTagStart(); + this.consume(); + } else if (char === '&') { + this.consume(); + this.delegate.appendToData(this.consumeCharRef() || '&'); + } else { + this.consume(); + this.delegate.appendToData(char); + } + }, + tagOpen: function tagOpen() { + var char = this.consume(); + if (char === '!') { + this.state = 'markupDeclaration'; + } else if (char === '/') { + this.state = 'endTagOpen'; + } else if ((0, _utils.isAlpha)(char)) { + this.state = 'tagName'; + this.delegate.beginStartTag(); + this.delegate.appendToTagName(char.toLowerCase()); + } + }, + markupDeclaration: function markupDeclaration() { + var char = this.consume(); + if (char === '-' && this.input.charAt(this.index) === '-') { + this.consume(); + this.state = 'commentStart'; + this.delegate.beginComment(); + } + }, + commentStart: function commentStart() { + var char = this.consume(); + if (char === '-') { + this.state = 'commentStartDash'; + } else if (char === '>') { + this.delegate.finishComment(); + this.state = 'beforeData'; + } else { + this.delegate.appendToCommentData(char); + this.state = 'comment'; + } + }, + commentStartDash: function commentStartDash() { + var char = this.consume(); + if (char === '-') { + this.state = 'commentEnd'; + } else if (char === '>') { + this.delegate.finishComment(); + this.state = 'beforeData'; + } else { + this.delegate.appendToCommentData('-'); + this.state = 'comment'; + } + }, + comment: function comment() { + var char = this.consume(); + if (char === '-') { + this.state = 'commentEndDash'; + } else { + this.delegate.appendToCommentData(char); + } + }, + commentEndDash: function commentEndDash() { + var char = this.consume(); + if (char === '-') { + this.state = 'commentEnd'; + } else { + this.delegate.appendToCommentData('-' + char); + this.state = 'comment'; + } + }, + commentEnd: function commentEnd() { + var char = this.consume(); + if (char === '>') { + this.delegate.finishComment(); + this.state = 'beforeData'; + } else { + this.delegate.appendToCommentData('--' + char); + this.state = 'comment'; + } + }, + tagName: function tagName() { + var char = this.consume(); + if ((0, _utils.isSpace)(char)) { + this.state = 'beforeAttributeName'; + } else if (char === '/') { + this.state = 'selfClosingStartTag'; + } else if (char === '>') { + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.delegate.appendToTagName(char); + } + }, + beforeAttributeName: function beforeAttributeName() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.consume(); + return; + } else if (char === '/') { + this.state = 'selfClosingStartTag'; + this.consume(); + } else if (char === '>') { + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.state = 'attributeName'; + this.delegate.beginAttribute(); + this.consume(); + this.delegate.appendToAttributeName(char); + } + }, + attributeName: function attributeName() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.state = 'afterAttributeName'; + this.consume(); + } else if (char === '/') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.state = 'selfClosingStartTag'; + } else if (char === '=') { + this.state = 'beforeAttributeValue'; + this.consume(); + } else if (char === '>') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.consume(); + this.delegate.appendToAttributeName(char); + } + }, + afterAttributeName: function afterAttributeName() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.consume(); + return; + } else if (char === '/') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.state = 'selfClosingStartTag'; + } else if (char === '=') { + this.consume(); + this.state = 'beforeAttributeValue'; + } else if (char === '>') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.state = 'attributeName'; + this.delegate.beginAttribute(); + this.delegate.appendToAttributeName(char); + } + }, + beforeAttributeValue: function beforeAttributeValue() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.consume(); + } else if (char === '"') { + this.state = 'attributeValueDoubleQuoted'; + this.delegate.beginAttributeValue(true); + this.consume(); + } else if (char === '\'') { + this.state = 'attributeValueSingleQuoted'; + this.delegate.beginAttributeValue(true); + this.consume(); + } else if (char === '>') { + this.delegate.beginAttributeValue(false); + this.delegate.finishAttributeValue(); + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.state = 'attributeValueUnquoted'; + this.delegate.beginAttributeValue(false); + this.consume(); + this.delegate.appendToAttributeValue(char); + } + }, + attributeValueDoubleQuoted: function attributeValueDoubleQuoted() { + var char = this.consume(); + if (char === '"') { + this.delegate.finishAttributeValue(); + this.state = 'afterAttributeValueQuoted'; + } else if (char === '&') { + this.delegate.appendToAttributeValue(this.consumeCharRef('"') || '&'); + } else { + this.delegate.appendToAttributeValue(char); + } + }, + attributeValueSingleQuoted: function attributeValueSingleQuoted() { + var char = this.consume(); + if (char === '\'') { + this.delegate.finishAttributeValue(); + this.state = 'afterAttributeValueQuoted'; + } else if (char === '&') { + this.delegate.appendToAttributeValue(this.consumeCharRef('\'') || '&'); + } else { + this.delegate.appendToAttributeValue(char); + } + }, + attributeValueUnquoted: function attributeValueUnquoted() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.delegate.finishAttributeValue(); + this.consume(); + this.state = 'beforeAttributeName'; + } else if (char === '&') { + this.consume(); + this.delegate.appendToAttributeValue(this.consumeCharRef('>') || '&'); + } else if (char === '>') { + this.delegate.finishAttributeValue(); + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.consume(); + this.delegate.appendToAttributeValue(char); + } + }, + afterAttributeValueQuoted: function afterAttributeValueQuoted() { + var char = this.peek(); + if ((0, _utils.isSpace)(char)) { + this.consume(); + this.state = 'beforeAttributeName'; + } else if (char === '/') { + this.consume(); + this.state = 'selfClosingStartTag'; + } else if (char === '>') { + this.consume(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.state = 'beforeAttributeName'; + } + }, + selfClosingStartTag: function selfClosingStartTag() { + var char = this.peek(); + if (char === '>') { + this.consume(); + this.delegate.markTagAsSelfClosing(); + this.delegate.finishTag(); + this.state = 'beforeData'; + } else { + this.state = 'beforeAttributeName'; + } + }, + endTagOpen: function endTagOpen() { + var char = this.consume(); + if ((0, _utils.isAlpha)(char)) { + this.state = 'tagName'; + this.delegate.beginEndTag(); + this.delegate.appendToTagName(char.toLowerCase()); + } + } + } + }; + exports.default = EventedTokenizer; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenizer*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenizer', [ + 'exports', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/evented-tokenizer' +], function (exports, _eventedTokenizer) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + var _eventedTokenizer2 = _interopRequireDefault(_eventedTokenizer); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + function Tokenizer(entityParser, options) { + this.token = null; + this.startLine = 1; + this.startColumn = 0; + this.options = options || {}; + this.tokenizer = new _eventedTokenizer2.default(this, entityParser); + } + Tokenizer.prototype = { + tokenize: function tokenize(input) { + this.tokens = []; + this.tokenizer.tokenize(input); + return this.tokens; + }, + tokenizePart: function tokenizePart(input) { + this.tokens = []; + this.tokenizer.tokenizePart(input); + return this.tokens; + }, + tokenizeEOF: function tokenizeEOF() { + this.tokens = []; + this.tokenizer.tokenizeEOF(); + return this.tokens[0]; + }, + reset: function reset() { + this.token = null; + this.startLine = 1; + this.startColumn = 0; + }, + addLocInfo: function addLocInfo() { + if (this.options.loc) { + this.token.loc = { + start: { + line: this.startLine, + column: this.startColumn + }, + end: { + line: this.tokenizer.line, + column: this.tokenizer.column + } + }; + } + this.startLine = this.tokenizer.line; + this.startColumn = this.tokenizer.column; + }, + beginData: function beginData() { + this.token = { + type: 'Chars', + chars: '' + }; + this.tokens.push(this.token); + }, + appendToData: function appendToData(char) { + this.token.chars += char; + }, + finishData: function finishData() { + this.addLocInfo(); + }, + beginComment: function beginComment() { + this.token = { + type: 'Comment', + chars: '' + }; + this.tokens.push(this.token); + }, + appendToCommentData: function appendToCommentData(char) { + this.token.chars += char; + }, + finishComment: function finishComment() { + this.addLocInfo(); + }, + beginStartTag: function beginStartTag() { + this.token = { + type: 'StartTag', + tagName: '', + attributes: [], + selfClosing: false + }; + this.tokens.push(this.token); + }, + beginEndTag: function beginEndTag() { + this.token = { + type: 'EndTag', + tagName: '' + }; + this.tokens.push(this.token); + }, + finishTag: function finishTag() { + this.addLocInfo(); + }, + markTagAsSelfClosing: function markTagAsSelfClosing() { + this.token.selfClosing = true; + }, + appendToTagName: function appendToTagName(char) { + this.token.tagName += char; + }, + beginAttribute: function beginAttribute() { + this._currentAttribute = [ + '', + '', + null + ]; + this.token.attributes.push(this._currentAttribute); + }, + appendToAttributeName: function appendToAttributeName(char) { + this._currentAttribute[0] += char; + }, + beginAttributeValue: function beginAttributeValue(isQuoted) { + this._currentAttribute[2] = isQuoted; + }, + appendToAttributeValue: function appendToAttributeValue(char) { + this._currentAttribute[1] = this._currentAttribute[1] || ''; + this._currentAttribute[1] += char; + }, + finishAttributeValue: function finishAttributeValue() { + } + }; + exports.default = Tokenizer; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/entity-parser*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/entity-parser', ['exports'], function (exports) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + function EntityParser(named) { + this.named = named; + } + var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/; + var CHARCODE = /^#([0-9]+)$/; + var NAMED = /^([A-Za-z0-9]+)$/; + EntityParser.prototype.parse = function (entity) { + if (!entity) { + return; + } + var matches = entity.match(HEXCHARCODE); + if (matches) { + return String.fromCharCode(parseInt(matches[1], 16)); + } + matches = entity.match(CHARCODE); + if (matches) { + return String.fromCharCode(parseInt(matches[1], 10)); + } + matches = entity.match(NAMED); + if (matches) { + return this.named[matches[1]]; + } + }; + exports.default = EntityParser; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/html5-named-char-refs*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/html5-named-char-refs', ['exports'], function (exports) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + var namedCharRefs = { + Aacute: 'Á', + aacute: 'á', + Abreve: 'Ă', + abreve: 'ă', + ac: '\u223E', + acd: '\u223F', + acE: '\u223E̳', + Acirc: 'Â', + acirc: 'â', + acute: '\xB4', + Acy: 'А', + acy: 'а', + AElig: 'Æ', + aelig: 'æ', + af: '\u2061', + Afr: '\uD835\uDD04', + afr: '\uD835\uDD1E', + Agrave: 'À', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + Alpha: 'Α', + alpha: 'α', + Amacr: 'Ā', + amacr: 'ā', + amalg: '\u2A3F', + AMP: '&', + amp: '&', + And: '\u2A53', + and: '\u2227', + andand: '\u2A55', + andd: '\u2A5C', + andslope: '\u2A58', + andv: '\u2A5A', + ang: '\u2220', + ange: '\u29A4', + angle: '\u2220', + angmsd: '\u2221', + angmsdaa: '\u29A8', + angmsdab: '\u29A9', + angmsdac: '\u29AA', + angmsdad: '\u29AB', + angmsdae: '\u29AC', + angmsdaf: '\u29AD', + angmsdag: '\u29AE', + angmsdah: '\u29AF', + angrt: '\u221F', + angrtvb: '\u22BE', + angrtvbd: '\u299D', + angsph: '\u2222', + angst: 'Å', + angzarr: '\u237C', + Aogon: 'Ą', + aogon: 'ą', + Aopf: '\uD835\uDD38', + aopf: '\uD835\uDD52', + ap: '\u2248', + apacir: '\u2A6F', + apE: '\u2A70', + ape: '\u224A', + apid: '\u224B', + apos: '\'', + ApplyFunction: '\u2061', + approx: '\u2248', + approxeq: '\u224A', + Aring: 'Å', + aring: 'å', + Ascr: '\uD835\uDC9C', + ascr: '\uD835\uDCB6', + Assign: '\u2254', + ast: '*', + asymp: '\u2248', + asympeq: '\u224D', + Atilde: 'Ã', + atilde: 'ã', + Auml: 'Ä', + auml: 'ä', + awconint: '\u2233', + awint: '\u2A11', + backcong: '\u224C', + backepsilon: '\u03F6', + backprime: '\u2035', + backsim: '\u223D', + backsimeq: '\u22CD', + Backslash: '\u2216', + Barv: '\u2AE7', + barvee: '\u22BD', + Barwed: '\u2306', + barwed: '\u2305', + barwedge: '\u2305', + bbrk: '\u23B5', + bbrktbrk: '\u23B6', + bcong: '\u224C', + Bcy: 'Б', + bcy: 'б', + bdquo: '\u201E', + becaus: '\u2235', + Because: '\u2235', + because: '\u2235', + bemptyv: '\u29B0', + bepsi: '\u03F6', + bernou: 'ℬ', + Bernoullis: 'ℬ', + Beta: 'Β', + beta: 'β', + beth: 'ℶ', + between: '\u226C', + Bfr: '\uD835\uDD05', + bfr: '\uD835\uDD1F', + bigcap: '\u22C2', + bigcirc: '\u25EF', + bigcup: '\u22C3', + bigodot: '\u2A00', + bigoplus: '\u2A01', + bigotimes: '\u2A02', + bigsqcup: '\u2A06', + bigstar: '\u2605', + bigtriangledown: '\u25BD', + bigtriangleup: '\u25B3', + biguplus: '\u2A04', + bigvee: '\u22C1', + bigwedge: '\u22C0', + bkarow: '\u290D', + blacklozenge: '\u29EB', + blacksquare: '\u25AA', + blacktriangle: '\u25B4', + blacktriangledown: '\u25BE', + blacktriangleleft: '\u25C2', + blacktriangleright: '\u25B8', + blank: '\u2423', + blk12: '\u2592', + blk14: '\u2591', + blk34: '\u2593', + block: '\u2588', + bne: '=⃥', + bnequiv: '\u2261⃥', + bNot: '\u2AED', + bnot: '\u2310', + Bopf: '\uD835\uDD39', + bopf: '\uD835\uDD53', + bot: '\u22A5', + bottom: '\u22A5', + bowtie: '\u22C8', + boxbox: '\u29C9', + boxDL: '\u2557', + boxDl: '\u2556', + boxdL: '\u2555', + boxdl: '\u2510', + boxDR: '\u2554', + boxDr: '\u2553', + boxdR: '\u2552', + boxdr: '\u250C', + boxH: '\u2550', + boxh: '\u2500', + boxHD: '\u2566', + boxHd: '\u2564', + boxhD: '\u2565', + boxhd: '\u252C', + boxHU: '\u2569', + boxHu: '\u2567', + boxhU: '\u2568', + boxhu: '\u2534', + boxminus: '\u229F', + boxplus: '\u229E', + boxtimes: '\u22A0', + boxUL: '\u255D', + boxUl: '\u255C', + boxuL: '\u255B', + boxul: '\u2518', + boxUR: '\u255A', + boxUr: '\u2559', + boxuR: '\u2558', + boxur: '\u2514', + boxV: '\u2551', + boxv: '\u2502', + boxVH: '\u256C', + boxVh: '\u256B', + boxvH: '\u256A', + boxvh: '\u253C', + boxVL: '\u2563', + boxVl: '\u2562', + boxvL: '\u2561', + boxvl: '\u2524', + boxVR: '\u2560', + boxVr: '\u255F', + boxvR: '\u255E', + boxvr: '\u251C', + bprime: '\u2035', + Breve: '\u02D8', + breve: '\u02D8', + brvbar: '\xA6', + Bscr: 'ℬ', + bscr: '\uD835\uDCB7', + bsemi: '\u204F', + bsim: '\u223D', + bsime: '\u22CD', + bsol: '\\', + bsolb: '\u29C5', + bsolhsub: '\u27C8', + bull: '\u2022', + bullet: '\u2022', + bump: '\u224E', + bumpE: '\u2AAE', + bumpe: '\u224F', + Bumpeq: '\u224E', + bumpeq: '\u224F', + Cacute: 'Ć', + cacute: 'ć', + Cap: '\u22D2', + cap: '\u2229', + capand: '\u2A44', + capbrcup: '\u2A49', + capcap: '\u2A4B', + capcup: '\u2A47', + capdot: '\u2A40', + CapitalDifferentialD: 'ⅅ', + caps: '\u2229︀', + caret: '\u2041', + caron: 'ˇ', + Cayleys: 'ℭ', + ccaps: '\u2A4D', + Ccaron: 'Č', + ccaron: 'č', + Ccedil: 'Ç', + ccedil: 'ç', + Ccirc: 'Ĉ', + ccirc: 'ĉ', + Cconint: '\u2230', + ccups: '\u2A4C', + ccupssm: '\u2A50', + Cdot: 'Ċ', + cdot: 'ċ', + cedil: '\xB8', + Cedilla: '\xB8', + cemptyv: '\u29B2', + cent: '\xA2', + CenterDot: '\xB7', + centerdot: '\xB7', + Cfr: 'ℭ', + cfr: '\uD835\uDD20', + CHcy: 'Ч', + chcy: 'ч', + check: '\u2713', + checkmark: '\u2713', + Chi: 'Χ', + chi: 'χ', + cir: '\u25CB', + circ: 'ˆ', + circeq: '\u2257', + circlearrowleft: '\u21BA', + circlearrowright: '\u21BB', + circledast: '\u229B', + circledcirc: '\u229A', + circleddash: '\u229D', + CircleDot: '\u2299', + circledR: '\xAE', + circledS: '\u24C8', + CircleMinus: '\u2296', + CirclePlus: '\u2295', + CircleTimes: '\u2297', + cirE: '\u29C3', + cire: '\u2257', + cirfnint: '\u2A10', + cirmid: '\u2AEF', + cirscir: '\u29C2', + ClockwiseContourIntegral: '\u2232', + CloseCurlyDoubleQuote: '\u201D', + CloseCurlyQuote: '\u2019', + clubs: '\u2663', + clubsuit: '\u2663', + Colon: '\u2237', + colon: ':', + Colone: '\u2A74', + colone: '\u2254', + coloneq: '\u2254', + comma: ',', + commat: '@', + comp: '\u2201', + compfn: '\u2218', + complement: '\u2201', + complexes: 'ℂ', + cong: '\u2245', + congdot: '\u2A6D', + Congruent: '\u2261', + Conint: '\u222F', + conint: '\u222E', + ContourIntegral: '\u222E', + Copf: 'ℂ', + copf: '\uD835\uDD54', + coprod: '\u2210', + Coproduct: '\u2210', + COPY: '\xA9', + copy: '\xA9', + copysr: '\u2117', + CounterClockwiseContourIntegral: '\u2233', + crarr: '\u21B5', + Cross: '\u2A2F', + cross: '\u2717', + Cscr: '\uD835\uDC9E', + cscr: '\uD835\uDCB8', + csub: '\u2ACF', + csube: '\u2AD1', + csup: '\u2AD0', + csupe: '\u2AD2', + ctdot: '\u22EF', + cudarrl: '\u2938', + cudarrr: '\u2935', + cuepr: '\u22DE', + cuesc: '\u22DF', + cularr: '\u21B6', + cularrp: '\u293D', + Cup: '\u22D3', + cup: '\u222A', + cupbrcap: '\u2A48', + CupCap: '\u224D', + cupcap: '\u2A46', + cupcup: '\u2A4A', + cupdot: '\u228D', + cupor: '\u2A45', + cups: '\u222A︀', + curarr: '\u21B7', + curarrm: '\u293C', + curlyeqprec: '\u22DE', + curlyeqsucc: '\u22DF', + curlyvee: '\u22CE', + curlywedge: '\u22CF', + curren: '\xA4', + curvearrowleft: '\u21B6', + curvearrowright: '\u21B7', + cuvee: '\u22CE', + cuwed: '\u22CF', + cwconint: '\u2232', + cwint: '\u2231', + cylcty: '\u232D', + Dagger: '\u2021', + dagger: '\u2020', + daleth: 'ℸ', + Darr: '\u21A1', + dArr: '\u21D3', + darr: '\u2193', + dash: '\u2010', + Dashv: '\u2AE4', + dashv: '\u22A3', + dbkarow: '\u290F', + dblac: '\u02DD', + Dcaron: 'Ď', + dcaron: 'ď', + Dcy: 'Д', + dcy: 'д', + DD: 'ⅅ', + dd: 'ⅆ', + ddagger: '\u2021', + ddarr: '\u21CA', + DDotrahd: '\u2911', + ddotseq: '\u2A77', + deg: '\xB0', + Del: '\u2207', + Delta: 'Δ', + delta: 'δ', + demptyv: '\u29B1', + dfisht: '\u297F', + Dfr: '\uD835\uDD07', + dfr: '\uD835\uDD21', + dHar: '\u2965', + dharl: '\u21C3', + dharr: '\u21C2', + DiacriticalAcute: '\xB4', + DiacriticalDot: '\u02D9', + DiacriticalDoubleAcute: '\u02DD', + DiacriticalGrave: '`', + DiacriticalTilde: '\u02DC', + diam: '\u22C4', + Diamond: '\u22C4', + diamond: '\u22C4', + diamondsuit: '\u2666', + diams: '\u2666', + die: '\xA8', + DifferentialD: 'ⅆ', + digamma: 'ϝ', + disin: '\u22F2', + div: '\xF7', + divide: '\xF7', + divideontimes: '\u22C7', + divonx: '\u22C7', + DJcy: 'Ђ', + djcy: 'ђ', + dlcorn: '\u231E', + dlcrop: '\u230D', + dollar: '$', + Dopf: '\uD835\uDD3B', + dopf: '\uD835\uDD55', + Dot: '\xA8', + dot: '\u02D9', + DotDot: '⃜', + doteq: '\u2250', + doteqdot: '\u2251', + DotEqual: '\u2250', + dotminus: '\u2238', + dotplus: '\u2214', + dotsquare: '\u22A1', + doublebarwedge: '\u2306', + DoubleContourIntegral: '\u222F', + DoubleDot: '\xA8', + DoubleDownArrow: '\u21D3', + DoubleLeftArrow: '\u21D0', + DoubleLeftRightArrow: '\u21D4', + DoubleLeftTee: '\u2AE4', + DoubleLongLeftArrow: '\u27F8', + DoubleLongLeftRightArrow: '\u27FA', + DoubleLongRightArrow: '\u27F9', + DoubleRightArrow: '\u21D2', + DoubleRightTee: '\u22A8', + DoubleUpArrow: '\u21D1', + DoubleUpDownArrow: '\u21D5', + DoubleVerticalBar: '\u2225', + DownArrow: '\u2193', + Downarrow: '\u21D3', + downarrow: '\u2193', + DownArrowBar: '\u2913', + DownArrowUpArrow: '\u21F5', + DownBreve: '̑', + downdownarrows: '\u21CA', + downharpoonleft: '\u21C3', + downharpoonright: '\u21C2', + DownLeftRightVector: '\u2950', + DownLeftTeeVector: '\u295E', + DownLeftVector: '\u21BD', + DownLeftVectorBar: '\u2956', + DownRightTeeVector: '\u295F', + DownRightVector: '\u21C1', + DownRightVectorBar: '\u2957', + DownTee: '\u22A4', + DownTeeArrow: '\u21A7', + drbkarow: '\u2910', + drcorn: '\u231F', + drcrop: '\u230C', + Dscr: '\uD835\uDC9F', + dscr: '\uD835\uDCB9', + DScy: 'Ѕ', + dscy: 'ѕ', + dsol: '\u29F6', + Dstrok: 'Đ', + dstrok: 'đ', + dtdot: '\u22F1', + dtri: '\u25BF', + dtrif: '\u25BE', + duarr: '\u21F5', + duhar: '\u296F', + dwangle: '\u29A6', + DZcy: 'Џ', + dzcy: 'џ', + dzigrarr: '\u27FF', + Eacute: 'É', + eacute: 'é', + easter: '\u2A6E', + Ecaron: 'Ě', + ecaron: 'ě', + ecir: '\u2256', + Ecirc: 'Ê', + ecirc: 'ê', + ecolon: '\u2255', + Ecy: 'Э', + ecy: 'э', + eDDot: '\u2A77', + Edot: 'Ė', + eDot: '\u2251', + edot: 'ė', + ee: 'ⅇ', + efDot: '\u2252', + Efr: '\uD835\uDD08', + efr: '\uD835\uDD22', + eg: '\u2A9A', + Egrave: 'È', + egrave: 'è', + egs: '\u2A96', + egsdot: '\u2A98', + el: '\u2A99', + Element: '\u2208', + elinters: '\u23E7', + ell: 'ℓ', + els: '\u2A95', + elsdot: '\u2A97', + Emacr: 'Ē', + emacr: 'ē', + empty: '\u2205', + emptyset: '\u2205', + EmptySmallSquare: '\u25FB', + emptyv: '\u2205', + EmptyVerySmallSquare: '\u25AB', + emsp: '\u2003', + emsp13: '\u2004', + emsp14: '\u2005', + ENG: 'Ŋ', + eng: 'ŋ', + ensp: '\u2002', + Eogon: 'Ę', + eogon: 'ę', + Eopf: '\uD835\uDD3C', + eopf: '\uD835\uDD56', + epar: '\u22D5', + eparsl: '\u29E3', + eplus: '\u2A71', + epsi: 'ε', + Epsilon: 'Ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '\u2256', + eqcolon: '\u2255', + eqsim: '\u2242', + eqslantgtr: '\u2A96', + eqslantless: '\u2A95', + Equal: '\u2A75', + equals: '=', + EqualTilde: '\u2242', + equest: '\u225F', + Equilibrium: '\u21CC', + equiv: '\u2261', + equivDD: '\u2A78', + eqvparsl: '\u29E5', + erarr: '\u2971', + erDot: '\u2253', + Escr: 'ℰ', + escr: 'ℯ', + esdot: '\u2250', + Esim: '\u2A73', + esim: '\u2242', + Eta: 'Η', + eta: 'η', + ETH: 'Ð', + eth: 'ð', + Euml: 'Ë', + euml: 'ë', + euro: '\u20AC', + excl: '!', + exist: '\u2203', + Exists: '\u2203', + expectation: 'ℰ', + ExponentialE: 'ⅇ', + exponentiale: 'ⅇ', + fallingdotseq: '\u2252', + Fcy: 'Ф', + fcy: 'ф', + female: '\u2640', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + Ffr: '\uD835\uDD09', + ffr: '\uD835\uDD23', + filig: 'fi', + FilledSmallSquare: '\u25FC', + FilledVerySmallSquare: '\u25AA', + fjlig: 'fj', + flat: '\u266D', + fllig: 'fl', + fltns: '\u25B1', + fnof: 'ƒ', + Fopf: '\uD835\uDD3D', + fopf: '\uD835\uDD57', + ForAll: '\u2200', + forall: '\u2200', + fork: '\u22D4', + forkv: '\u2AD9', + Fouriertrf: 'ℱ', + fpartint: '\u2A0D', + frac12: '\xBD', + frac13: '\u2153', + frac14: '\xBC', + frac15: '\u2155', + frac16: '\u2159', + frac18: '\u215B', + frac23: '\u2154', + frac25: '\u2156', + frac34: '\xBE', + frac35: '\u2157', + frac38: '\u215C', + frac45: '\u2158', + frac56: '\u215A', + frac58: '\u215D', + frac78: '\u215E', + frasl: '\u2044', + frown: '\u2322', + Fscr: 'ℱ', + fscr: '\uD835\uDCBB', + gacute: 'ǵ', + Gamma: 'Γ', + gamma: 'γ', + Gammad: 'Ϝ', + gammad: 'ϝ', + gap: '\u2A86', + Gbreve: 'Ğ', + gbreve: 'ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + gcirc: 'ĝ', + Gcy: 'Г', + gcy: 'г', + Gdot: 'Ġ', + gdot: 'ġ', + gE: '\u2267', + ge: '\u2265', + gEl: '\u2A8C', + gel: '\u22DB', + geq: '\u2265', + geqq: '\u2267', + geqslant: '\u2A7E', + ges: '\u2A7E', + gescc: '\u2AA9', + gesdot: '\u2A80', + gesdoto: '\u2A82', + gesdotol: '\u2A84', + gesl: '\u22DB︀', + gesles: '\u2A94', + Gfr: '\uD835\uDD0A', + gfr: '\uD835\uDD24', + Gg: '\u22D9', + gg: '\u226B', + ggg: '\u22D9', + gimel: 'ℷ', + GJcy: 'Ѓ', + gjcy: 'ѓ', + gl: '\u2277', + gla: '\u2AA5', + glE: '\u2A92', + glj: '\u2AA4', + gnap: '\u2A8A', + gnapprox: '\u2A8A', + gnE: '\u2269', + gne: '\u2A88', + gneq: '\u2A88', + gneqq: '\u2269', + gnsim: '\u22E7', + Gopf: '\uD835\uDD3E', + gopf: '\uD835\uDD58', + grave: '`', + GreaterEqual: '\u2265', + GreaterEqualLess: '\u22DB', + GreaterFullEqual: '\u2267', + GreaterGreater: '\u2AA2', + GreaterLess: '\u2277', + GreaterSlantEqual: '\u2A7E', + GreaterTilde: '\u2273', + Gscr: '\uD835\uDCA2', + gscr: 'ℊ', + gsim: '\u2273', + gsime: '\u2A8E', + gsiml: '\u2A90', + GT: '>', + Gt: '\u226B', + gt: '>', + gtcc: '\u2AA7', + gtcir: '\u2A7A', + gtdot: '\u22D7', + gtlPar: '\u2995', + gtquest: '\u2A7C', + gtrapprox: '\u2A86', + gtrarr: '\u2978', + gtrdot: '\u22D7', + gtreqless: '\u22DB', + gtreqqless: '\u2A8C', + gtrless: '\u2277', + gtrsim: '\u2273', + gvertneqq: '\u2269︀', + gvnE: '\u2269︀', + Hacek: 'ˇ', + hairsp: '\u200A', + half: '\xBD', + hamilt: 'ℋ', + HARDcy: 'Ъ', + hardcy: 'ъ', + hArr: '\u21D4', + harr: '\u2194', + harrcir: '\u2948', + harrw: '\u21AD', + Hat: '^', + hbar: 'ℏ', + Hcirc: 'Ĥ', + hcirc: 'ĥ', + hearts: '\u2665', + heartsuit: '\u2665', + hellip: '\u2026', + hercon: '\u22B9', + Hfr: 'ℌ', + hfr: '\uD835\uDD25', + HilbertSpace: 'ℋ', + hksearow: '\u2925', + hkswarow: '\u2926', + hoarr: '\u21FF', + homtht: '\u223B', + hookleftarrow: '\u21A9', + hookrightarrow: '\u21AA', + Hopf: 'ℍ', + hopf: '\uD835\uDD59', + horbar: '\u2015', + HorizontalLine: '\u2500', + Hscr: 'ℋ', + hscr: '\uD835\uDCBD', + hslash: 'ℏ', + Hstrok: 'Ħ', + hstrok: 'ħ', + HumpDownHump: '\u224E', + HumpEqual: '\u224F', + hybull: '\u2043', + hyphen: '\u2010', + Iacute: 'Í', + iacute: 'í', + ic: '\u2063', + Icirc: 'Î', + icirc: 'î', + Icy: 'И', + icy: 'и', + Idot: 'İ', + IEcy: 'Е', + iecy: 'е', + iexcl: '\xA1', + iff: '\u21D4', + Ifr: 'ℑ', + ifr: '\uD835\uDD26', + Igrave: 'Ì', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '\u2A0C', + iiint: '\u222D', + iinfin: '\u29DC', + iiota: '\u2129', + IJlig: 'IJ', + ijlig: 'ij', + Im: 'ℑ', + Imacr: 'Ī', + imacr: 'ī', + image: 'ℑ', + ImaginaryI: 'ⅈ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '\u22B7', + imped: 'Ƶ', + Implies: '\u21D2', + in: '\u2208', + incare: '\u2105', + infin: '\u221E', + infintie: '\u29DD', + inodot: 'ı', + Int: '\u222C', + int: '\u222B', + intcal: '\u22BA', + integers: 'ℤ', + Integral: '\u222B', + intercal: '\u22BA', + Intersection: '\u22C2', + intlarhk: '\u2A17', + intprod: '\u2A3C', + InvisibleComma: '\u2063', + InvisibleTimes: '\u2062', + IOcy: 'Ё', + iocy: 'ё', + Iogon: 'Į', + iogon: 'į', + Iopf: '\uD835\uDD40', + iopf: '\uD835\uDD5A', + Iota: 'Ι', + iota: 'ι', + iprod: '\u2A3C', + iquest: '\xBF', + Iscr: 'ℐ', + iscr: '\uD835\uDCBE', + isin: '\u2208', + isindot: '\u22F5', + isinE: '\u22F9', + isins: '\u22F4', + isinsv: '\u22F3', + isinv: '\u2208', + it: '\u2062', + Itilde: 'Ĩ', + itilde: 'ĩ', + Iukcy: 'І', + iukcy: 'і', + Iuml: 'Ï', + iuml: 'ï', + Jcirc: 'Ĵ', + jcirc: 'ĵ', + Jcy: 'Й', + jcy: 'й', + Jfr: '\uD835\uDD0D', + jfr: '\uD835\uDD27', + jmath: 'ȷ', + Jopf: '\uD835\uDD41', + jopf: '\uD835\uDD5B', + Jscr: '\uD835\uDCA5', + jscr: '\uD835\uDCBF', + Jsercy: 'Ј', + jsercy: 'ј', + Jukcy: 'Є', + jukcy: 'є', + Kappa: 'Κ', + kappa: 'κ', + kappav: 'ϰ', + Kcedil: 'Ķ', + kcedil: 'ķ', + Kcy: 'К', + kcy: 'к', + Kfr: '\uD835\uDD0E', + kfr: '\uD835\uDD28', + kgreen: 'ĸ', + KHcy: 'Х', + khcy: 'х', + KJcy: 'Ќ', + kjcy: 'ќ', + Kopf: '\uD835\uDD42', + kopf: '\uD835\uDD5C', + Kscr: '\uD835\uDCA6', + kscr: '\uD835\uDCC0', + lAarr: '\u21DA', + Lacute: 'Ĺ', + lacute: 'ĺ', + laemptyv: '\u29B4', + lagran: 'ℒ', + Lambda: 'Λ', + lambda: 'λ', + Lang: '\u27EA', + lang: '\u27E8', + langd: '\u2991', + langle: '\u27E8', + lap: '\u2A85', + Laplacetrf: 'ℒ', + laquo: '\xAB', + Larr: '\u219E', + lArr: '\u21D0', + larr: '\u2190', + larrb: '\u21E4', + larrbfs: '\u291F', + larrfs: '\u291D', + larrhk: '\u21A9', + larrlp: '\u21AB', + larrpl: '\u2939', + larrsim: '\u2973', + larrtl: '\u21A2', + lat: '\u2AAB', + lAtail: '\u291B', + latail: '\u2919', + late: '\u2AAD', + lates: '\u2AAD︀', + lBarr: '\u290E', + lbarr: '\u290C', + lbbrk: '\u2772', + lbrace: '{', + lbrack: '[', + lbrke: '\u298B', + lbrksld: '\u298F', + lbrkslu: '\u298D', + Lcaron: 'Ľ', + lcaron: 'ľ', + Lcedil: 'Ļ', + lcedil: 'ļ', + lceil: '\u2308', + lcub: '{', + Lcy: 'Л', + lcy: 'л', + ldca: '\u2936', + ldquo: '\u201C', + ldquor: '\u201E', + ldrdhar: '\u2967', + ldrushar: '\u294B', + ldsh: '\u21B2', + lE: '\u2266', + le: '\u2264', + LeftAngleBracket: '\u27E8', + LeftArrow: '\u2190', + Leftarrow: '\u21D0', + leftarrow: '\u2190', + LeftArrowBar: '\u21E4', + LeftArrowRightArrow: '\u21C6', + leftarrowtail: '\u21A2', + LeftCeiling: '\u2308', + LeftDoubleBracket: '\u27E6', + LeftDownTeeVector: '\u2961', + LeftDownVector: '\u21C3', + LeftDownVectorBar: '\u2959', + LeftFloor: '\u230A', + leftharpoondown: '\u21BD', + leftharpoonup: '\u21BC', + leftleftarrows: '\u21C7', + LeftRightArrow: '\u2194', + Leftrightarrow: '\u21D4', + leftrightarrow: '\u2194', + leftrightarrows: '\u21C6', + leftrightharpoons: '\u21CB', + leftrightsquigarrow: '\u21AD', + LeftRightVector: '\u294E', + LeftTee: '\u22A3', + LeftTeeArrow: '\u21A4', + LeftTeeVector: '\u295A', + leftthreetimes: '\u22CB', + LeftTriangle: '\u22B2', + LeftTriangleBar: '\u29CF', + LeftTriangleEqual: '\u22B4', + LeftUpDownVector: '\u2951', + LeftUpTeeVector: '\u2960', + LeftUpVector: '\u21BF', + LeftUpVectorBar: '\u2958', + LeftVector: '\u21BC', + LeftVectorBar: '\u2952', + lEg: '\u2A8B', + leg: '\u22DA', + leq: '\u2264', + leqq: '\u2266', + leqslant: '\u2A7D', + les: '\u2A7D', + lescc: '\u2AA8', + lesdot: '\u2A7F', + lesdoto: '\u2A81', + lesdotor: '\u2A83', + lesg: '\u22DA︀', + lesges: '\u2A93', + lessapprox: '\u2A85', + lessdot: '\u22D6', + lesseqgtr: '\u22DA', + lesseqqgtr: '\u2A8B', + LessEqualGreater: '\u22DA', + LessFullEqual: '\u2266', + LessGreater: '\u2276', + lessgtr: '\u2276', + LessLess: '\u2AA1', + lesssim: '\u2272', + LessSlantEqual: '\u2A7D', + LessTilde: '\u2272', + lfisht: '\u297C', + lfloor: '\u230A', + Lfr: '\uD835\uDD0F', + lfr: '\uD835\uDD29', + lg: '\u2276', + lgE: '\u2A91', + lHar: '\u2962', + lhard: '\u21BD', + lharu: '\u21BC', + lharul: '\u296A', + lhblk: '\u2584', + LJcy: 'Љ', + ljcy: 'љ', + Ll: '\u22D8', + ll: '\u226A', + llarr: '\u21C7', + llcorner: '\u231E', + Lleftarrow: '\u21DA', + llhard: '\u296B', + lltri: '\u25FA', + Lmidot: 'Ŀ', + lmidot: 'ŀ', + lmoust: '\u23B0', + lmoustache: '\u23B0', + lnap: '\u2A89', + lnapprox: '\u2A89', + lnE: '\u2268', + lne: '\u2A87', + lneq: '\u2A87', + lneqq: '\u2268', + lnsim: '\u22E6', + loang: '\u27EC', + loarr: '\u21FD', + lobrk: '\u27E6', + LongLeftArrow: '\u27F5', + Longleftarrow: '\u27F8', + longleftarrow: '\u27F5', + LongLeftRightArrow: '\u27F7', + Longleftrightarrow: '\u27FA', + longleftrightarrow: '\u27F7', + longmapsto: '\u27FC', + LongRightArrow: '\u27F6', + Longrightarrow: '\u27F9', + longrightarrow: '\u27F6', + looparrowleft: '\u21AB', + looparrowright: '\u21AC', + lopar: '\u2985', + Lopf: '\uD835\uDD43', + lopf: '\uD835\uDD5D', + loplus: '\u2A2D', + lotimes: '\u2A34', + lowast: '\u2217', + lowbar: '_', + LowerLeftArrow: '\u2199', + LowerRightArrow: '\u2198', + loz: '\u25CA', + lozenge: '\u25CA', + lozf: '\u29EB', + lpar: '(', + lparlt: '\u2993', + lrarr: '\u21C6', + lrcorner: '\u231F', + lrhar: '\u21CB', + lrhard: '\u296D', + lrm: '\u200E', + lrtri: '\u22BF', + lsaquo: '\u2039', + Lscr: 'ℒ', + lscr: '\uD835\uDCC1', + Lsh: '\u21B0', + lsh: '\u21B0', + lsim: '\u2272', + lsime: '\u2A8D', + lsimg: '\u2A8F', + lsqb: '[', + lsquo: '\u2018', + lsquor: '\u201A', + Lstrok: 'Ł', + lstrok: 'ł', + LT: '<', + Lt: '\u226A', + lt: '<', + ltcc: '\u2AA6', + ltcir: '\u2A79', + ltdot: '\u22D6', + lthree: '\u22CB', + ltimes: '\u22C9', + ltlarr: '\u2976', + ltquest: '\u2A7B', + ltri: '\u25C3', + ltrie: '\u22B4', + ltrif: '\u25C2', + ltrPar: '\u2996', + lurdshar: '\u294A', + luruhar: '\u2966', + lvertneqq: '\u2268︀', + lvnE: '\u2268︀', + macr: '\xAF', + male: '\u2642', + malt: '\u2720', + maltese: '\u2720', + Map: '\u2905', + map: '\u21A6', + mapsto: '\u21A6', + mapstodown: '\u21A7', + mapstoleft: '\u21A4', + mapstoup: '\u21A5', + marker: '\u25AE', + mcomma: '\u2A29', + Mcy: 'М', + mcy: 'м', + mdash: '\u2014', + mDDot: '\u223A', + measuredangle: '\u2221', + MediumSpace: '\u205F', + Mellintrf: 'ℳ', + Mfr: '\uD835\uDD10', + mfr: '\uD835\uDD2A', + mho: '\u2127', + micro: 'µ', + mid: '\u2223', + midast: '*', + midcir: '\u2AF0', + middot: '\xB7', + minus: '\u2212', + minusb: '\u229F', + minusd: '\u2238', + minusdu: '\u2A2A', + MinusPlus: '\u2213', + mlcp: '\u2ADB', + mldr: '\u2026', + mnplus: '\u2213', + models: '\u22A7', + Mopf: '\uD835\uDD44', + mopf: '\uD835\uDD5E', + mp: '\u2213', + Mscr: 'ℳ', + mscr: '\uD835\uDCC2', + mstpos: '\u223E', + Mu: 'Μ', + mu: 'μ', + multimap: '\u22B8', + mumap: '\u22B8', + nabla: '\u2207', + Nacute: 'Ń', + nacute: 'ń', + nang: '\u2220⃒', + nap: '\u2249', + napE: '\u2A70̸', + napid: '\u224B̸', + napos: 'ʼn', + napprox: '\u2249', + natur: '\u266E', + natural: '\u266E', + naturals: 'ℕ', + nbsp: '\xA0', + nbump: '\u224E̸', + nbumpe: '\u224F̸', + ncap: '\u2A43', + Ncaron: 'Ň', + ncaron: 'ň', + Ncedil: 'Ņ', + ncedil: 'ņ', + ncong: '\u2247', + ncongdot: '\u2A6D̸', + ncup: '\u2A42', + Ncy: 'Н', + ncy: 'н', + ndash: '\u2013', + ne: '\u2260', + nearhk: '\u2924', + neArr: '\u21D7', + nearr: '\u2197', + nearrow: '\u2197', + nedot: '\u2250̸', + NegativeMediumSpace: '\u200B', + NegativeThickSpace: '\u200B', + NegativeThinSpace: '\u200B', + NegativeVeryThinSpace: '\u200B', + nequiv: '\u2262', + nesear: '\u2928', + nesim: '\u2242̸', + NestedGreaterGreater: '\u226B', + NestedLessLess: '\u226A', + NewLine: '\n', + nexist: '\u2204', + nexists: '\u2204', + Nfr: '\uD835\uDD11', + nfr: '\uD835\uDD2B', + ngE: '\u2267̸', + nge: '\u2271', + ngeq: '\u2271', + ngeqq: '\u2267̸', + ngeqslant: '\u2A7E̸', + nges: '\u2A7E̸', + nGg: '\u22D9̸', + ngsim: '\u2275', + nGt: '\u226B⃒', + ngt: '\u226F', + ngtr: '\u226F', + nGtv: '\u226B̸', + nhArr: '\u21CE', + nharr: '\u21AE', + nhpar: '\u2AF2', + ni: '\u220B', + nis: '\u22FC', + nisd: '\u22FA', + niv: '\u220B', + NJcy: 'Њ', + njcy: 'њ', + nlArr: '\u21CD', + nlarr: '\u219A', + nldr: '\u2025', + nlE: '\u2266̸', + nle: '\u2270', + nLeftarrow: '\u21CD', + nleftarrow: '\u219A', + nLeftrightarrow: '\u21CE', + nleftrightarrow: '\u21AE', + nleq: '\u2270', + nleqq: '\u2266̸', + nleqslant: '\u2A7D̸', + nles: '\u2A7D̸', + nless: '\u226E', + nLl: '\u22D8̸', + nlsim: '\u2274', + nLt: '\u226A⃒', + nlt: '\u226E', + nltri: '\u22EA', + nltrie: '\u22EC', + nLtv: '\u226A̸', + nmid: '\u2224', + NoBreak: '\u2060', + NonBreakingSpace: '\xA0', + Nopf: 'ℕ', + nopf: '\uD835\uDD5F', + Not: '\u2AEC', + not: '\xAC', + NotCongruent: '\u2262', + NotCupCap: '\u226D', + NotDoubleVerticalBar: '\u2226', + NotElement: '\u2209', + NotEqual: '\u2260', + NotEqualTilde: '\u2242̸', + NotExists: '\u2204', + NotGreater: '\u226F', + NotGreaterEqual: '\u2271', + NotGreaterFullEqual: '\u2267̸', + NotGreaterGreater: '\u226B̸', + NotGreaterLess: '\u2279', + NotGreaterSlantEqual: '\u2A7E̸', + NotGreaterTilde: '\u2275', + NotHumpDownHump: '\u224E̸', + NotHumpEqual: '\u224F̸', + notin: '\u2209', + notindot: '\u22F5̸', + notinE: '\u22F9̸', + notinva: '\u2209', + notinvb: '\u22F7', + notinvc: '\u22F6', + NotLeftTriangle: '\u22EA', + NotLeftTriangleBar: '\u29CF̸', + NotLeftTriangleEqual: '\u22EC', + NotLess: '\u226E', + NotLessEqual: '\u2270', + NotLessGreater: '\u2278', + NotLessLess: '\u226A̸', + NotLessSlantEqual: '\u2A7D̸', + NotLessTilde: '\u2274', + NotNestedGreaterGreater: '\u2AA2̸', + NotNestedLessLess: '\u2AA1̸', + notni: '\u220C', + notniva: '\u220C', + notnivb: '\u22FE', + notnivc: '\u22FD', + NotPrecedes: '\u2280', + NotPrecedesEqual: '\u2AAF̸', + NotPrecedesSlantEqual: '\u22E0', + NotReverseElement: '\u220C', + NotRightTriangle: '\u22EB', + NotRightTriangleBar: '\u29D0̸', + NotRightTriangleEqual: '\u22ED', + NotSquareSubset: '\u228F̸', + NotSquareSubsetEqual: '\u22E2', + NotSquareSuperset: '\u2290̸', + NotSquareSupersetEqual: '\u22E3', + NotSubset: '\u2282⃒', + NotSubsetEqual: '\u2288', + NotSucceeds: '\u2281', + NotSucceedsEqual: '\u2AB0̸', + NotSucceedsSlantEqual: '\u22E1', + NotSucceedsTilde: '\u227F̸', + NotSuperset: '\u2283⃒', + NotSupersetEqual: '\u2289', + NotTilde: '\u2241', + NotTildeEqual: '\u2244', + NotTildeFullEqual: '\u2247', + NotTildeTilde: '\u2249', + NotVerticalBar: '\u2224', + npar: '\u2226', + nparallel: '\u2226', + nparsl: '\u2AFD⃥', + npart: '\u2202̸', + npolint: '\u2A14', + npr: '\u2280', + nprcue: '\u22E0', + npre: '\u2AAF̸', + nprec: '\u2280', + npreceq: '\u2AAF̸', + nrArr: '\u21CF', + nrarr: '\u219B', + nrarrc: '\u2933̸', + nrarrw: '\u219D̸', + nRightarrow: '\u21CF', + nrightarrow: '\u219B', + nrtri: '\u22EB', + nrtrie: '\u22ED', + nsc: '\u2281', + nsccue: '\u22E1', + nsce: '\u2AB0̸', + Nscr: '\uD835\uDCA9', + nscr: '\uD835\uDCC3', + nshortmid: '\u2224', + nshortparallel: '\u2226', + nsim: '\u2241', + nsime: '\u2244', + nsimeq: '\u2244', + nsmid: '\u2224', + nspar: '\u2226', + nsqsube: '\u22E2', + nsqsupe: '\u22E3', + nsub: '\u2284', + nsubE: '\u2AC5̸', + nsube: '\u2288', + nsubset: '\u2282⃒', + nsubseteq: '\u2288', + nsubseteqq: '\u2AC5̸', + nsucc: '\u2281', + nsucceq: '\u2AB0̸', + nsup: '\u2285', + nsupE: '\u2AC6̸', + nsupe: '\u2289', + nsupset: '\u2283⃒', + nsupseteq: '\u2289', + nsupseteqq: '\u2AC6̸', + ntgl: '\u2279', + Ntilde: 'Ñ', + ntilde: 'ñ', + ntlg: '\u2278', + ntriangleleft: '\u22EA', + ntrianglelefteq: '\u22EC', + ntriangleright: '\u22EB', + ntrianglerighteq: '\u22ED', + Nu: 'Ν', + nu: 'ν', + num: '#', + numero: '\u2116', + numsp: '\u2007', + nvap: '\u224D⃒', + nVDash: '\u22AF', + nVdash: '\u22AE', + nvDash: '\u22AD', + nvdash: '\u22AC', + nvge: '\u2265⃒', + nvgt: '>⃒', + nvHarr: '\u2904', + nvinfin: '\u29DE', + nvlArr: '\u2902', + nvle: '\u2264⃒', + nvlt: '<⃒', + nvltrie: '\u22B4⃒', + nvrArr: '\u2903', + nvrtrie: '\u22B5⃒', + nvsim: '\u223C⃒', + nwarhk: '\u2923', + nwArr: '\u21D6', + nwarr: '\u2196', + nwarrow: '\u2196', + nwnear: '\u2927', + Oacute: 'Ó', + oacute: 'ó', + oast: '\u229B', + ocir: '\u229A', + Ocirc: 'Ô', + ocirc: 'ô', + Ocy: 'О', + ocy: 'о', + odash: '\u229D', + Odblac: 'Ő', + odblac: 'ő', + odiv: '\u2A38', + odot: '\u2299', + odsold: '\u29BC', + OElig: 'Œ', + oelig: 'œ', + ofcir: '\u29BF', + Ofr: '\uD835\uDD12', + ofr: '\uD835\uDD2C', + ogon: '\u02DB', + Ograve: 'Ò', + ograve: 'ò', + ogt: '\u29C1', + ohbar: '\u29B5', + ohm: 'Ω', + oint: '\u222E', + olarr: '\u21BA', + olcir: '\u29BE', + olcross: '\u29BB', + oline: '\u203E', + olt: '\u29C0', + Omacr: 'Ō', + omacr: 'ō', + Omega: 'Ω', + omega: 'ω', + Omicron: 'Ο', + omicron: 'ο', + omid: '\u29B6', + ominus: '\u2296', + Oopf: '\uD835\uDD46', + oopf: '\uD835\uDD60', + opar: '\u29B7', + OpenCurlyDoubleQuote: '\u201C', + OpenCurlyQuote: '\u2018', + operp: '\u29B9', + oplus: '\u2295', + Or: '\u2A54', + or: '\u2228', + orarr: '\u21BB', + ord: '\u2A5D', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '\u22B6', + oror: '\u2A56', + orslope: '\u2A57', + orv: '\u2A5B', + oS: '\u24C8', + Oscr: '\uD835\uDCAA', + oscr: 'ℴ', + Oslash: 'Ø', + oslash: 'ø', + osol: '\u2298', + Otilde: 'Õ', + otilde: 'õ', + Otimes: '\u2A37', + otimes: '\u2297', + otimesas: '\u2A36', + Ouml: 'Ö', + ouml: 'ö', + ovbar: '\u233D', + OverBar: '\u203E', + OverBrace: '\u23DE', + OverBracket: '\u23B4', + OverParenthesis: '\u23DC', + par: '\u2225', + para: '\xB6', + parallel: '\u2225', + parsim: '\u2AF3', + parsl: '\u2AFD', + part: '\u2202', + PartialD: '\u2202', + Pcy: 'П', + pcy: 'п', + percnt: '%', + period: '.', + permil: '\u2030', + perp: '\u22A5', + pertenk: '\u2031', + Pfr: '\uD835\uDD13', + pfr: '\uD835\uDD2D', + Phi: 'Φ', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '\u260E', + Pi: 'Π', + pi: 'π', + pitchfork: '\u22D4', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '\u2A23', + plusb: '\u229E', + pluscir: '\u2A22', + plusdo: '\u2214', + plusdu: '\u2A25', + pluse: '\u2A72', + PlusMinus: '\xB1', + plusmn: '\xB1', + plussim: '\u2A26', + plustwo: '\u2A27', + pm: '\xB1', + Poincareplane: 'ℌ', + pointint: '\u2A15', + Popf: 'ℙ', + popf: '\uD835\uDD61', + pound: '\xA3', + Pr: '\u2ABB', + pr: '\u227A', + prap: '\u2AB7', + prcue: '\u227C', + prE: '\u2AB3', + pre: '\u2AAF', + prec: '\u227A', + precapprox: '\u2AB7', + preccurlyeq: '\u227C', + Precedes: '\u227A', + PrecedesEqual: '\u2AAF', + PrecedesSlantEqual: '\u227C', + PrecedesTilde: '\u227E', + preceq: '\u2AAF', + precnapprox: '\u2AB9', + precneqq: '\u2AB5', + precnsim: '\u22E8', + precsim: '\u227E', + Prime: '\u2033', + prime: '\u2032', + primes: 'ℙ', + prnap: '\u2AB9', + prnE: '\u2AB5', + prnsim: '\u22E8', + prod: '\u220F', + Product: '\u220F', + profalar: '\u232E', + profline: '\u2312', + profsurf: '\u2313', + prop: '\u221D', + Proportion: '\u2237', + Proportional: '\u221D', + propto: '\u221D', + prsim: '\u227E', + prurel: '\u22B0', + Pscr: '\uD835\uDCAB', + pscr: '\uD835\uDCC5', + Psi: 'Ψ', + psi: 'ψ', + puncsp: '\u2008', + Qfr: '\uD835\uDD14', + qfr: '\uD835\uDD2E', + qint: '\u2A0C', + Qopf: 'ℚ', + qopf: '\uD835\uDD62', + qprime: '\u2057', + Qscr: '\uD835\uDCAC', + qscr: '\uD835\uDCC6', + quaternions: 'ℍ', + quatint: '\u2A16', + quest: '?', + questeq: '\u225F', + QUOT: '"', + quot: '"', + rAarr: '\u21DB', + race: '\u223Ḏ', + Racute: 'Ŕ', + racute: 'ŕ', + radic: '\u221A', + raemptyv: '\u29B3', + Rang: '\u27EB', + rang: '\u27E9', + rangd: '\u2992', + range: '\u29A5', + rangle: '\u27E9', + raquo: '\xBB', + Rarr: '\u21A0', + rArr: '\u21D2', + rarr: '\u2192', + rarrap: '\u2975', + rarrb: '\u21E5', + rarrbfs: '\u2920', + rarrc: '\u2933', + rarrfs: '\u291E', + rarrhk: '\u21AA', + rarrlp: '\u21AC', + rarrpl: '\u2945', + rarrsim: '\u2974', + Rarrtl: '\u2916', + rarrtl: '\u21A3', + rarrw: '\u219D', + rAtail: '\u291C', + ratail: '\u291A', + ratio: '\u2236', + rationals: 'ℚ', + RBarr: '\u2910', + rBarr: '\u290F', + rbarr: '\u290D', + rbbrk: '\u2773', + rbrace: '}', + rbrack: ']', + rbrke: '\u298C', + rbrksld: '\u298E', + rbrkslu: '\u2990', + Rcaron: 'Ř', + rcaron: 'ř', + Rcedil: 'Ŗ', + rcedil: 'ŗ', + rceil: '\u2309', + rcub: '}', + Rcy: 'Р', + rcy: 'р', + rdca: '\u2937', + rdldhar: '\u2969', + rdquo: '\u201D', + rdquor: '\u201D', + rdsh: '\u21B3', + Re: 'ℜ', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '\u25AD', + REG: '\xAE', + reg: '\xAE', + ReverseElement: '\u220B', + ReverseEquilibrium: '\u21CB', + ReverseUpEquilibrium: '\u296F', + rfisht: '\u297D', + rfloor: '\u230B', + Rfr: 'ℜ', + rfr: '\uD835\uDD2F', + rHar: '\u2964', + rhard: '\u21C1', + rharu: '\u21C0', + rharul: '\u296C', + Rho: 'Ρ', + rho: 'ρ', + rhov: 'ϱ', + RightAngleBracket: '\u27E9', + RightArrow: '\u2192', + Rightarrow: '\u21D2', + rightarrow: '\u2192', + RightArrowBar: '\u21E5', + RightArrowLeftArrow: '\u21C4', + rightarrowtail: '\u21A3', + RightCeiling: '\u2309', + RightDoubleBracket: '\u27E7', + RightDownTeeVector: '\u295D', + RightDownVector: '\u21C2', + RightDownVectorBar: '\u2955', + RightFloor: '\u230B', + rightharpoondown: '\u21C1', + rightharpoonup: '\u21C0', + rightleftarrows: '\u21C4', + rightleftharpoons: '\u21CC', + rightrightarrows: '\u21C9', + rightsquigarrow: '\u219D', + RightTee: '\u22A2', + RightTeeArrow: '\u21A6', + RightTeeVector: '\u295B', + rightthreetimes: '\u22CC', + RightTriangle: '\u22B3', + RightTriangleBar: '\u29D0', + RightTriangleEqual: '\u22B5', + RightUpDownVector: '\u294F', + RightUpTeeVector: '\u295C', + RightUpVector: '\u21BE', + RightUpVectorBar: '\u2954', + RightVector: '\u21C0', + RightVectorBar: '\u2953', + ring: '\u02DA', + risingdotseq: '\u2253', + rlarr: '\u21C4', + rlhar: '\u21CC', + rlm: '\u200F', + rmoust: '\u23B1', + rmoustache: '\u23B1', + rnmid: '\u2AEE', + roang: '\u27ED', + roarr: '\u21FE', + robrk: '\u27E7', + ropar: '\u2986', + Ropf: 'ℝ', + ropf: '\uD835\uDD63', + roplus: '\u2A2E', + rotimes: '\u2A35', + RoundImplies: '\u2970', + rpar: ')', + rpargt: '\u2994', + rppolint: '\u2A12', + rrarr: '\u21C9', + Rrightarrow: '\u21DB', + rsaquo: '\u203A', + Rscr: 'ℛ', + rscr: '\uD835\uDCC7', + Rsh: '\u21B1', + rsh: '\u21B1', + rsqb: ']', + rsquo: '\u2019', + rsquor: '\u2019', + rthree: '\u22CC', + rtimes: '\u22CA', + rtri: '\u25B9', + rtrie: '\u22B5', + rtrif: '\u25B8', + rtriltri: '\u29CE', + RuleDelayed: '\u29F4', + ruluhar: '\u2968', + rx: '\u211E', + Sacute: 'Ś', + sacute: 'ś', + sbquo: '\u201A', + Sc: '\u2ABC', + sc: '\u227B', + scap: '\u2AB8', + Scaron: 'Š', + scaron: 'š', + sccue: '\u227D', + scE: '\u2AB4', + sce: '\u2AB0', + Scedil: 'Ş', + scedil: 'ş', + Scirc: 'Ŝ', + scirc: 'ŝ', + scnap: '\u2ABA', + scnE: '\u2AB6', + scnsim: '\u22E9', + scpolint: '\u2A13', + scsim: '\u227F', + Scy: 'С', + scy: 'с', + sdot: '\u22C5', + sdotb: '\u22A1', + sdote: '\u2A66', + searhk: '\u2925', + seArr: '\u21D8', + searr: '\u2198', + searrow: '\u2198', + sect: '\xA7', + semi: ';', + seswar: '\u2929', + setminus: '\u2216', + setmn: '\u2216', + sext: '\u2736', + Sfr: '\uD835\uDD16', + sfr: '\uD835\uDD30', + sfrown: '\u2322', + sharp: '\u266F', + SHCHcy: 'Щ', + shchcy: 'щ', + SHcy: 'Ш', + shcy: 'ш', + ShortDownArrow: '\u2193', + ShortLeftArrow: '\u2190', + shortmid: '\u2223', + shortparallel: '\u2225', + ShortRightArrow: '\u2192', + ShortUpArrow: '\u2191', + shy: '\xAD', + Sigma: 'Σ', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '\u223C', + simdot: '\u2A6A', + sime: '\u2243', + simeq: '\u2243', + simg: '\u2A9E', + simgE: '\u2AA0', + siml: '\u2A9D', + simlE: '\u2A9F', + simne: '\u2246', + simplus: '\u2A24', + simrarr: '\u2972', + slarr: '\u2190', + SmallCircle: '\u2218', + smallsetminus: '\u2216', + smashp: '\u2A33', + smeparsl: '\u29E4', + smid: '\u2223', + smile: '\u2323', + smt: '\u2AAA', + smte: '\u2AAC', + smtes: '\u2AAC︀', + SOFTcy: 'Ь', + softcy: 'ь', + sol: '/', + solb: '\u29C4', + solbar: '\u233F', + Sopf: '\uD835\uDD4A', + sopf: '\uD835\uDD64', + spades: '\u2660', + spadesuit: '\u2660', + spar: '\u2225', + sqcap: '\u2293', + sqcaps: '\u2293︀', + sqcup: '\u2294', + sqcups: '\u2294︀', + Sqrt: '\u221A', + sqsub: '\u228F', + sqsube: '\u2291', + sqsubset: '\u228F', + sqsubseteq: '\u2291', + sqsup: '\u2290', + sqsupe: '\u2292', + sqsupset: '\u2290', + sqsupseteq: '\u2292', + squ: '\u25A1', + Square: '\u25A1', + square: '\u25A1', + SquareIntersection: '\u2293', + SquareSubset: '\u228F', + SquareSubsetEqual: '\u2291', + SquareSuperset: '\u2290', + SquareSupersetEqual: '\u2292', + SquareUnion: '\u2294', + squarf: '\u25AA', + squf: '\u25AA', + srarr: '\u2192', + Sscr: '\uD835\uDCAE', + sscr: '\uD835\uDCC8', + ssetmn: '\u2216', + ssmile: '\u2323', + sstarf: '\u22C6', + Star: '\u22C6', + star: '\u2606', + starf: '\u2605', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '\xAF', + Sub: '\u22D0', + sub: '\u2282', + subdot: '\u2ABD', + subE: '\u2AC5', + sube: '\u2286', + subedot: '\u2AC3', + submult: '\u2AC1', + subnE: '\u2ACB', + subne: '\u228A', + subplus: '\u2ABF', + subrarr: '\u2979', + Subset: '\u22D0', + subset: '\u2282', + subseteq: '\u2286', + subseteqq: '\u2AC5', + SubsetEqual: '\u2286', + subsetneq: '\u228A', + subsetneqq: '\u2ACB', + subsim: '\u2AC7', + subsub: '\u2AD5', + subsup: '\u2AD3', + succ: '\u227B', + succapprox: '\u2AB8', + succcurlyeq: '\u227D', + Succeeds: '\u227B', + SucceedsEqual: '\u2AB0', + SucceedsSlantEqual: '\u227D', + SucceedsTilde: '\u227F', + succeq: '\u2AB0', + succnapprox: '\u2ABA', + succneqq: '\u2AB6', + succnsim: '\u22E9', + succsim: '\u227F', + SuchThat: '\u220B', + Sum: '\u2211', + sum: '\u2211', + sung: '\u266A', + Sup: '\u22D1', + sup: '\u2283', + sup1: '\xB9', + sup2: '\xB2', + sup3: '\xB3', + supdot: '\u2ABE', + supdsub: '\u2AD8', + supE: '\u2AC6', + supe: '\u2287', + supedot: '\u2AC4', + Superset: '\u2283', + SupersetEqual: '\u2287', + suphsol: '\u27C9', + suphsub: '\u2AD7', + suplarr: '\u297B', + supmult: '\u2AC2', + supnE: '\u2ACC', + supne: '\u228B', + supplus: '\u2AC0', + Supset: '\u22D1', + supset: '\u2283', + supseteq: '\u2287', + supseteqq: '\u2AC6', + supsetneq: '\u228B', + supsetneqq: '\u2ACC', + supsim: '\u2AC8', + supsub: '\u2AD4', + supsup: '\u2AD6', + swarhk: '\u2926', + swArr: '\u21D9', + swarr: '\u2199', + swarrow: '\u2199', + swnwar: '\u292A', + szlig: 'ß', + Tab: '\t', + target: '\u2316', + Tau: 'Τ', + tau: 'τ', + tbrk: '\u23B4', + Tcaron: 'Ť', + tcaron: 'ť', + Tcedil: 'Ţ', + tcedil: 'ţ', + Tcy: 'Т', + tcy: 'т', + tdot: '⃛', + telrec: '\u2315', + Tfr: '\uD835\uDD17', + tfr: '\uD835\uDD31', + there4: '\u2234', + Therefore: '\u2234', + therefore: '\u2234', + Theta: 'Θ', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '\u2248', + thicksim: '\u223C', + ThickSpace: '\u205F\u200A', + thinsp: '\u2009', + ThinSpace: '\u2009', + thkap: '\u2248', + thksim: '\u223C', + THORN: 'Þ', + thorn: 'þ', + Tilde: '\u223C', + tilde: '\u02DC', + TildeEqual: '\u2243', + TildeFullEqual: '\u2245', + TildeTilde: '\u2248', + times: '\xD7', + timesb: '\u22A0', + timesbar: '\u2A31', + timesd: '\u2A30', + tint: '\u222D', + toea: '\u2928', + top: '\u22A4', + topbot: '\u2336', + topcir: '\u2AF1', + Topf: '\uD835\uDD4B', + topf: '\uD835\uDD65', + topfork: '\u2ADA', + tosa: '\u2929', + tprime: '\u2034', + TRADE: '\u2122', + trade: '\u2122', + triangle: '\u25B5', + triangledown: '\u25BF', + triangleleft: '\u25C3', + trianglelefteq: '\u22B4', + triangleq: '\u225C', + triangleright: '\u25B9', + trianglerighteq: '\u22B5', + tridot: '\u25EC', + trie: '\u225C', + triminus: '\u2A3A', + TripleDot: '⃛', + triplus: '\u2A39', + trisb: '\u29CD', + tritime: '\u2A3B', + trpezium: '\u23E2', + Tscr: '\uD835\uDCAF', + tscr: '\uD835\uDCC9', + TScy: 'Ц', + tscy: 'ц', + TSHcy: 'Ћ', + tshcy: 'ћ', + Tstrok: 'Ŧ', + tstrok: 'ŧ', + twixt: '\u226C', + twoheadleftarrow: '\u219E', + twoheadrightarrow: '\u21A0', + Uacute: 'Ú', + uacute: 'ú', + Uarr: '\u219F', + uArr: '\u21D1', + uarr: '\u2191', + Uarrocir: '\u2949', + Ubrcy: 'Ў', + ubrcy: 'ў', + Ubreve: 'Ŭ', + ubreve: 'ŭ', + Ucirc: 'Û', + ucirc: 'û', + Ucy: 'У', + ucy: 'у', + udarr: '\u21C5', + Udblac: 'Ű', + udblac: 'ű', + udhar: '\u296E', + ufisht: '\u297E', + Ufr: '\uD835\uDD18', + ufr: '\uD835\uDD32', + Ugrave: 'Ù', + ugrave: 'ù', + uHar: '\u2963', + uharl: '\u21BF', + uharr: '\u21BE', + uhblk: '\u2580', + ulcorn: '\u231C', + ulcorner: '\u231C', + ulcrop: '\u230F', + ultri: '\u25F8', + Umacr: 'Ū', + umacr: 'ū', + uml: '\xA8', + UnderBar: '_', + UnderBrace: '\u23DF', + UnderBracket: '\u23B5', + UnderParenthesis: '\u23DD', + Union: '\u22C3', + UnionPlus: '\u228E', + Uogon: 'Ų', + uogon: 'ų', + Uopf: '\uD835\uDD4C', + uopf: '\uD835\uDD66', + UpArrow: '\u2191', + Uparrow: '\u21D1', + uparrow: '\u2191', + UpArrowBar: '\u2912', + UpArrowDownArrow: '\u21C5', + UpDownArrow: '\u2195', + Updownarrow: '\u21D5', + updownarrow: '\u2195', + UpEquilibrium: '\u296E', + upharpoonleft: '\u21BF', + upharpoonright: '\u21BE', + uplus: '\u228E', + UpperLeftArrow: '\u2196', + UpperRightArrow: '\u2197', + Upsi: 'ϒ', + upsi: 'υ', + upsih: 'ϒ', + Upsilon: 'Υ', + upsilon: 'υ', + UpTee: '\u22A5', + UpTeeArrow: '\u21A5', + upuparrows: '\u21C8', + urcorn: '\u231D', + urcorner: '\u231D', + urcrop: '\u230E', + Uring: 'Ů', + uring: 'ů', + urtri: '\u25F9', + Uscr: '\uD835\uDCB0', + uscr: '\uD835\uDCCA', + utdot: '\u22F0', + Utilde: 'Ũ', + utilde: 'ũ', + utri: '\u25B5', + utrif: '\u25B4', + uuarr: '\u21C8', + Uuml: 'Ü', + uuml: 'ü', + uwangle: '\u29A7', + vangrt: '\u299C', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '\u2205', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '\u221D', + vArr: '\u21D5', + varr: '\u2195', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '\u228A︀', + varsubsetneqq: '\u2ACB︀', + varsupsetneq: '\u228B︀', + varsupsetneqq: '\u2ACC︀', + vartheta: 'ϑ', + vartriangleleft: '\u22B2', + vartriangleright: '\u22B3', + Vbar: '\u2AEB', + vBar: '\u2AE8', + vBarv: '\u2AE9', + Vcy: 'В', + vcy: 'в', + VDash: '\u22AB', + Vdash: '\u22A9', + vDash: '\u22A8', + vdash: '\u22A2', + Vdashl: '\u2AE6', + Vee: '\u22C1', + vee: '\u2228', + veebar: '\u22BB', + veeeq: '\u225A', + vellip: '\u22EE', + Verbar: '\u2016', + verbar: '|', + Vert: '\u2016', + vert: '|', + VerticalBar: '\u2223', + VerticalLine: '|', + VerticalSeparator: '\u2758', + VerticalTilde: '\u2240', + VeryThinSpace: '\u200A', + Vfr: '\uD835\uDD19', + vfr: '\uD835\uDD33', + vltri: '\u22B2', + vnsub: '\u2282⃒', + vnsup: '\u2283⃒', + Vopf: '\uD835\uDD4D', + vopf: '\uD835\uDD67', + vprop: '\u221D', + vrtri: '\u22B3', + Vscr: '\uD835\uDCB1', + vscr: '\uD835\uDCCB', + vsubnE: '\u2ACB︀', + vsubne: '\u228A︀', + vsupnE: '\u2ACC︀', + vsupne: '\u228B︀', + Vvdash: '\u22AA', + vzigzag: '\u299A', + Wcirc: 'Ŵ', + wcirc: 'ŵ', + wedbar: '\u2A5F', + Wedge: '\u22C0', + wedge: '\u2227', + wedgeq: '\u2259', + weierp: '\u2118', + Wfr: '\uD835\uDD1A', + wfr: '\uD835\uDD34', + Wopf: '\uD835\uDD4E', + wopf: '\uD835\uDD68', + wp: '\u2118', + wr: '\u2240', + wreath: '\u2240', + Wscr: '\uD835\uDCB2', + wscr: '\uD835\uDCCC', + xcap: '\u22C2', + xcirc: '\u25EF', + xcup: '\u22C3', + xdtri: '\u25BD', + Xfr: '\uD835\uDD1B', + xfr: '\uD835\uDD35', + xhArr: '\u27FA', + xharr: '\u27F7', + Xi: 'Ξ', + xi: 'ξ', + xlArr: '\u27F8', + xlarr: '\u27F5', + xmap: '\u27FC', + xnis: '\u22FB', + xodot: '\u2A00', + Xopf: '\uD835\uDD4F', + xopf: '\uD835\uDD69', + xoplus: '\u2A01', + xotime: '\u2A02', + xrArr: '\u27F9', + xrarr: '\u27F6', + Xscr: '\uD835\uDCB3', + xscr: '\uD835\uDCCD', + xsqcup: '\u2A06', + xuplus: '\u2A04', + xutri: '\u25B3', + xvee: '\u22C1', + xwedge: '\u22C0', + Yacute: 'Ý', + yacute: 'ý', + YAcy: 'Я', + yacy: 'я', + Ycirc: 'Ŷ', + ycirc: 'ŷ', + Ycy: 'Ы', + ycy: 'ы', + yen: '\xA5', + Yfr: '\uD835\uDD1C', + yfr: '\uD835\uDD36', + YIcy: 'Ї', + yicy: 'ї', + Yopf: '\uD835\uDD50', + yopf: '\uD835\uDD6A', + Yscr: '\uD835\uDCB4', + yscr: '\uD835\uDCCE', + YUcy: 'Ю', + yucy: 'ю', + Yuml: 'Ÿ', + yuml: 'ÿ', + Zacute: 'Ź', + zacute: 'ź', + Zcaron: 'Ž', + zcaron: 'ž', + Zcy: 'З', + zcy: 'з', + Zdot: 'Ż', + zdot: 'ż', + zeetrf: 'ℨ', + ZeroWidthSpace: '\u200B', + Zeta: 'Ζ', + zeta: 'ζ', + Zfr: 'ℨ', + zfr: '\uD835\uDD37', + ZHcy: 'Ж', + zhcy: 'ж', + zigrarr: '\u21DD', + Zopf: 'ℤ', + zopf: '\uD835\uDD6B', + Zscr: '\uD835\uDCB5', + zscr: '\uD835\uDCCF', + zwj: '‍', + zwnj: '‌' + }; + exports.default = namedCharRefs; +}); +/*simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenize*/ +define('simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenize', [ + 'exports', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/tokenizer', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/entity-parser', + 'simple-html-tokenizer@0.2.6#lib/simple-html-tokenizer/html5-named-char-refs' +], function (exports, _tokenizer, _entityParser, _html5NamedCharRefs) { + 'use strict'; + Object.defineProperty(exports, '__esModule', { value: true }); + var _tokenizer2 = _interopRequireDefault(_tokenizer); + var _entityParser2 = _interopRequireDefault(_entityParser); + var _html5NamedCharRefs2 = _interopRequireDefault(_html5NamedCharRefs); + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj }; + } + function tokenize(input, options) { + var tokenizer = new _tokenizer2.default(new _entityParser2.default(_html5NamedCharRefs2.default), options); + return tokenizer.tokenize(input); + } + exports.default = tokenize; +}); +/*can-simple-dom@1.7.1#lib/default-tokenize*/ +define('can-simple-dom@1.7.1#lib/default-tokenize', [ + 'require', + 'exports', + 'module', + 'simple-html-tokenizer/lib/simple-html-tokenizer/tokenize' +], function (require, exports, module) { + var tokenize = require('simple-html-tokenizer/lib/simple-html-tokenizer/tokenize').default; + module.exports = function (input) { + return tokenize(input); + }; +}); +/*can-simple-dom@1.7.1#test/element-sp-test*/ +define('can-simple-dom@1.7.1#test/element-sp-test', [ + 'require', + 'exports', + 'module', + '../can-simple-dom', + 'steal-qunit', + '../lib/html-parser', + '../lib/void-map', + '../lib/html-serializer', + '../lib/default-tokenize' +], function (require, exports, module) { + var Document = require('../can-simple-dom'); + var QUnit = require('steal-qunit'); + var Parser = require('../lib/html-parser'); + var voidMap = require('../lib/void-map'); + var Serializer = require('../lib/html-serializer'); + var tokenize = require('../lib/default-tokenize'); + QUnit.module('can-simple-dom - Element with serialization and parsing'); + QUnit.test('document.implementation is supported (#23)', function (assert) { + var document = new Document(); + document.__addSerializerAndParser(new Serializer(voidMap), new Parser(tokenize, document, voidMap)); + assert.ok(document.implementation, 'implementation exists'); + var doc2 = document.implementation.createHTMLDocument(''); + assert.ok(doc2.body, 'has a body'); + }); + QUnit.test('innerHTML supported', function (assert) { + var document = new Document(); + document.__addSerializerAndParser(new Serializer(voidMap), new Parser(tokenize, document, voidMap)); + document.body.innerHTML = 'HI'; + assert.equal(document.body.firstChild.nodeName, 'SPAN'); + assert.equal(document.body.firstChild.className, 'bar'); + assert.equal(document.body.firstChild.firstChild.nodeValue, 'HI'); + assert.equal(document.body.innerHTML, 'HI'); + }); + QUnit.test('outerHTML supported', function (assert) { + var document = new Document(); + document.__addSerializerAndParser(new Serializer(voidMap), new Parser(tokenize, document, voidMap)); + document.body.innerHTML = '
      HI
      '; + var item = document.getElementById('item'); + assert.equal(item.outerHTML, '
      HI
      ', 'getter'); + item.outerHTML = ''; + assert.equal(document.body.innerHTML, '', 'setter'); + }); +}); +/*can-simple-dom@1.7.1#test/element-event-test*/ +define('can-simple-dom@1.7.1#test/element-event-test', [ + 'require', + 'exports', + 'module', + '../lib/document', + '../lib/html-serializer', + '../lib/void-map', + './support', + 'steal-qunit' +], function (require, exports, module) { + var Document = require('../lib/document'); + var Serializer = require('../lib/html-serializer'); + var voidMap = require('../lib/void-map'); + var _support = require('./support'); + var element = _support.element; + var fragment = _support.fragment; + var text = _support.text; + var QUnit = require('steal-qunit'); + QUnit.module('can-simple-dom - Event'); + QUnit.test('basic bubbling', function (assert) { + assert.expect(4); + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + document.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document, 'document current target'); + }); + document.documentElement.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.documentElement, 'documentElement current target'); + }); + document.body.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.body, 'body current target'); + }); + elem.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, elem, 'elem current target'); + }); + document.body.appendChild(elem); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', true, false); + elem.dispatchEvent(ev); + }); + QUnit.test('stop propagation', function (assert) { + assert.expect(2); + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + document.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document, 'document current target'); + }); + document.documentElement.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.documentElement, 'documentElement current target'); + }); + document.body.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.body, 'body current target'); + event.stopPropagation(); + }); + elem.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, elem, 'elem current target'); + }); + document.body.appendChild(elem); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', true, false); + elem.dispatchEvent(ev); + }); + QUnit.test('initEvent without bubbling', function (assert) { + assert.expect(2); + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + document.body.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, document.body, 'body current target'); + event.stopPropagation(); + }); + elem.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, elem, 'elem current target'); + }); + elem.addEventListener('foo', function (event) { + assert.strictEqual(event.currentTarget, elem, 'elem current target'); + }); + document.body.appendChild(elem); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', false, false); + elem.dispatchEvent(ev); + }); + QUnit.test('this inside event handler', function (assert) { + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + elem.addEventListener('foo', function () { + assert.equal(this, elem, 'this is the element'); + }); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', true, false); + elem.dispatchEvent(ev); + }); + QUnit.test('deduplicate event handlers', function (assert) { + var done = assert.async(); + var document = new Document(); + var elem = document.createElement('div'); + document.body.appendChild(elem); + var handler = function () { + assert.ok(true, 'event dispatched'); + done(); + }; + elem.addEventListener('foo', handler); + elem.addEventListener('foo', handler); + var ev = document.createEvent('HTMLEvents'); + ev.initEvent('foo', true, false); + elem.dispatchEvent(ev); + }); +}); +/*can-simple-dom@1.7.1#test/parser-test*/ +define('can-simple-dom@1.7.1#test/parser-test', [ + 'require', + 'exports', + 'module', + './support', + '../lib/html-parser', + '../lib/void-map', + '../lib/default-tokenize', + 'steal-qunit' +], function (require, exports, module) { + var _support = require('./support'); + var document = _support.document; + var Parser = require('../lib/html-parser'); + var voidMap = require('../lib/void-map'); + var tokenize = require('../lib/default-tokenize'); + var QUnit = require('steal-qunit'); + QUnit.module('can-simple-dom - Basic HTML parsing', { + beforeEach: function () { + this.parser = new Parser(tokenize, document, voidMap); + } + }); + QUnit.test('simple parse', function (assert) { + var fragment = this.parser.parse('
      Hello
      '); + assert.ok(fragment); + var node = fragment.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName.toLowerCase(), 'div'); + assert.ok(node.firstChild); + assert.equal(node.firstChild.nodeType, 3); + assert.equal(node.firstChild.nodeValue, 'Hello'); + }); + QUnit.test('nested parse', function (assert) { + var fragment = this.parser.parse('text before
      Hello
      text between
      World
      text after'); + assert.ok(fragment); + var node = fragment.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'text before'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'DIV'); + assert.ok(node.firstChild); + assert.equal(node.firstChild.nodeType, 3); + assert.equal(node.firstChild.nodeValue, 'Hello'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'text between'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'DIV'); + var expectedValues = { + id: 'foo', + title: 'Hello World' + }; + assert.equal(node.attributes.length, 2); + assert.equal(node.attributes[0].value, expectedValues[node.attributes[0].name]); + assert.equal(node.attributes[1].value, expectedValues[node.attributes[1].name]); + assert.equal(node.attributes.length, 2); + assert.ok(node.firstChild); + assert.equal(node.firstChild.nodeType, 3); + assert.equal(node.firstChild.nodeValue, 'World'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'text after'); + }); + QUnit.test('void tags', function (assert) { + var fragment = this.parser.parse('
      Hello
      World
      '); + assert.ok(fragment); + var node = fragment.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'DIV'); + node = node.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'Hello'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'BR'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 3); + assert.equal(node.nodeValue, 'World'); + node = node.nextSibling; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'IMG'); + assert.equal(node.getAttribute('src'), 'http://example.com/image.png?foo=bar&bar=foo'); + assert.equal(node.nextSibling, null); + }); + QUnit.test('node attribute charater encode', function (assert) { + var fragment = this.parser.parse('
      '); + assert.ok(fragment); + var node = fragment.firstChild; + assert.ok(node); + assert.equal(node.nodeType, 1); + assert.equal(node.nodeName, 'DIV'); + var attibutes = node.attributes; + assert.ok(attibutes.length); + var title = attibutes[0]; + assert.equal(title.name, 'title'); + assert.equal(title.value, ' foo & bar & baz < buz > biz'); + }); +}); +/*can-simple-dom@1.7.1#test/style-test*/ +define('can-simple-dom@1.7.1#test/style-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../lib/document/style' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var CSSStyleDeclaration = require('../lib/document/style'); + QUnit.module('can-simple-dom - CSStyleDeclaration'); + QUnit.test('cssText is enumerable', function (assert) { + var proto = CSSStyleDeclaration.prototype; + var descriptor = Object.getOwnPropertyDescriptor(proto, 'cssText'); + assert.equal(descriptor.enumerable, true, 'it is enumerable'); + }); + QUnit.test('cssText is configurable', function (assert) { + var proto = CSSStyleDeclaration.prototype; + var descriptor = Object.getOwnPropertyDescriptor(proto, 'cssText'); + assert.equal(descriptor.configurable, true, 'it is configurable'); + }); + QUnit.test('getPropertyValue must be a function', function (assert) { + var proto = CSSStyleDeclaration.prototype; + assert.equal(typeof proto.getPropertyValue, 'function', 'it is a function'); + }); +}); +/*can-simple-dom@1.7.1#test/test*/ +define('can-simple-dom@1.7.1#test/test', [ + 'require', + 'exports', + 'module', + './document-test', + './element-test', + './serializer-test', + './element-sp-test', + './element-event-test', + './parser-test', + './style-test' +], function (require, exports, module) { + require('./document-test'); + require('./element-test'); + require('./serializer-test'); + require('./element-sp-test'); + require('./element-event-test'); + require('./parser-test'); + require('./style-test'); +}); +/*can-simple-observable@2.5.0#can-simple-observable-test*/ +define('can-simple-observable@2.5.0#can-simple-observable-test', [ + 'require', + 'exports', + 'module', + '@steal', + 'steal-qunit', + 'can-symbol', + 'can-simple-observable', + 'can-reflect', + 'can-observation-recorder' +], function (require, exports, module) { + var steal = require('@steal'); + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var SimpleObservable = require('can-simple-observable'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var getChangesSymbol = canSymbol.for('can.getChangesDependencyRecord'); + var skipProduction = steal.isEnv('production') ? QUnit.skip : QUnit.test; + QUnit.module('can-simple-observable'); + QUnit.test('basics', function (assert) { + assert.expect(5); + var obs = new SimpleObservable('one'); + assert.equal(canReflect.getValue(obs), 'one', 'getValue'); + canReflect.setValue(obs, 'two'); + ObservationRecorder.start(); + assert.equal(canReflect.getValue(obs), 'two', 'setValue'); + var dependencies = ObservationRecorder.stop(); + assert.ok(dependencies.valueDependencies.has(obs), 'was recorded'); + var handler = function (newValue) { + assert.equal(newValue, 'three', 'onValue'); + }; + canReflect.onValue(obs, handler); + canReflect.setValue(obs, 'three'); + canReflect.offValue(obs, handler); + canReflect.setValue(obs, 'four'); + assert.equal(canReflect.getValue(obs), 'four', 'getValue after offValue'); + }); + QUnit.test('basics with .value', function (assert) { + assert.expect(5); + var obs = new SimpleObservable('one'); + assert.equal(obs.value, 'one', 'getValue'); + obs.value = 'two'; + ObservationRecorder.start(); + assert.equal(obs.value, 'two', 'setValue'); + var dependencies = ObservationRecorder.stop(); + assert.ok(dependencies.valueDependencies.has(obs), 'was recorded'); + var handler = function (newValue) { + assert.equal(newValue, 'three', 'onValue'); + }; + canReflect.onValue(obs, handler); + obs.value = 'three'; + canReflect.offValue(obs, handler); + obs.value = 'four'; + assert.equal(obs.value, 'four', 'getValue after offValue'); + }); + skipProduction('log observable changes', function (assert) { + var done = assert.async(); + var obs = new SimpleObservable('one'); + obs.log(); + assert.expect(2); + obs._log = function (previous, current) { + assert.equal(current, 'two', 'should get current value'); + assert.equal(previous, 'one', 'should get previous value'); + done(); + }; + canReflect.setValue(obs, 'two'); + }); + skipProduction('getWhatIChange works', function (assert) { + var one = new SimpleObservable('one'); + var two = new SimpleObservable('two'); + var handler = function handler() { + two.set('three'); + }; + var dependencyRecord = { valueDependencies: new Set([two]) }; + handler[getChangesSymbol] = function () { + return dependencyRecord; + }; + canReflect.onValue(one, handler); + assert.deepEqual(canReflect.getWhatIChange(one).mutate, dependencyRecord); + }); +}); +/*can-stache-key@1.4.3#can-stache-key-test*/ +define('can-stache-key@1.4.3#can-stache-key-test', [ + 'require', + 'exports', + 'module', + 'can-stache-key', + 'steal-qunit', + 'can-observation', + 'can-event-queue/map/map', + 'can-simple-observable', + 'can-test-helpers', + 'can-observation-recorder', + 'can-simple-map', + 'can-reflect' +], function (require, exports, module) { + var observeReader = require('can-stache-key'); + var QUnit = require('steal-qunit'); + var Observation = require('can-observation'); + var eventQueue = require('can-event-queue/map/map'); + var SimpleObservable = require('can-simple-observable'); + var testHelpers = require('can-test-helpers'); + var ObservationRecorder = require('can-observation-recorder'); + var SimpleMap = require('can-simple-map'); + var canReflect = require('can-reflect'); + QUnit.module('can-stache-key', {}); + QUnit.test('can read a promise (#179)', function (assert) { + var done = assert.async(); + var data = { + promise: new Promise(function (resolve) { + setTimeout(function () { + resolve('Something'); + }, 2); + }) + }; + var calls = 0; + var c = new Observation(function () { + return observeReader.read(data, observeReader.reads('promise.value')).value; + }); + canReflect.onValue(c, function (newVal, oldVal) { + calls++; + assert.equal(calls, 1, 'only one call'); + assert.equal(newVal, 'Something', 'new value'); + assert.equal(oldVal, undefined, 'oldVal'); + done(); + }); + }); + QUnit.test('can.Compute.read can read a promise-like (#82)', function (assert) { + var done = assert.async(); + var data = { + promiseLike: { + then: function (resolve) { + setTimeout(function () { + resolve('Something'); + }, 2); + } + } + }; + var calls = 0; + var c = new Observation(function () { + return observeReader.read(data, observeReader.reads('promiseLike.value')).value; + }); + canReflect.onValue(c, function (newVal, oldVal) { + calls++; + assert.equal(calls, 1, 'only one call'); + assert.equal(newVal, 'Something', 'new value'); + assert.equal(oldVal, undefined, 'oldVal'); + done(); + }); + }); + QUnit.test('can.compute.reads', function (assert) { + assert.deepEqual(observeReader.reads('@foo'), [{ + key: 'foo', + at: true + }]); + assert.deepEqual(observeReader.reads('@foo.bar'), [ + { + key: 'foo', + at: true + }, + { + key: 'bar', + at: false + } + ]); + assert.deepEqual(observeReader.reads('@foo\\.bar'), [{ + key: 'foo.bar', + at: true + }]); + assert.deepEqual(observeReader.reads('foo.bar@zed'), [ + { + key: 'foo', + at: false + }, + { + key: 'bar', + at: false + }, + { + key: 'zed', + at: true + } + ]); + }); + QUnit.test('able to read things like can-define', function (assert) { + assert.expect(3); + var obj = eventQueue({}); + var prop = 'PROP'; + Object.defineProperty(obj, 'prop', { + get: function () { + ObservationRecorder.add(obj, 'prop'); + return prop; + }, + set: function (val) { + var old = prop; + prop = val; + this.dispatch('prop', prop, old); + } + }); + var data = { obj: obj }; + var c = new Observation(function () { + var value = observeReader.read(data, observeReader.reads('obj.prop'), { + foundObservable: function (obs, index) { + assert.equal(obs, obj, 'got an observable'); + assert.equal(index, 1, 'got the right index'); + } + }).value; + assert.equal(value, 'PROP'); + }); + canReflect.onValue(c, function () { + }); + }); + QUnit.test('foundObservable called with observable object (#7)', function (assert) { + var map = new SimpleMap({ + isSaving: function () { + ObservationRecorder.add(this, '_saving'); + }, + addEventListener: function () { + } + }); + var c = new Observation(function () { + observeReader.read(map, observeReader.reads('isSaving'), { + foundObservable: function (obs) { + assert.equal(obs, map); + }, + callMethodsOnObservables: true + }); + }); + canReflect.onValue(c, function () { + }); + }); + QUnit.test('can read from strings', function (assert) { + var context = ' hi there '; + var result = observeReader.read(context, observeReader.reads('trim'), {}); + assert.equal(result.value(context), context.trim(context), 'trim method works'); + }); + QUnit.test('read / write to SimpleMap', function (assert) { + var map = new SimpleMap(); + var c = new Observation(function () { + var data = observeReader.read(map, observeReader.reads('value'), { + foundObservable: function (obs) { + assert.equal(obs, map, 'got map'); + } + }); + return data.value; + }); + canReflect.onValue(c, function (newVal) { + assert.equal(newVal, 1, 'got updated'); + }); + observeReader.write(map, 'value', 1); + }); + QUnit.test('write deep in SimpleMap', function (assert) { + var map = new SimpleMap(); + observeReader.write(map, 'foo', new SimpleMap()); + observeReader.write(map, 'foo.bar', 1); + assert.equal(map.get('foo').get('bar'), 1, 'value set'); + }); + QUnit.test('write to compute in object', function (assert) { + var value = 2; + var computeObject = {}; + canReflect.assignSymbols(computeObject, { + 'can.getValue': function () { + return value; + }, + 'can.setValue': function (newVal) { + value = newVal; + } + }); + var obj = { compute: computeObject }; + observeReader.write(obj, 'compute', 3); + assert.equal(value, 3, 'value set'); + }); + QUnit.test('write to a map in a compute', function (assert) { + var map = new SimpleMap({ complete: true }); + var computeObject = {}; + canReflect.assignSymbols(computeObject, { + 'can.getValue': function () { + return map; + }, + 'can.setValue': function (newVal) { + map = newVal; + } + }); + observeReader.write(computeObject, 'complete', false); + assert.equal(map.attr('complete'), false, 'value set'); + }); + QUnit.test('reads can be passed a number (can-stache#207)', function (assert) { + var reads = observeReader.reads(0); + assert.deepEqual(reads, [{ + key: '0', + at: false + }], 'number converted to string'); + }); + QUnit.test('can read primitive numbers (#88)', function (assert) { + var reads = observeReader.reads('num@toFixed'); + var toFixed = observeReader.read({ num: 5 }, reads, {}).value; + assert.equal(typeof toFixed, 'function', 'got to fixed'); + }); + QUnit.test('it returns null when promise getter is null #2', function (assert) { + var nullPromise = observeReader.read(null, observeReader.reads('value')); + assert.equal(typeof nullPromise, 'object'); + }); + QUnit.test('set onto observable objects and values', function (assert) { + var map = new SimpleMap(); + observeReader.write({ map: map }, 'map', { a: 'b' }); + assert.equal(map.get('a'), 'b', 'merged'); + var simple = new SimpleObservable(); + observeReader.write({ simple: simple }, 'simple', 1); + assert.equal(simple.get(), 1); + }); + testHelpers.dev.devOnlyTest('functions are not called by read()', function (assert) { + var func = function () { + assert.ok(false, 'method called'); + }; + var data = { func: func }; + var reads = observeReader.reads('func'); + observeReader.read(data, reads); + assert.ok(true); + }); + testHelpers.dev.devOnlyTest('a warning is given for `callMethodsOnObservables: true`', function (assert) { + var teardown = testHelpers.dev.willWarn('can-stache-key: read() called with `callMethodsOnObservables: true`.'); + var func = function () { + assert.ok(true, 'method called'); + }; + var data = new SimpleMap({ func: func }); + var reads = observeReader.reads('func'); + observeReader.read(data, reads, { callMethodsOnObservables: true }); + assert.equal(teardown(), 1, 'warning displayed'); + }); + QUnit.test('writing to a null observable is ignored', function (assert) { + observeReader.write({}, 'foo.bar', 'value'); + observeReader.write(null, 'bar', 'value'); + observeReader.write(null, 'foo.bar', 'value'); + assert.ok(true, 'all passed without error'); + }); + QUnit.test('parentHasKey and foundLastParent (#31)', function (assert) { + var hasKeys = function (obj, keys) { + canReflect.assignSymbols(obj, { + 'can.hasKey': function (key) { + return keys.indexOf(key) > -1; + } + }); + }; + var def = { ghi: undefined }; + hasKeys(def, ['ghi']); + var abc = { def: def }; + hasKeys(abc, ['def']); + var parent = { abc: abc }; + hasKeys(parent, ['abc']); + var testCases = { + 'abc.def.ghi': { + parent: def, + value: undefined, + parentHasKey: true, + foundLastParent: true + }, + 'abc.def.jkl': { + parent: def, + value: undefined, + parentHasKey: false, + foundLastParent: true + }, + 'abc.ghi.ghi': { + parent: abc, + value: undefined, + parentHasKey: false, + foundLastParent: false + }, + 'def.ghi.jkl': { + parent: parent, + value: undefined, + parentHasKey: false, + foundLastParent: false + } + }; + var reads, actual, expected; + for (var key in testCases) { + reads = observeReader.reads(key); + actual = observeReader.read(parent, reads); + expected = testCases[key]; + assert.equal(actual.value, expected.value, key + '.value'); + assert.equal(actual.parent, expected.parent, key + '.parent'); + assert.equal(actual.parentHasKey, expected.parentHasKey, key + '.parentHasKey'); + assert.equal(actual.foundLastParent, expected.foundLastParent, key + '.foundLastParent'); + } + }); + QUnit.test('objHasKeyAtIndex doesn\'t handle non-object types correctly (#33)', function (assert) { + var result = observeReader.read(47, observeReader.reads('toFixed')); + assert.equal(typeof result.value, 'function'); + assert.equal(result.parent, 47); + assert.equal(result.parentHasKey, true); + }); + QUnit.test('write to an object', function (assert) { + var obj = {}; + observeReader.write(obj, 'value', 1); + assert.deepEqual(obj, { value: 1 }); + obj = { value: null }; + observeReader.write(obj, 'value', 1); + assert.deepEqual(obj, { value: 1 }); + }); + QUnit.test('.then won\'t call bindings #49', function (assert) { + var promiseIsh = {}; + Object.defineProperty(promiseIsh, 'then', { + get: function () { + ObservationRecorder.add(this, 'then'); + } + }); + ObservationRecorder.start(); + observeReader.read(promiseIsh, observeReader.reads('prop')); + var recordings = ObservationRecorder.stop(); + assert.equal(recordings.keyDependencies.size, 0, 'no key recordings'); + }); +}); +/*can-validate-interface@1.0.3#index*/ +define('can-validate-interface@1.0.3#index', function (require, exports, module) { + 'use strict'; + function flatten(arrays) { + return arrays.reduce(function (ret, val) { + return ret.concat(val); + }, []); + } + function makeInterfaceValidator(interfacePropArrays) { + var props = flatten(interfacePropArrays); + return function (base) { + var missingProps = props.reduce(function (missing, prop) { + return prop in base ? missing : missing.concat(prop); + }, []); + return missingProps.length ? { + message: 'missing expected properties', + related: missingProps + } : undefined; + }; + } + module.exports = makeInterfaceValidator; +}); +/*can-validate-interface@1.0.3#test*/ +define('can-validate-interface@1.0.3#test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './index.js' +], function (require, exports, module) { + 'use strict'; + var QUnit = require('steal-qunit'); + var makeInterfaceValidator = require('./index.js'); + QUnit.module('can-validate-interface/makeInterfaceValidator'); + QUnit.test('basics', function (assert) { + var dataMethods = [ + 'create', + 'read', + 'update', + 'delete' + ]; + var daoValidator = makeInterfaceValidator([ + dataMethods, + 'id' + ]); + var dao = { + create: function () { + }, + read: function () { + }, + update: function () { + }, + delete: function () { + } + }; + var errors = daoValidator(dao); + assert.deepEqual(errors, { + message: 'missing expected properties', + related: ['id'] + }); + dao.id = 10; + errors = daoValidator(dao); + assert.equal(errors, undefined); + }); +}); +/*can-view-live@5.0.4#test/html-test*/ +define('can-view-live@5.0.4#test/html-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-define/list/list', + 'can-observation', + 'steal-qunit', + 'can-simple-observable', + 'can-test-helpers', + 'can-dom-mutate', + 'can-reflect-dependencies', + 'can-symbol', + 'can-fragment', + 'can-queues', + 'can-dom-mutate/node/node', + 'can-globals' +], function (require, exports, module) { + (function (global, require, exports, module) { + var live = require('can-view-live'); + var DefineList = require('can-define/list/list'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SimpleObservable = require('can-simple-observable'); + var testHelpers = require('can-test-helpers'); + var domMutate = require('can-dom-mutate'); + var canReflectDeps = require('can-reflect-dependencies'); + var canSymbol = require('can-symbol'); + var fragment = require('can-fragment'); + var queues = require('can-queues'); + var domMutateNode = require('can-dom-mutate/node/node'); + var canGlobals = require('can-globals'); + QUnit.module('can-view-live.html'); + var afterMutation = function (cb) { + var doc = canGlobals.getKeyValue('document'); + var div = doc.createElement('div'); + var insertionDisposal = domMutate.onNodeInsertion(div, function () { + insertionDisposal(); + doc.body.removeChild(div); + setTimeout(cb, 5); + }); + setTimeout(function () { + domMutateNode.appendChild.call(doc.body, div); + }, 10); + }; + QUnit.test('basics', function (assert) { + var div = document.createElement('div'), span = document.createElement('span'); + div.appendChild(span); + var items = new DefineList([ + 'one', + 'two' + ]); + var html = new Observation(function itemsHTML() { + var html = ''; + items.forEach(function (item) { + html += ''; + }); + return html; + }); + live.html(span, html); + assert.equal(div.getElementsByTagName('label').length, 2); + items.push('three'); + assert.equal(div.getElementsByTagName('label').length, 3); + }); + QUnit.test('html live binding handles getting a function from a compute', function (assert) { + assert.expect(5); + var handler = function (el) { + assert.ok(true, 'called handler'); + assert.equal(el.nodeType, Node.COMMENT_NODE, 'got a placeholder'); + }; + var div = document.createElement('div'), placeholder = document.createTextNode(''); + div.appendChild(placeholder); + var count = new SimpleObservable(0); + var html = new Observation(function () { + if (count.get() === 0) { + return '

      Hello World

      '; + } else { + return handler; + } + }); + live.html(placeholder, html); + assert.equal(div.getElementsByTagName('h1').length, 1, 'got h1'); + count.set(1); + assert.equal(div.getElementsByTagName('h1').length, 0, 'got h1'); + count.set(0); + assert.equal(div.getElementsByTagName('h1').length, 1, 'got h1'); + }); + QUnit.test('Works with Observations - .html', function (assert) { + var div = document.createElement('div'), span = document.createElement('span'); + div.appendChild(span); + var items = new DefineList([ + 'one', + 'two' + ]); + var html = new Observation(function () { + var html = ''; + items.forEach(function (item) { + html += ''; + }); + return html; + }); + live.html(span, html, div); + assert.equal(div.getElementsByTagName('label').length, 2); + items.push('three'); + assert.equal(div.getElementsByTagName('label').length, 3); + }); + QUnit.test('html live binding handles objects with can.viewInsert symbol', function (assert) { + assert.expect(2); + var div = document.createElement('div'); + var options = {}; + var placeholder = document.createTextNode('Placeholder text'); + div.appendChild(placeholder); + var html = new Observation(function () { + var d = {}; + d[canSymbol.for('can.viewInsert')] = function () { + assert.equal(arguments[0], options, 'options were passed to symbol function'); + return document.createTextNode('Replaced text'); + }; + return d; + }); + live.html(placeholder, html, options); + assert.equal(div.textContent, 'Replaced text', 'symbol function called'); + }); + testHelpers.dev.devOnlyTest('child elements must disconnect before parents can re-evaluate', function (assert) { + assert.expect(1); + var observable = new SimpleObservable('value'); + var childObservation = new Observation(function child() { + assert.ok(true, 'called child content once'); + observable.get(); + return 'CHILD CONTENT'; + }); + var parentObservation = new Observation(function parent() { + var result = observable.get(); + if (result === 'value') { + var childTextNode = document.createTextNode(''); + var childFrag = document.createDocumentFragment(); + childFrag.appendChild(childTextNode); + live.html(childTextNode, childObservation); + return childFrag; + } else { + return 'NEW CONTENT'; + } + }); + var parentTextNode = document.createTextNode(''); + var div = document.createElement('div'); + div.appendChild(parentTextNode); + live.html(parentTextNode, parentObservation); + observable.set('VALUE'); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(3); + var div = document.createElement('div'), span = document.createElement('span'); + div.appendChild(span); + document.body.appendChild(div); + var html = new Observation(function simpleHello() { + return '

      Hello

      '; + }); + live.html(span, html); + assert.deepEqual(canReflectDeps.getDependencyDataOf(div.firstChild).whatChangesMe.mutate.valueDependencies, new Set([html]), 'whatChangesMe(
      ) shows the observation'); + assert.deepEqual(canReflectDeps.getDependencyDataOf(html).whatIChange.mutate.valueDependencies, new Set([div.firstChild]), 'whatIChange() shows the div'); + var undo = domMutate.onNodeDisconnected(div, function checkTeardown() { + undo(); + setTimeout(function () { + assert.equal(typeof canReflectDeps.getDependencyDataOf(div.firstChild), 'undefined', 'dependencies should be clear out when elements is removed'); + done(); + }, 20); + }); + domMutateNode.removeChild.call(div.parentNode, div); + }); + QUnit.test('.html works if it is enqueued twice', function (assert) { + var div = fragment('
      PLACEHOLDER
      ').firstChild; + var html = new SimpleObservable(fragment('

      1

      ')); + live.html(div.firstChild, html); + queues.batch.start(); + queues.domQueue.enqueue(function setHTMLTO3() { + var frag3 = fragment('

      3

      '); + frag3.ID = 3; + html.set(frag3); + }, null, [], { element: div.firstChild }); + var frag2 = fragment('

      2

      '); + frag2.ID = 2; + html.set(frag2); + queues.batch.stop(); + assert.ok(true, 'got here without an error'); + assert.deepEqual(div.querySelector('p').textContent, '3'); + }); + QUnit.test('tearing down a .html inside another .html works', function (assert) { + var showPerson = new SimpleObservable(true); + var personObservation = new Observation(function () { + return showPerson.value ? 'Matt' : undefined; + }); + var personFrag = document.createDocumentFragment(); + var personTextNode = document.createTextNode(''); + personFrag.appendChild(personTextNode); + live.html(personTextNode, personObservation, personFrag); + var ifPersonObservation = new Observation(function () { + return personObservation.value ? personFrag : undefined; + }); + var ifPersonFrag = document.createDocumentFragment(); + var ifPersonTextNode = document.createTextNode(''); + ifPersonFrag.appendChild(ifPersonTextNode); + live.html(ifPersonTextNode, ifPersonObservation, ifPersonFrag); + assert.deepEqual(ifPersonFrag.childNodes.length, 5, 'initial nodes correct'); + assert.deepEqual(ifPersonFrag.childNodes[2].textContent, 'Matt', 'initial text node correct'); + showPerson.value = false; + assert.deepEqual(ifPersonFrag.childNodes.length, 3, 'nodes torn down correctly'); + assert.deepEqual(ifPersonFrag.childNodes[1].textContent, '', 'placeholder text node correct'); + }); + QUnit.test('Live binding is restored when the placeholder is reconnected', function (assert) { + var done = assert.async(); + var div = document.createElement('div'), span = document.createElement('span'); + document.getElementById('qunit-fixture').appendChild(div); + div.appendChild(span); + var items = new DefineList([ + 'one', + 'two' + ]); + var html = new Observation(function itemsHTML() { + var html = ''; + items.forEach(function (item) { + html += ''; + }); + return html; + }); + live.html(span, html); + assert.equal(div.getElementsByTagName('label').length, 2); + var commentChildren = [].slice.call(div.childNodes, 0).filter(function (node) { + return node.nodeType === Node.COMMENT_NODE; + }); + div.removeChild(commentChildren[0]); + div.removeChild(commentChildren[1]); + afterMutation(function () { + items.push('three'); + div.insertBefore(commentChildren[0], div.firstChild); + div.appendChild(commentChildren[1]); + afterMutation(function () { + console.log(document.getElementById('qunit-fixture').innerHTML); + assert.equal(div.getElementsByTagName('label').length, 3); + done(); + }); + }); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-live@5.0.4#lib/patcher*/ +define('can-view-live@5.0.4#lib/patcher', [ + 'require', + 'exports', + 'module', + 'can-diff/patcher/patcher' +], function (require, exports, module) { + 'use strict'; + var Patcher = require('can-diff/patcher/patcher'); + module.exports = Patcher; +}); +/*can-view-live@5.0.4#test/patcher-test*/ +define('can-view-live@5.0.4#test/patcher-test', [ + 'require', + 'exports', + 'module', + 'can-define/list/list', + 'steal-qunit', + 'can-symbol', + '../lib/patcher', + 'can-simple-observable' +], function (require, exports, module) { + var DefineList = require('can-define/list/list'); + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var Patcher = require('../lib/patcher'); + var SimpleObservable = require('can-simple-observable'); + QUnit.module('can-view-live patcher', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('multiple lists can be updated at once', function (assert) { + assert.expect(2); + var list = new DefineList([ + 'a', + 'b' + ]); + var p1 = new Patcher(list), p2 = new Patcher(list); + p1[canSymbol.for('can.onPatches')](function () { + assert.ok(true, 'called p1'); + }); + p2[canSymbol.for('can.onPatches')](function () { + assert.ok(true, 'called p2'); + }); + list.push('c'); + }); + QUnit.test('undefined value won\'t error', function (assert) { + assert.expect(1); + var undfinedObservable = new SimpleObservable(undefined); + var pu = new Patcher(undfinedObservable); + pu[canSymbol.for('can.onPatches')](function () { + assert.ok(true, 'called pu'); + }); + undfinedObservable.set('a'); + }); +}); +/*can-view-live@5.0.4#test/list-test*/ +define('can-view-live@5.0.4#test/list-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-define/list/list', + 'can-observation', + 'steal-qunit', + 'can-simple-observable', + 'can-simple-map', + 'can-reflect', + 'can-queues', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-symbol', + 'can-test-helpers', + 'can-reflect-dependencies', + 'can-globals' +], function (require, exports, module) { + (function (global, require, exports, module) { + var live = require('can-view-live'); + var DefineList = require('can-define/list/list'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SimpleObservable = require('can-simple-observable'); + var SimpleMap = require('can-simple-map'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var canSymbol = require('can-symbol'); + var testHelpers = require('can-test-helpers'); + var canReflectDeps = require('can-reflect-dependencies'); + var globals = require('can-globals'); + function afterMutation(cb) { + var doc = globals.getKeyValue('document'); + var div = doc.createElement('div'); + var undo = domMutate.onNodeConnected(div, function () { + undo(); + doc.body.removeChild(div); + setTimeout(cb, 5); + }); + setTimeout(function () { + domMutateNode.appendChild.call(doc.body, div); + }, 10); + } + QUnit.module('can-view-live.list', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('basics', function (assert) { + var div = document.createElement('div'), list = new DefineList([ + 'sloth', + 'bear' + ]), template = function (animal) { + return ' ' + animal.get() + ''; + }; + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, list, template, {}); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + div.getElementsByTagName('label')[0].myexpando = 'EXPANDO-ED'; + list.push('turtle'); + assert.equal(div.getElementsByTagName('label')[0].myexpando, 'EXPANDO-ED', 'same expando'); + assert.equal(div.getElementsByTagName('span')[2].innerHTML, 'turtle', 'turtle added'); + }); + QUnit.test('list within an Observation', function (assert) { + assert.expect(5); + var div = document.createElement('div'), map = new SimpleMap({ + animals: new DefineList([ + 'bear', + 'turtle' + ]) + }), template = function (animal) { + return ' ' + animal.get() + ''; + }; + var listCompute = new Observation(function animalsFromMap() { + return map.attr('animals'); + }); + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, listCompute, template, {}); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + div.getElementsByTagName('label')[0].myexpando = 'EXPANDO-ED'; + map.attr('animals').push('turtle'); + assert.equal(div.getElementsByTagName('label')[0].myexpando, 'EXPANDO-ED', 'same expando'); + assert.equal(div.getElementsByTagName('span')[2].innerHTML, 'turtle', 'turtle added'); + map.attr('animals', new DefineList([ + 'sloth', + 'bear', + 'turtle' + ])); + var spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 3, 'there are 3 spans'); + assert.ok(!div.getElementsByTagName('label')[0].myexpando, 'no expando'); + }); + QUnit.test('.list within a observable value holding an Array list', function (assert) { + var div = document.createElement('div'); + var template = function (num) { + return ' ' + num + ''; + }; + var arr = new SimpleObservable([ + 0, + 1 + ]); + div.innerHTML = 'my fav nums: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, arr, template, {}); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + arr.set([ + 0, + 1, + 2 + ]); + var spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 3, 'there are 3 spans'); + }); + QUnit.test('live.list should handle move patches', function (assert) { + var parent = document.createElement('div'); + var child = document.createElement('div'); + parent.appendChild(child); + var onPatchesHandler; + var list = [ + 'a', + 'b', + 'c' + ]; + canReflect.assignSymbols(list, { + 'can.onPatches': function (handler) { + onPatchesHandler = handler; + } + }); + var template = function (num) { + return '' + num.get() + ''; + }; + live.list(child, list, template, {}); + list.shift(); + list.splice(1, 0, 'a'); + queues.batch.start(); + onPatchesHandler([{ + type: 'move', + fromIndex: 0, + toIndex: 1 + }]); + queues.batch.stop(); + assert.ok(true, 'The list should not blow up'); + var values = canReflect.toArray(parent.getElementsByTagName('span')).map(function (span) { + return span.innerHTML; + }); + assert.deepEqual(values, [ + 'b', + 'a', + 'c' + ]); + }); + QUnit.test('list and an falsey section (#1979)', function (assert) { + var div = document.createElement('div'), template = function (num) { + return ' ' + num + ''; + }, falseyTemplate = function () { + return '

      NOTHING

      '; + }; + var listCompute = new SimpleObservable([ + 0, + 1 + ]); + div.innerHTML = 'my fav nums: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, listCompute, template, {}, falseyTemplate); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + listCompute.set([]); + var spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 0, 'there are 0 spans'); + var ps = div.getElementsByTagName('p'); + assert.equal(ps.length, 1, 'there is 1 p'); + listCompute.set([2]); + spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 1, 'there is 1 spans'); + ps = div.getElementsByTagName('p'); + assert.equal(ps.length, 0, 'there is 1 p'); + }); + QUnit.test('list and an initial falsey section (#1979)', function (assert) { + var div = document.createElement('div'), template = function (num) { + return ' ' + num + ''; + }, falseyTemplate = function () { + return '

      NOTHING

      '; + }; + var listCompute = new SimpleObservable([]); + div.innerHTML = 'my fav nums: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, listCompute, template, {}, falseyTemplate); + var spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 0, 'there are 0 spans'); + var ps = div.getElementsByTagName('p'); + assert.equal(ps.length, 1, 'there is 1 p'); + listCompute.set([2]); + spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 1, 'there is 1 spans'); + ps = div.getElementsByTagName('p'); + assert.equal(ps.length, 0, 'there is 1 p'); + }); + QUnit.test('list items should be correct even if renderer flushes batch (#8)', function (assert) { + var partial = document.createElement('div'); + var placeholderElement = document.createElement('span'); + var list = new DefineList([ + 'one', + 'two' + ]); + var renderer = function (item) { + queues.flush(); + return '' + item.get() + ''; + }; + partial.appendChild(placeholderElement); + live.list(placeholderElement, list, renderer, {}); + assert.equal(partial.getElementsByTagName('span').length, 2, 'should be two items'); + assert.equal(partial.getElementsByTagName('span')[0].firstChild.data, 'one', 'list item 0 is "one"'); + assert.equal(partial.getElementsByTagName('span')[1].firstChild.data, 'two', 'list item 1 is "two"'); + queues.batch.start(); + list.splice(0, 0, 'three'); + list.splice(2, 1); + queues.batch.stop(); + assert.equal(partial.getElementsByTagName('span').length, 2, 'should be two items'); + assert.equal(partial.getElementsByTagName('span')[0].firstChild.data, 'three', 'list item 0 is "three"'); + assert.equal(partial.getElementsByTagName('span')[1].firstChild.data, 'one', 'list item 1 is "one"'); + }); + QUnit.test('can insert at multiple list indexes when flusing batch (#150)', function (assert) { + var partial = document.createElement('div'); + var placeholderElement = document.createElement('span'); + var list = new DefineList([ + 'one', + 'two' + ]); + var renderer = function (item) { + queues.flush(); + return '' + item.get() + ''; + }; + partial.appendChild(placeholderElement); + live.list(placeholderElement, list, renderer, {}); + assert.equal(partial.getElementsByTagName('span').length, 2, 'should be two items'); + assert.equal(partial.getElementsByTagName('span')[0].firstChild.data, 'one', 'list item 0 is "one"'); + assert.equal(partial.getElementsByTagName('span')[1].firstChild.data, 'two', 'list item 1 is "two"'); + queues.batch.start(); + list.splice(0, 0, 'zero'); + list.splice(2, 0, 'one and a half'); + list.splice(4, 0, 'three'); + queues.batch.stop(); + assert.equal(partial.getElementsByTagName('span').length, 5, 'should be five items'); + assert.equal(partial.getElementsByTagName('span')[0].firstChild.data, 'zero', 'list item 0 is "zero"'); + assert.equal(partial.getElementsByTagName('span')[1].firstChild.data, 'one', 'list item 1 is "one"'); + assert.equal(partial.getElementsByTagName('span')[2].firstChild.data, 'one and a half', 'list item 1 is "one"'); + assert.equal(partial.getElementsByTagName('span')[3].firstChild.data, 'two', 'list item 0 is "two"'); + assert.equal(partial.getElementsByTagName('span')[4].firstChild.data, 'three', 'list item 1 is "three"'); + }); + QUnit.test('can remove and insert at multiple list indexes when flusing batch', function (assert) { + var partial = document.createElement('div'); + var placeholderElement = document.createElement('span'); + var list = new DefineList([ + 'one', + 'two' + ]); + var renderer = function (item) { + queues.flush(); + return '' + item.get() + ''; + }; + partial.appendChild(placeholderElement); + live.list(placeholderElement, list, renderer, {}); + assert.equal(partial.getElementsByTagName('span').length, 2, 'should be two items'); + assert.equal(partial.getElementsByTagName('span')[0].firstChild.data, 'one', 'list item 0 is "one"'); + assert.equal(partial.getElementsByTagName('span')[1].firstChild.data, 'two', 'list item 1 is "two"'); + queues.batch.start(); + list.splice(0, 0, 'zero'); + list.splice(1, 1, 'one and a half'); + list.splice(2, 1, 'three'); + queues.batch.stop(); + assert.equal(partial.getElementsByTagName('span').length, 3, 'should be three items'); + assert.equal(partial.getElementsByTagName('span')[0].firstChild.data, 'zero', 'list item 0 is "zero"'); + assert.equal(partial.getElementsByTagName('span')[1].firstChild.data, 'one and a half', 'list item 1 is "one"'); + assert.equal(partial.getElementsByTagName('span')[2].firstChild.data, 'three', 'list item 1 is "three"'); + }); + QUnit.test('Works with Observations - .list', function (assert) { + var div = document.createElement('div'), map = new SimpleMap({ + animals: new DefineList([ + 'bear', + 'turtle' + ]) + }), template = function (animal) { + return ' ' + animal.get() + ''; + }; + var listObservation = new Observation(function () { + return map.attr('animals'); + }); + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + live.list(el, listObservation, template, {}); + assert.equal(div.getElementsByTagName('label').length, 2, 'There are 2 labels'); + div.getElementsByTagName('label')[0].myexpando = 'EXPANDO-ED'; + map.attr('animals').push('turtle'); + assert.equal(div.getElementsByTagName('label')[0].myexpando, 'EXPANDO-ED', 'same expando'); + assert.equal(div.getElementsByTagName('span')[2].innerHTML, 'turtle', 'turtle added'); + map.attr('animals', new DefineList([ + 'sloth', + 'bear', + 'turtle' + ])); + var spans = div.getElementsByTagName('span'); + assert.equal(spans.length, 3, 'there are 3 spans'); + assert.ok(!div.getElementsByTagName('label')[0].myexpando, 'no expando'); + }); + QUnit.test('no memory leaks', function (assert) { + var div = document.createElement('div'), map = new SimpleMap({ + animals: new DefineList([ + 'bear', + 'turtle' + ]) + }), template = function (animal) { + return ' ' + animal.get() + ''; + }; + var listObservation = new Observation(function () { + return map.attr('animals'); + }); + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + this.fixture.appendChild(div); + var fixture = this.fixture; + live.list(el, listObservation, template, {}); + var done = assert.async(); + function checkHandlers() { + var handlers = map[canSymbol.for('can.meta')].handlers.get([]); + if (handlers.length === 0) { + assert.equal(handlers.length, 0, 'there are no bindings'); + done(); + } else { + setTimeout(checkHandlers, 10); + } + } + setTimeout(function () { + domMutateNode.removeChild.call(fixture, div); + afterMutation(checkHandlers); + }, 10); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(2); + var div = document.createElement('div'); + div.innerHTML = 'my fav animals: !'; + document.body.appendChild(div); + var el = div.getElementsByTagName('span')[0]; + var list = new DefineList([ + 'sloth', + 'bear' + ]); + var template = function (animal) { + return ' ' + animal.get() + ''; + }; + live.list(el, list, template, {}); + var placeholder = div.childNodes[3]; + assert.deepEqual(canReflectDeps.getDependencyDataOf(placeholder).whatChangesMe.mutate.valueDependencies, new Set([list])); + var undo = domMutate.onNodeDisconnected(div, function checkTeardown() { + undo(); + setTimeout(function () { + assert.equal(typeof canReflectDeps.getDependencyDataOf(placeholder), 'undefined', 'dependencies should be cleared when parent node is removed'); + done(); + }, 10); + }); + domMutateNode.removeChild.call(div.parentNode, div); + }); + QUnit.test('Undefined list and teardown', function (assert) { + var div = document.createElement('div'), map = new SimpleMap({ items: undefined }), template = function () { + return ''; + }; + var listObservation = new Observation(function () { + return map.attr('items'); + }); + div.innerHTML = 'my fav animals: !'; + var el = div.getElementsByTagName('span')[0]; + this.fixture.appendChild(div); + var fixture = this.fixture; + live.list(el, listObservation, template, {}); + var done = assert.async(); + function checkHandlers() { + assert.ok(true, 'was able to teardown'); + done(); + } + setTimeout(function () { + domMutateNode.removeChild.call(fixture, div); + afterMutation(checkHandlers); + }, 10); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-live@5.0.4#test/text-test*/ +define('can-view-live@5.0.4#test/text-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-observation', + 'steal-qunit', + 'can-simple-observable', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-test-helpers', + 'can-reflect-dependencies', + 'can-globals', + 'can-reflect' +], function (require, exports, module) { + (function (global, require, exports, module) { + var live = require('can-view-live'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SimpleObservable = require('can-simple-observable'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var testHelpers = require('can-test-helpers'); + var canReflectDeps = require('can-reflect-dependencies'); + var canGlobals = require('can-globals'); + var canReflect = require('can-reflect'); + QUnit.module('can-view-live.text', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + var afterMutation = function (cb) { + var doc = canGlobals.getKeyValue('document'); + var div = doc.createElement('div'); + var insertionDisposal = domMutate.onNodeInsertion(div, function () { + insertionDisposal(); + doc.body.removeChild(div); + setTimeout(cb, 5); + }); + setTimeout(function () { + domMutateNode.appendChild.call(doc.body, div); + }, 10); + }; + var esc = function (str) { + return str.replace(//g, '>'); + }; + QUnit.test('text', function (assert) { + var div = document.createElement('div'), span = document.createElement('span'); + div.appendChild(span); + var value = new SimpleObservable([ + 'one', + 'two' + ]); + var text = new Observation(function html() { + var html = ''; + value.get().forEach(function (item) { + html += ''; + }); + return html; + }); + live.text(span, text); + assert.equal(div.innerHTML, esc('')); + value.set([ + 'one', + 'two', + 'three' + ]); + assert.equal(div.innerHTML, esc('')); + }); + QUnit.test('text binding is memory safe (#666)', function (assert) { + var div = document.createElement('div'), span = document.createElement('span'), text = new Observation(function () { + return 'foo'; + }); + div.appendChild(span); + domMutateNode.appendChild.call(this.fixture, div); + live.text(span, text); + domMutateNode.removeChild.call(this.fixture, div); + var done = assert.async(); + setTimeout(function () { + assert.notOk(canReflect.isBound(text), 'not bound'); + done(); + }, 100); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(3); + var div = document.createElement('div'); + var placeholder = document.createTextNode(''); + div.appendChild(placeholder); + document.body.appendChild(div); + var value = new SimpleObservable([ + 'one', + 'two' + ]); + var text = new Observation(function html() { + return value.get().map(function (item) { + return ''; + }).join(''); + }); + live.text(placeholder, text); + assert.deepEqual(canReflectDeps.getDependencyDataOf(placeholder).whatChangesMe.mutate.valueDependencies, new Set([text]), 'whatChangesMe(
      ) shows the observation'); + assert.deepEqual(canReflectDeps.getDependencyDataOf(text).whatIChange.mutate.valueDependencies, new Set([placeholder]), 'whatChangesMe(observation) shows the PlaceHolder node'); + var undo = domMutate.onNodeDisconnected(div, function checkTeardown() { + undo(); + setTimeout(function () { + assert.equal(typeof canReflectDeps.getDependencyDataOf(placeholder), 'undefined', 'dependencies should be clear out when elements is removed'); + done(); + }, 10); + }); + domMutateNode.removeChild.call(div.parentNode, div); + }); + QUnit.test('Live binding is restored when the text node is reconnected', function (assert) { + var done = assert.async(); + var div = document.createElement('div'), textNode = document.createTextNode(''); + this.fixture.appendChild(div); + div.appendChild(textNode); + var value = new SimpleObservable('one'); + live.text(textNode, value); + assert.equal(div.innerHTML, 'one'); + div.appendChild(textNode); + afterMutation(function () { + value.set('two'); + assert.equal(div.innerHTML, 'two'); + div.removeChild(textNode); + afterMutation(function () { + value.set('three'); + assert.equal(textNode.nodeValue, 'two'); + div.appendChild(textNode); + afterMutation(function () { + assert.equal(div.innerHTML, 'three'); + value.set('four'); + assert.equal(div.innerHTML, 'four'); + done(); + }); + }); + }); + }); + QUnit.test('Removing the documentElement tears down correctly', function (assert) { + var done = assert.async(); + assert.expect(1); + var realDoc = canGlobals.getKeyValue('document'); + var doc = document.implementation.createHTMLDocument('testing'); + canGlobals.setKeyValue('document', doc); + var tn = doc.createTextNode('foo'); + domMutate.onNodeDisconnected(doc.body, function () { + canGlobals.setKeyValue('document', realDoc); + assert.ok(true, 'Removal fired'); + done(); + }); + var text = new Observation(function () { + return 'foo'; + }); + domMutateNode.appendChild.call(doc.body, tn); + live.text(tn, text); + domMutateNode.removeChild.call(doc, doc.documentElement); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-live@5.0.4#test/attr-test*/ +define('can-view-live@5.0.4#test/attr-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-observation', + 'steal-qunit', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-simple-observable', + 'can-test-helpers', + 'can-reflect-dependencies' +], function (require, exports, module) { + var live = require('can-view-live'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var SimpleObservable = require('can-simple-observable'); + var testHelpers = require('can-test-helpers'); + var canReflectDeps = require('can-reflect-dependencies'); + QUnit.module('can-view-live.attr', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('basics', function (assert) { + var div = document.createElement('div'); + var firstValue = new SimpleObservable(null); + var first = new Observation(function () { + return firstValue.get() ? 'selected' : ''; + }); + var secondValue = new SimpleObservable(null); + var second = new Observation(function () { + return secondValue.get() ? 'active' : ''; + }); + var className = new Observation(function () { + return 'foo ' + first.get() + ' ' + second.get() + ' end'; + }); + live.attr(div, 'class', className); + assert.equal(div.className, 'foo end'); + firstValue.set(true); + assert.equal(div.className, 'foo selected end'); + secondValue.set(true); + assert.equal(div.className, 'foo selected active end'); + firstValue.set(false); + assert.equal(div.className, 'foo active end'); + }); + QUnit.test('specialAttribute with new line', function (assert) { + var div = document.createElement('div'); + var style = new SimpleObservable('width: 50px;\nheight:50px;'); + live.attr(div, 'style', style); + assert.equal(div.style.height, '50px'); + assert.equal(div.style.width, '50px'); + }); + QUnit.test('can.live.attr works with non-string attributes (#1790)', function (assert) { + var el = document.createElement('div'), attrCompute = new Observation(function () { + return 2; + }); + domMutateNode.setAttribute.call(el, 'value', 1); + live.attr(el, 'value', attrCompute); + assert.ok(true, 'No exception thrown.'); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(4); + var div = document.createElement('div'); + document.body.appendChild(div); + var id = new SimpleObservable('foo'); + var title = new SimpleObservable('something'); + live.attr(div, 'id', id); + live.attr(div, 'title', title); + assert.deepEqual(canReflectDeps.getDependencyDataOf(div).whatChangesMe.mutate.valueDependencies, new Set([ + id, + title + ]), 'getDependencyDataOf(
      ) should return the two SimpleObservables as dependencies'); + console.log(canReflectDeps.getDependencyDataOf(id)); + assert.deepEqual(canReflectDeps.getDependencyDataOf(id).whatIChange.mutate.valueDependencies, new Set([div]), 'getDependencyDataOf(id) should return the
      as a dependency'); + assert.deepEqual(canReflectDeps.getDependencyDataOf(title).whatIChange.mutate.valueDependencies, new Set([div]), 'getDependencyDataOf(title) should return the
      as a dependency'); + var undo = domMutate.onNodeDisconnected(div, function checkTeardown() { + undo(); + assert.equal(typeof canReflectDeps.getDependencyDataOf(div), 'undefined', 'dependencies should be cleared out when elements is removed'); + done(); + }); + domMutateNode.removeChild.call(div.parentNode, div); + }); + QUnit.test('can.live.attr works with value (#96)', function (assert) { + var el = document.createElement('input'), attrObservable = new SimpleObservable('Hello'); + live.attr(el, 'value', attrObservable); + assert.equal(el.value, 'Hello', 'Hello'); + attrObservable.set('Hi'); + assert.equal(el.value, 'Hi', 'Hi'); + el.value = 'Hey'; + assert.equal(el.value, 'Hey', 'Hey'); + attrObservable.set('Aloha'); + assert.equal(el.value, 'Aloha', 'Aloha'); + }); +}); +/*can-view-live@5.0.4#test/attrs-test*/ +define('can-view-live@5.0.4#test/attrs-test', [ + 'require', + 'exports', + 'module', + 'can-view-live', + 'can-observation', + 'steal-qunit', + 'can-simple-observable', + 'can-queues', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-test-helpers', + 'can-reflect-dependencies' +], function (require, exports, module) { + var live = require('can-view-live'); + var Observation = require('can-observation'); + var QUnit = require('steal-qunit'); + var SimpleObservable = require('can-simple-observable'); + var queues = require('can-queues'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var testHelpers = require('can-test-helpers'); + var canReflectDeps = require('can-reflect-dependencies'); + QUnit.module('can-view-live.attrs', { + beforeEach: function () { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('basics', function (assert) { + var div = document.createElement('div'); + var property = new SimpleObservable('class'), value = new SimpleObservable('foo'); + var text = new Observation(function () { + var html = ''; + if (property.get() && value.get()) { + html += property.get() + '=\'' + value.get() + '\''; + } + return html; + }); + live.attrs(div, text); + assert.equal(div.className, 'foo'); + property.set(null); + assert.equal(div.className, ''); + queues.batch.start(); + property.set('foo'); + value.set('bar'); + queues.batch.stop(); + assert.equal(div.getAttribute('foo'), 'bar'); + }); + QUnit.test('should remove `removed` events listener', function (assert) { + var done = assert.async(); + var onNodeRemoved = domMutate.onNodeRemoved; + domMutate.onNodeRemoved = function () { + assert.ok(true, 'addEventListener called'); + var disposal = onNodeRemoved.apply(null, arguments); + domMutate.onNodeRemoved = onNodeRemoved; + return function () { + assert.ok(true, 'disposal function was called'); + disposal(); + done(); + }; + }; + var div = document.createElement('div'); + var text = new SimpleObservable('hello'); + domMutateNode.appendChild.call(this.fixture, div); + live.attrs(div, text); + domMutateNode.removeChild.call(this.fixture, div); + }); + testHelpers.dev.devOnlyTest('can-reflect-dependencies', function (assert) { + var done = assert.async(); + assert.expect(3); + var div = document.createElement('div'); + document.body.appendChild(div); + var attr = new SimpleObservable('class'); + var value = new SimpleObservable('foo'); + var text = new Observation(function () { + var html = ''; + if (attr.get() && value.get()) { + html += attr.get() + '="' + value.get() + '"'; + } + return html; + }); + live.attrs(div, text); + assert.deepEqual(canReflectDeps.getDependencyDataOf(div).whatChangesMe.mutate.valueDependencies, new Set([text]), 'getDependencyDataOf(
      ) should return the observation as a dependency'); + assert.deepEqual(canReflectDeps.getDependencyDataOf(text).whatIChange.mutate.valueDependencies, new Set([div]), 'getDependencyDataOf(observation) should return the div as a dependency'); + var undo = domMutate.onNodeDisconnected(div, function checkTeardown() { + undo(); + assert.equal(typeof canReflectDeps.getDependencyDataOf(div), 'undefined', 'dependencies should be cleared out when element is removed'); + done(); + }); + domMutateNode.removeChild.call(div.parentNode, div); + }); +}); +/*can-view-live@5.0.4#test/test*/ +define('can-view-live@5.0.4#test/test', [ + 'require', + 'exports', + 'module', + './html-test', + './patcher-test', + './list-test', + './text-test', + './attr-test', + './attrs-test' +], function (require, exports, module) { + require('./html-test'); + require('./patcher-test'); + require('./list-test'); + require('./text-test'); + require('./attr-test'); + require('./attrs-test'); +}); +/*can-view-model@4.0.3#can-view-model_test*/ +define('can-view-model@4.0.3#can-view-model_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-view-model', + 'can-simple-map' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var viewModel = require('can-view-model'); + var SimpleMap = require('can-simple-map'); + QUnit.module('can-view-model'); + QUnit.test('basics', function (assert) { + var el = document.createElement('div'); + viewModel(el, 'foo', 'bar'); + assert.equal(viewModel(el, 'foo'), 'bar'); + assert.ok(viewModel(el) instanceof SimpleMap, 'is SimpleMap'); + }); + QUnit.test('a selector can be passed as the first argument (#6)', function (assert) { + var el = document.createElement('div'); + el.className = 'the-el'; + document.getElementById('qunit-fixture').appendChild(el); + viewModel('.the-el', 'foo', 'bar'); + assert.equal(viewModel('.the-el', 'foo'), 'bar'); + assert.ok(viewModel(el) instanceof SimpleMap, 'is can-map'); + }); + QUnit.test('set custom can-simple-map on element (#5)', function (assert) { + var vm, elVm; + var CustomMap = SimpleMap.extend({}); + var el = document.createElement('div'); + document.getElementById('qunit-fixture').appendChild(el); + vm = new CustomMap({ foo: 'bar' }); + elVm = viewModel(el, vm); + assert.equal(viewModel(el, 'foo'), 'bar'); + }); + QUnit.test('Allow passing array like (jQuery) element', function (assert) { + var $el = {}; + var el = document.createElement('div'); + el.className = 'the-el'; + $el[0] = el; + $el.length = 1; + document.getElementById('qunit-fixture').appendChild(el); + viewModel($el, 'foo', 'bar'); + assert.equal(viewModel('.the-el', 'foo'), 'bar', 'It reads view scope from html element'); + assert.equal(viewModel($el, 'foo'), 'bar', 'It reads view scope from array like (jQuery) element'); + assert.ok(viewModel(el) instanceof SimpleMap, 'is can-map'); + }); + QUnit.test('elements with length property not treated as arraylikes (#31)', function (assert) { + var el = document.createElement('select'); + document.getElementById('qunit-fixture').appendChild(el); + assert.equal(el.length, 0, 'Select has length property (0 for empty)'); + assert.deepEqual(viewModel(el).get(), {}, 'viewModel created on empty select'); + var opt = document.createElement('option'); + el.appendChild(opt); + assert.equal(el.length, 1, 'Select has length 1'); + assert.deepEqual(viewModel(el).get(), {}, 'viewModel created on non-empty select'); + }); +}); +/*can-view-model@4.0.3#test/test*/ +define('can-view-model@4.0.3#test/test', [ + 'require', + 'exports', + 'module', + '../can-view-model_test' +], function (require, exports, module) { + require('../can-view-model_test'); +}); +/*can-view-parser@4.1.3#test/can-view-parser-test*/ +define('can-view-parser@4.1.3#test/can-view-parser-test', [ + 'require', + 'exports', + 'module', + 'can-view-parser', + 'steal-qunit', + 'can-log/dev/dev', + 'can-attribute-encoder', + 'can-test-helpers' +], function (require, exports, module) { + var parser = require('can-view-parser'); + var QUnit = require('steal-qunit'); + var canDev = require('can-log/dev/dev'); + var encoder = require('can-attribute-encoder'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-view-parser'); + var makeChecks = function (assert, tests) { + var count = 0; + var makeCheck = function (name) { + return function () { + if (count >= tests.length) { + assert.ok(false, 'called ' + name + ' with ' + JSON.stringify([].slice.call(arguments))); + } else { + var test = tests[count], args = test[1]; + assert.equal(name, test[0], 'test ' + count + ' ' + name + '('); + for (var i = 0; i < args.length; i++) { + assert.equal(arguments[i], args[i], i + 1 + ' arg -> ' + args[i]); + } + count++; + } + }; + }; + return { + start: makeCheck('start'), + end: makeCheck('end'), + close: makeCheck('close'), + attrStart: makeCheck('attrStart'), + attrEnd: makeCheck('attrEnd'), + attrValue: makeCheck('attrValue'), + chars: makeCheck('chars'), + comment: makeCheck('comment'), + special: makeCheck('special'), + done: makeCheck('done') + }; + }; + QUnit.test('html to html', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['id'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['id'] + ], + [ + 'special', + ['#if'] + ], + [ + 'special', + ['.'] + ], + [ + 'special', + ['/if'] + ], + [ + 'attrStart', + ['class'] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'special', + ['foo'] + ], + [ + 'attrEnd', + ['class'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['Hello '] + ], + [ + 'special', + ['message'] + ], + [ + 'chars', + ['!'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      Hello {{message}}!

      ', makeChecks(assert, tests)); + }); + QUnit.test('uppercase html to html', function (assert) { + var tests = [ + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'chars', + ['sibling'] + ], + [ + 'close', + ['div'] + ], + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'chars', + ['sibling'] + ], + [ + 'close', + ['div'] + ], + [ + 'done', + [] + ] + ]; + parser('
      sibling
      sibling
      ', makeChecks(assert, tests)); + }); + QUnit.test('camelCase attributes stay untouched (svg) - #22', function (assert) { + var tests = [ + [ + 'start', + [ + 'svg', + false + ] + ], + [ + 'attrStart', + ['viewBox'] + ], + [ + 'attrValue', + ['0 0 15 22'] + ], + [ + 'attrEnd', + ['viewBox'] + ], + [ + 'end', + [ + 'svg', + false + ] + ], + [ + 'close', + ['svg'] + ], + [ + 'done', + [] + ] + ]; + parser('', makeChecks(assert, tests)); + }); + QUnit.test('camelCase tags stay untouched (svg)', function (assert) { + var tests = [ + [ + 'start', + [ + 'svg', + false + ] + ], + [ + 'end', + [ + 'svg', + false + ] + ], + [ + 'start', + [ + 'radialGradient', + false + ] + ], + [ + 'end', + [ + 'radialGradient', + false + ] + ], + [ + 'close', + ['radialGradient'] + ], + [ + 'close', + ['svg'] + ], + [ + 'done', + [] + ] + ]; + parser('', makeChecks(assert, tests)); + }); + QUnit.test('special in an attribute in an in-tag section', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'special', + ['#truthy'] + ], + [ + 'attrStart', + ['foo'] + ], + [ + 'special', + ['baz'] + ], + [ + 'attrEnd', + ['foo'] + ], + [ + 'special', + ['/truthy'] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('special with a custom attribute', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'special', + ['#attribute'] + ], + [ + 'special', + ['name'] + ], + [ + 'attrStart', + [''] + ], + [ + 'special', + ['value'] + ], + [ + 'attrEnd', + [''] + ], + [ + 'special', + ['/attribute'] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('single attribute value', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'input', + true + ] + ], + [ + 'attrStart', + ['DISABLED'] + ], + [ + 'attrEnd', + ['DISABLED'] + ], + [ + 'end', + [ + 'input', + true + ] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('trailing linebreaks in IE', function (assert) { + parser('12345{{!\n This is a\n multi-line comment...\n}}67890\n', makeChecks(assert, [ + [ + 'chars', + ['12345'] + ], + [ + 'special', + ['!\n This is a\n multi-line comment...\n'] + ], + [ + 'chars', + ['67890\n'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('block are allowed inside anchor tags', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'a', + false + ] + ], + [ + 'end', + [ + 'a', + false + ] + ], + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'close', + ['a'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('anchors are allowed as children of inline elements - #2169', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'span', + false + ] + ], + [ + 'end', + [ + 'span', + false + ] + ], + [ + 'start', + [ + 'a', + false + ] + ], + [ + 'end', + [ + 'a', + false + ] + ], + [ + 'close', + ['a'] + ], + [ + 'close', + ['span'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('inline tags encapsulate inner block elements', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'span', + false + ] + ], + [ + 'end', + [ + 'span', + false + ] + ], + [ + 'start', + [ + 'div', + false + ] + ], + [ + 'end', + [ + 'div', + false + ] + ], + [ + 'close', + ['div'] + ], + [ + 'close', + ['span'] + ], + [ + 'done', + [] + ] + ])); + parser('

      ', makeChecks(assert, [ + [ + 'start', + [ + 'em', + false + ] + ], + [ + 'end', + [ + 'em', + false + ] + ], + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'close', + ['em'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('unordered lists will contain their list items', function (assert) { + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'ul', + false + ] + ], + [ + 'end', + [ + 'ul', + false + ] + ], + [ + 'start', + [ + 'li', + false + ] + ], + [ + 'end', + [ + 'li', + false + ] + ], + [ + 'close', + ['li'] + ], + [ + 'start', + [ + 'li', + false + ] + ], + [ + 'end', + [ + 'li', + false + ] + ], + [ + 'close', + ['li'] + ], + [ + 'close', + ['ul'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('supports single character attributes (#1132)', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'circle', + false + ] + ], + [ + 'attrStart', + ['r'] + ], + [ + 'attrValue', + ['25'] + ], + [ + 'attrEnd', + ['r'] + ], + [ + 'end', + [ + 'circle', + false + ] + ], + [ + 'close', + ['circle'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('accept custom tag with colon ":" #1108', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'x:widget', + true + ] + ], + [ + 'end', + [ + 'x:widget', + true + ] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('output json', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['id'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['id'] + ], + [ + 'special', + ['#if'] + ], + [ + 'special', + ['.'] + ], + [ + 'special', + ['/if'] + ], + [ + 'attrStart', + ['class'] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'special', + ['foo'] + ], + [ + 'attrEnd', + ['class'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['Hello '] + ], + [ + 'special', + ['message'] + ], + [ + 'chars', + ['!'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + var intermediate = parser('

      Hello {{message}}!

      ', makeChecks(assert, tests), true); + parser(intermediate, makeChecks(assert, tests)); + }); + QUnit.test('less than outside of an element', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + [' < '] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + var intermediate = parser('

      <

      ', makeChecks(assert, tests), true); + parser(intermediate, makeChecks(assert, tests)); + }); + QUnit.test('allow () and [] to enclose attributes', function (assert) { + parser('

      ', makeChecks(assert, [ + [ + 'start', + [ + 'p', + false + ] + ], + [ + 'attrStart', + ['[click]'] + ], + [ + 'attrValue', + ['test'] + ], + [ + 'attrEnd', + ['[click]'] + ], + [ + 'end', + ['p'] + ], + [ + 'close', + ['p'] + ], + [ + 'done', + [] + ] + ])); + parser('

      ', makeChecks(assert, [ + [ + 'start', + [ + 'p', + false + ] + ], + [ + 'attrStart', + [encoder.encode('(click)')] + ], + [ + 'attrValue', + ['test'] + ], + [ + 'attrEnd', + [encoder.encode('(click)')] + ], + [ + 'end', + ['p'] + ], + [ + 'close', + ['p'] + ], + [ + 'done', + [] + ] + ])); + parser('

      ', makeChecks(assert, [ + [ + 'start', + [ + 'p', + false + ] + ], + [ + 'attrStart', + [encoder.encode('(click-me)')] + ], + [ + 'attrValue', + ['test'] + ], + [ + 'attrEnd', + [encoder.encode('(click-me)')] + ], + [ + 'end', + ['p'] + ], + [ + 'close', + ['p'] + ], + [ + 'done', + [] + ] + ])); + parser('

      ', makeChecks(assert, [ + [ + 'start', + [ + 'p', + false + ] + ], + [ + 'attrStart', + [encoder.encode('(click_me)')] + ], + [ + 'attrValue', + ['test'] + ], + [ + 'attrEnd', + [encoder.encode('(click_me)')] + ], + [ + 'end', + ['p'] + ], + [ + 'close', + ['p'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('allow {} to enclose attributes', function (assert) { + parser.parseAttrs('{a}="b" {{#c}}d{{/c}}', makeChecks(assert, [ + [ + 'attrStart', + [encoder.encode('{a}')] + ], + [ + 'attrValue', + ['b'] + ], + [ + 'attrEnd', + [encoder.encode('{a}')] + ], + [ + 'special', + ['#c'] + ], + [ + 'attrStart', + ['d'] + ], + [ + 'attrEnd', + ['d'] + ], + [ + 'special', + ['/c'] + ] + ])); + }); + QUnit.test('tripple curly in attrs', function (assert) { + parser.parseAttrs('items="{{{ completed }}}"', makeChecks(assert, [ + [ + 'attrStart', + ['items'] + ], + [ + 'special', + ['{ completed '] + ], + [ + 'attrEnd', + ['items'] + ] + ])); + }); + QUnit.test('something', function (assert) { + parser.parseAttrs('c d=\'e\'', makeChecks(assert, [ + [ + 'attrStart', + ['c'] + ], + [ + 'attrEnd', + ['c'] + ], + [ + 'attrStart', + ['d'] + ], + [ + 'attrValue', + ['e'] + ], + [ + 'attrEnd', + ['d'] + ] + ])); + }); + QUnit.test('references', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'year-selector', + true + ] + ], + [ + 'attrStart', + ['*y'] + ], + [ + 'attrEnd', + ['*y'] + ], + [ + 'end', + ['year-selector'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('quotes around attributes and other lazy attribute writing (#2097)', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'c-d', + true + ] + ], + [ + 'attrStart', + ['a'] + ], + [ + 'attrValue', + ['{z}'] + ], + [ + 'attrEnd', + ['a'] + ], + [ + 'end', + ['c-d'] + ], + [ + 'done', + [] + ] + ])); + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'span', + true + ] + ], + [ + 'attrStart', + ['v'] + ], + [ + 'special', + ['.'] + ], + [ + 'attrEnd', + ['v'] + ], + [ + 'end', + ['span'] + ], + [ + 'done', + [] + ] + ])); + parser('
      ', makeChecks(assert, [ + [ + 'start', + [ + 'div', + true + ] + ], + [ + 'special', + ['^f'] + ], + [ + 'attrStart', + ['d'] + ], + [ + 'attrEnd', + ['d'] + ], + [ + 'special', + ['/f'] + ], + [ + 'end', + ['div'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('camelCased attributes are converted to spinal-case', function (assert) { + parser.parseAttrs('({camelCase})=\'assigned\'', makeChecks(assert, [ + [ + 'attrStart', + [encoder.encode('({camelCase})')] + ], + [ + 'attrValue', + ['assigned'] + ], + [ + 'attrEnd', + [encoder.encode('({camelCase})')] + ] + ])); + }); + QUnit.test('elements that have attributes with equal signs and no values are handled appropriately (#17)', function (assert) { + parser('', makeChecks(assert, [ + [ + 'start', + [ + 'input', + true + ] + ], + [ + 'attrStart', + ['class'] + ], + [ + 'attrValue', + ['toggle'] + ], + [ + 'attrEnd', + ['class'] + ], + [ + 'attrStart', + ['type'] + ], + [ + 'attrValue', + ['checkbox'] + ], + [ + 'attrEnd', + ['type'] + ], + [ + 'attrStart', + [encoder.encode('{($checked)}')] + ], + [ + 'attrValue', + ['complete'] + ], + [ + 'attrEnd', + [encoder.encode('{($checked)}')] + ], + [ + 'attrStart', + [encoder.encode('($change)')] + ], + [ + 'attrEnd', + [encoder.encode('($change)')] + ], + [ + 'end', + ['input'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('{{}} in attribute values are handled correctly (#34)', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['class'] + ], + [ + 'special', + ['foo'] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + ['class'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(assert, tests)); + }); + QUnit.test('> in attribute values are handled correctly', function (assert) { + parser('

      bar

      ', makeChecks(assert, [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['data-content'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['data-content'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['bar'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ])); + parser('

      bar

      ', makeChecks(assert, [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['data-nothing'] + ], + [ + 'attrEnd', + ['data-nothing'] + ], + [ + 'attrStart', + ['data-something'] + ], + [ + 'attrValue', + ['something'] + ], + [ + 'attrEnd', + ['data-something'] + ], + [ + 'attrStart', + ['data-content'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['data-content'] + ], + [ + 'attrStart', + ['data-something-after'] + ], + [ + 'attrValue', + ['something-after'] + ], + [ + 'attrEnd', + ['data-something-after'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['bar'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ])); + parser('

      \nbar

      ', makeChecks(assert, [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + ['data-first'] + ], + [ + 'attrValue', + ['foo'] + ], + [ + 'attrEnd', + ['data-first'] + ], + [ + 'attrStart', + ['data-second'] + ], + [ + 'attrValue', + ['><>>>>>>>/>> \n />'] + ], + [ + 'attrEnd', + ['data-second'] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['\nbar'] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('tags with data attributes are allowed in comments (#2)', function (assert) { + parser('{{! foo }}', makeChecks(assert, [ + [ + 'special', + ['! foo '] + ], + [ + 'done', + [] + ] + ])); + parser('{{! }}', makeChecks(assert, [ + [ + 'special', + ['! '] + ], + [ + 'done', + [] + ] + ])); + parser('{{! }}', makeChecks(assert, [ + [ + 'special', + ['! '] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('multiline special comments (#14)', function (assert) { + parser('{{! foo !}}', makeChecks(assert, [ + [ + 'special', + ['! foo !'] + ], + [ + 'done', + [] + ] + ])); + parser('{{! {{foo}} {{bar}} !}}', makeChecks(assert, [ + [ + 'special', + ['! {{foo}} {{bar}} !'] + ], + [ + 'done', + [] + ] + ])); + parser('{{!\n{{foo}}\n{{bar}}\n!}}', makeChecks(assert, [ + [ + 'special', + ['!\n{{foo}}\n{{bar}}\n!'] + ], + [ + 'done', + [] + ] + ])); + }); + QUnit.test('spaces in attribute names that start with `{` or `(` are encoded (#48)', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('{foo bar}')] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + [encoder.encode('{foo bar}')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(assert, tests)); + }); + QUnit.test('for attributes without values, spaces in attribute names that start with `{` or `(` are encoded (#48)', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('{foo }')] + ], + [ + 'attrEnd', + [encoder.encode('{foo }')] + ], + [ + 'attrStart', + [encoder.encode('{bar }')] + ], + [ + 'attrEnd', + [encoder.encode('{bar }')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(assert, tests)); + }); + QUnit.test('mismatched brackets work: {(foo})', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('{(foo})')] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + [encoder.encode('{(foo})')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(assert, tests)); + }); + QUnit.test('mismatched brackets work: ({foo)}', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('({foo)}')] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + [encoder.encode('({foo)}')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(assert, tests)); + }); + QUnit.test('forward slashes are encoded (#52)', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('{foo/bar}')] + ], + [ + 'attrValue', + ['a'] + ], + [ + 'attrEnd', + [encoder.encode('{foo/bar}')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(assert, tests)); + }); + QUnit.test('camelCase properties are encoded with on:, :to, :from, :bind bindings', function (assert) { + var tests = [ + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'attrStart', + [encoder.encode('on:aB')] + ], + [ + 'attrValue', + ['c'] + ], + [ + 'attrEnd', + [encoder.encode('on:aB')] + ], + [ + 'attrStart', + [encoder.encode('dE:to')] + ], + [ + 'attrValue', + ['f'] + ], + [ + 'attrEnd', + [encoder.encode('dE:to')] + ], + [ + 'attrStart', + [encoder.encode('gH:from')] + ], + [ + 'attrValue', + ['i'] + ], + [ + 'attrEnd', + [encoder.encode('gH:from')] + ], + [ + 'attrStart', + [encoder.encode('jK:bind')] + ], + [ + 'attrValue', + ['l'] + ], + [ + 'attrEnd', + [encoder.encode('jK:bind')] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'close', + ['h1'] + ], + [ + 'done', + [] + ] + ]; + parser('

      ', makeChecks(assert, tests)); + }); + testHelpers.dev.devOnlyTest('Warn on missing attribute value end quotes (canjs/can-view-parser#7)', function (assert) { + var makeWarnChecks = function (input, texts) { + var count = 0; + var teardown = testHelpers.dev.willWarn(/End quote is missing for/, function (message, matched) { + assert.ok(matched, texts[count++]); + }); + parser(input, { + start: function (tagName, unary) { + }, + end: function (tagName, unary) { + }, + attrStart: function (attrName) { + }, + attrEnd: function (attrName) { + }, + attrValue: function (val) { + }, + done: function () { + } + }); + assert.equal(count, teardown()); + }; + makeWarnChecks('', ['1: End quote is missing for callback']); + makeWarnChecks('', ['1: End quote is missing for current-page']); + makeWarnChecks('
      ', ['1: End quote is missing for current-page']); + makeWarnChecks('', ['1: End quote is missing for current-page']); + }); + QUnit.test('TextNodes are not inserted before the or after the ', function (assert) { + var tests = [ + [ + 'start', + [ + 'html', + false + ] + ], + [ + 'end', + [ + 'html', + false + ] + ], + [ + 'start', + [ + 'head', + false + ] + ], + [ + 'end', + [ + 'head', + false + ] + ], + [ + 'chars', + ['\n\t\t'] + ], + [ + 'start', + [ + 'title', + false + ] + ], + [ + 'end', + [ + 'title', + false + ] + ], + [ + 'chars', + ['Test'] + ], + [ + 'close', + ['title'] + ], + [ + 'chars', + ['\n\t\t'] + ], + [ + 'close', + ['head'] + ], + [ + 'chars', + ['\n\t'] + ], + [ + 'start', + [ + 'body', + false + ] + ], + [ + 'end', + [ + 'body', + false + ] + ], + [ + 'chars', + ['\n\t\t'] + ], + [ + 'start', + [ + 'h1', + false + ] + ], + [ + 'end', + [ + 'h1', + false + ] + ], + [ + 'chars', + ['Test'] + ], + [ + 'close', + ['h1'] + ], + [ + 'chars', + ['\n\t'] + ], + [ + 'close', + ['body'] + ], + [ + 'close', + ['html'] + ], + [ + 'done', + [] + ] + ]; + var html = '\n\t\n\t\tTest\n\t\t\n\t\n\t\t

      Test

      \n\t\n'; + parser(html, makeChecks(assert, tests)); + }); +}); +/*can-view-scope@4.13.6#test/variable-scope-test*/ +define('can-view-scope@4.13.6#test/variable-scope-test', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'steal-qunit', + 'can-simple-map', + 'can-reflect' +], function (require, exports, module) { + var Scope = require('can-view-scope'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var canReflect = require('can-reflect'); + QUnit.module('can-view-scope variable scope'); + QUnit.test('reading', function (assert) { + var root = { + rootProp: 'ROOT', + conflictProp: 'ROOT' + }; + var scope = new Scope(root).add({ + variableProp: 'VARIABLE', + conflictProp: 'VARIABLE' + }, { variable: true }); + assert.equal(scope.get('variableProp'), 'VARIABLE', 'can read a variable'); + assert.equal(scope.get('this.rootProp'), 'ROOT', 'can pass variables for the root'); + assert.equal(scope.get('this.conflictProp'), 'ROOT', 'this.conflictProp'); + assert.equal(scope.get('./conflictProp'), 'ROOT', './conflictProp'); + assert.equal(scope.get('conflictProp'), 'VARIABLE', 'conflictProp'); + assert.equal(scope.get('this'), root, 'this is right'); + var root2 = { + root2Prop: 'ROOT2', + conflictProp: 'ROOT2' + }; + var scope2 = new Scope(root).add(root2).add({ + variableProp: 'VARIABLE', + conflictProp: 'VARIABLE' + }, { variable: true }); + assert.equal(scope2.get('variableProp'), 'VARIABLE', 'can read a variable'); + assert.equal(scope2.get('this.root2Prop'), 'ROOT2', 'can pass variables for the root 2'); + assert.equal(scope2.get('this.conflictProp'), 'ROOT2', 'this.conflictProp'); + assert.equal(scope2.get('./conflictProp'), 'ROOT2', './conflictProp'); + assert.equal(scope2.get('conflictProp'), 'VARIABLE', 'conflictProp'); + assert.equal(scope2.get('../conflictProp'), 'ROOT', '../conflictProp'); + var root3 = { + root3Prop: 'ROOT3', + conflictProp: 'ROOT3' + }; + var scope3 = new Scope(root).add(root2).add(root3).add({ + variableProp: 'VARIABLE', + conflictProp: 'VARIABLE' + }, { variable: true }); + assert.equal(scope3.get('../../conflictProp'), 'ROOT', '../../conflictProp'); + }); + QUnit.test('writing', function (assert) { + var root = new SimpleMap({ name: 'ROOT' }); + var scope; + scope = new Scope(root).addLetContext(); + scope.set('rootProp', 'VALUE'); + assert.equal(root.get('rootProp'), 'VALUE', 'wrote to property with .set'); + var rootProp = scope.computeData('rootProp2'); + canReflect.setValue(rootProp, 'VALUE2'); + assert.equal(root.get('rootProp2'), 'VALUE2', 'wrote property by setting ScopeKeyData'); + var rootProp3 = scope.computeData('rootProp3'); + canReflect.onValue(rootProp3, function () { + }); + canReflect.setValue(rootProp3, 'VALUE3'); + assert.equal(root.get('rootProp3'), 'VALUE3', 'wrote to property by setting bound ScopeKeyData'); + scope = new Scope(root).addLetContext({ tempProp: undefined }); + scope.set('tempProp', 'foo'); + assert.equal(root.get('tempProp'), undefined, 'write to undefined not set on root'); + assert.equal(scope.get('tempProp'), 'foo', 'able to read from root'); + }); +}); +/*can-view-scope@4.13.6#test/scope-set-test*/ +define('can-view-scope@4.13.6#test/scope-set-test', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'steal-qunit', + 'can-test-helpers', + 'can-simple-map', + 'can-simple-observable' +], function (require, exports, module) { + var Scope = require('can-view-scope'); + var QUnit = require('steal-qunit'); + var testHelpers = require('can-test-helpers'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + QUnit.module('can-view-scope set'); + QUnit.test('computes are set as this and . and ../', function (assert) { + var value = new SimpleObservable(1); + var scope = new Scope(value); + scope.set('this', 2); + assert.equal(scope.get('this'), 2, 'this read value'); + scope.set('.', 3); + assert.equal(scope.get('this'), 3, '. read value'); + scope = scope.add({}); + scope.set('..', 4); + assert.equal(scope.get('..'), 4, '.. read value'); + }); + QUnit.test('can set scope attributes with ../ (#2132)', function (assert) { + var map = new SimpleMap(); + var scope = new Scope(map); + var top = scope.add(new SimpleMap()); + top.set('../foo', 'bar'); + assert.equal(map.attr('foo'), 'bar'); + }); + QUnit.test('Scope attributes can be set (#1297, #1304)', function (assert) { + var comp = new SimpleObservable('Test'); + var map = new SimpleMap({ other: new SimpleMap({ name: 'Justin' }) }); + var scope = new Scope({ + name: 'Matthew', + other: { + person: { name: 'David' }, + comp: comp + } + }); + scope.set('name', 'Wilbur'); + assert.equal(scope.get('name'), 'Wilbur', 'set(key) updated'); + scope.set('other.person.name', 'Dave'); + assert.equal(scope.get('other.person.name'), 'Dave', 'set(key.key.key) updated'); + scope.set('other.comp', 'Changed'); + assert.equal(comp.get(), 'Changed', 'set(key.compute) updated'); + scope = new Scope(map); + scope.set('other.name', 'Brian'); + assert.equal(scope.get('other.name'), 'Brian', 'Value updated'); + assert.equal(map.attr('other').attr('name'), 'Brian', 'Name update in map'); + }); + QUnit.test('setting a key on a non observable context', function (assert) { + var context = { colors: new SimpleMap() }; + var scope = new Scope(context); + scope.set('colors', { prop: 'bar' }); + assert.deepEqual(context.colors.attr(), { prop: 'bar' }, 'can updateDeep'); + }); + QUnit.test('filename and lineNumber can be read from anywhere in scope chain', function (assert) { + var parent = new Scope({}); + var scope = parent.add({}); + parent.set('scope.filename', 'my-cool-file.txt'); + parent.set('scope.lineNumber', '5'); + assert.equal(scope.peek('scope.filename'), 'my-cool-file.txt', 'scope.peek("scope.filename")'); + assert.equal(scope.peek('scope.lineNumber'), '5', 'scope.peek("scope.lineNumber")'); + }); + testHelpers.dev.devOnlyTest('Setting a value to an attribute with an undefined parent errors (canjs/can-stache-bindings#298)', function (assert) { + var teardown = testHelpers.dev.willError(/Attempting to set a value at (.+) where (.+) is undefined./); + var scope = new Scope({}); + scope.set('../person.name', 'Christopher'); + assert.equal(teardown(), 1, 'saw errors'); + }); +}); +/*can-view-scope@4.13.6#test/scope-key-data-test*/ +define('can-view-scope@4.13.6#test/scope-key-data-test', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'can-simple-map', + 'steal-qunit', + 'can-symbol', + 'can-reflect', + 'can-simple-observable', + 'can-observation', + 'can-observation-recorder', + 'can-test-helpers' +], function (require, exports, module) { + var Scope = require('can-view-scope'); + var SimpleMap = require('can-simple-map'); + var QUnit = require('steal-qunit'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var SimpleObservable = require('can-simple-observable'); + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-view-scope scope-key-data'); + QUnit.test('able to scope-key-data this', function (assert) { + var value = new SimpleObservable(1); + var scope = new Scope(value); + var thisObservable = scope.computeData('this'); + thisObservable.on(function () { + }); + assert.equal(canReflect.getValue(thisObservable), 1); + canReflect.setValue(thisObservable, 2); + }); + QUnit.test('ScopeKeyData\'s thisArg is observable', function (assert) { + var doSomething = function () { + return this.value; + }; + var context = new SimpleMap({ + foo: { + doSomething: doSomething, + value: 'A' + } + }); + var res = new Scope(context).computeData('this.foo@doSomething', { proxyMethods: false }); + var obs = new Observation(function () { + var func = canReflect.getValue(res); + return func.call(res.thisArg); + }); + canReflect.onValue(obs, function (value) { + assert.equal(value, 'B'); + }); + context.set('foo', { + doSomething: doSomething, + value: 'B' + }); + }); + QUnit.test('reading ScopeKeyData will update underlying observable', function (assert) { + var context = new SimpleMap({ 'prop': 'value' }); + var prop = new Scope(context).computeData('this.prop', { proxyMethods: false }); + canReflect.onValue(prop, function () { + }); + context.on('prop', function () { + assert.equal(canReflect.getValue(prop), 'VALUE', 'able to read fastPath value'); + }, 'notify'); + context.set('prop', 'VALUE'); + var root = new SimpleObservable('value'); + var observation = new Observation(function () { + return root.value; + }); + context = { 'prop': observation }; + prop = new Scope(context).computeData('this.prop', { proxyMethods: false }); + canReflect.onValue(prop, function () { + }); + canReflect.onValue(root, function () { + assert.equal(canReflect.getValue(prop), 'VALUE', 'able to read deep, non-fast-path value'); + }, 'notify'); + root.value = 'VALUE'; + }); + QUnit.test('able to read from primitives (#197)', function (assert) { + var map = new SimpleMap({ someProperty: 'hello' }); + var scope = new Scope(map); + var scopeKeyData = scope.computeData('someProperty@split'); + canReflect.onValue(scopeKeyData, function () { + }); + assert.ok(true, 'does not error'); + }); + QUnit.test('initialValue should not emit ObservationRecords (#198)', function (assert) { + var map = new SimpleMap({ someProperty: 'hello' }); + var scope = new Scope(map); + var scopeKeyData = scope.computeData('someProperty'); + ObservationRecorder.start(); + assert.equal(scopeKeyData.initialValue, 'hello'); + var records = ObservationRecorder.stop(); + assert.equal(records.valueDependencies.size, 0, 'no value deps'); + }); + QUnit.test('Implements can.setElement', function (assert) { + var observation = new Observation(function () { + return 'test'; + }); + var map = new SimpleMap({ someProp: observation }); + var scope = new Scope(map); + var scopeKeyData = scope.computeData('someProp'); + scopeKeyData[canSymbol.for('can.setElement')](document.createElement('div')); + assert.ok(true, 'ScopeKeyData has can.setElement'); + }); + testHelpers.dev.devOnlyTest('Warn when key is not found and log the value of the last property that can be read #206', function (assert) { + var teardown = testHelpers.dev.willWarn(/Unable to find key "foo.length". Found "foo" with value: %o/, function (message, matched) { + assert.ok(matched, 'warning displayed'); + }); + var context = { foo: true }; + var scope = new Scope(context); + var scopeKeyData = scope.computeData('foo.length', { warnOnMissingKey: true }); + scopeKeyData.read(); + teardown(); + }); + testHelpers.dev.devOnlyTest('Warn when key is not defined #206', function (assert) { + var teardown = testHelpers.dev.willWarn('Unable to find key "foo.length".', function (message, matched) { + assert.ok(matched, 'warning is not displayed'); + }); + var scope = new Scope({}); + var scopeKeyData = scope.computeData('foo.length', { warnOnMissingKey: true }); + scopeKeyData.read(); + teardown(); + }); +}); +/*can-view-scope@4.13.6#test/scope-test*/ +define('can-view-scope@4.13.6#test/scope-test', [ + 'require', + 'exports', + 'module', + 'can-view-scope', + 'can-stache-key', + '../template-context', + 'can-symbol', + 'steal-qunit', + 'can-reflect', + 'can-observation', + 'can-test-helpers', + 'can-simple-map', + 'can-simple-observable', + 'can-observation-recorder', + 'can-reflect-dependencies', + 'can-stache-helpers', + './variable-scope-test', + './scope-set-test', + './scope-key-data-test' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Scope = require('can-view-scope'); + var observeReader = require('can-stache-key'); + var TemplateContext = require('../template-context'); + var canSymbol = require('can-symbol'); + var QUnit = require('steal-qunit'); + var canReflect = require('can-reflect'); + var Observation = require('can-observation'); + var testHelpers = require('can-test-helpers'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + var ObservationRecorder = require('can-observation-recorder'); + var canReflectDeps = require('can-reflect-dependencies'); + var canStacheHelpers = require('can-stache-helpers'); + QUnit.module('can/view/scope'); + QUnit.test('basics', function (assert) { + var address = new SimpleMap({ zip: 60647 }); + var person = new SimpleMap({ + name: 'Justin', + address: address + }); + var items = new SimpleMap({ + people: person, + count: 1000 + }); + var itemsScope = new Scope(items), personScope = new Scope(person, itemsScope), zipScope = new Scope(address, personScope); + var nameInfo; + var c = new Observation(function () { + nameInfo = zipScope.read('../name'); + }); + canReflect.onValue(c, function () { + }); + assert.deepEqual(nameInfo.reads, [{ + key: 'name', + at: false + }], 'reads'); + assert.equal(nameInfo.scope, personScope, 'scope'); + assert.equal(nameInfo.value, 'Justin', 'value'); + assert.equal(nameInfo.rootObserve, person, 'rootObserve'); + }); + QUnit.test('Scope.prototype.computeData', function (assert) { + var map = new SimpleMap(); + var base = new Scope(map); + var computeData = base.computeData('age'); + assert.equal(computeData.observation, computeData.options.observation, 'ScopeKeyData should have a backing observation stored on its `options`'); + var age = computeData.compute; + assert.equal(age(), undefined, 'age is not set'); + age.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 31, 'newVal is provided correctly'); + assert.equal(oldVal, undefined, 'oldVal is undefined'); + }); + age(31); + assert.equal(map.attr('age'), 31, 'maps age is set correctly'); + }); + QUnit.test('backtrack path (#163)', function (assert) { + var row = new SimpleMap({ first: 'Justin' }), col = { format: 'str' }, base = new Scope(row), cur = base.add(col); + assert.equal(cur.peek('.'), col, 'got col'); + assert.equal(cur.peek('..'), row, 'got row'); + assert.equal(cur.peek('../first'), 'Justin', 'got row'); + }); + QUnit.test('nested properties with compute', function (assert) { + var me = new SimpleMap({ name: new SimpleMap({ first: 'Justin' }) }); + var cur = new Scope(me); + var compute = cur.computeData('name.first').compute; + var changes = 0; + var handler = function (ev, newVal, oldVal) { + if (changes === 0) { + assert.equal(oldVal, 'Justin'); + assert.equal(newVal, 'Brian'); + } else if (changes === 1) { + assert.equal(oldVal, 'Brian'); + assert.equal(newVal, undefined); + } else if (changes === 2) { + assert.equal(oldVal, undefined); + assert.equal(newVal, 'Payal'); + } else if (changes === 3) { + assert.equal(oldVal, 'Payal'); + assert.equal(newVal, 'Curtis'); + } + changes++; + }; + compute.bind('change', handler); + assert.equal(compute(), 'Justin', 'read value after bind'); + me.attr('name').attr('first', 'Brian'); + me.attr('name', undefined); + me.attr('name', { first: 'Payal' }); + me.attr('name', new SimpleMap({ first: 'Curtis' })); + compute.unbind('change', handler); + }); + QUnit.test('function at the end', function (assert) { + var compute = new Scope({ + me: { + info: function () { + return 'Justin'; + } + } + }).computeData('me.info').compute; + assert.equal(compute()(), 'Justin'); + var fn = function () { + return this.name; + }; + var compute2 = new Scope({ + me: { + info: fn, + name: 'Hank' + } + }).computeData('me.info', { + isArgument: true, + args: [] + }).compute; + assert.equal(compute2()(), 'Hank'); + }); + QUnit.test('binds to the right scope only', function (assert) { + var baseMap = new SimpleMap({ me: new SimpleMap({ name: new SimpleMap({ first: 'Justin' }) }) }); + var base = new Scope(baseMap); + var topMap = new SimpleMap({ me: new SimpleMap({ name: new SimpleMap({}) }) }); + var scope = base.add(topMap); + var compute = scope.computeData('../me.name.first').compute; + compute.bind('change', function (ev, newVal, oldVal) { + assert.equal(oldVal, 'Justin'); + assert.equal(newVal, 'Brian'); + }); + assert.equal(compute(), 'Justin'); + topMap.attr('me').attr('name').attr('first', 'Payal'); + baseMap.attr('me').attr('name').attr('first', 'Brian'); + }); + QUnit.test('Scope read returnObserveMethods=true', function (assert) { + var MapConstruct = SimpleMap.extend({ + foo: function (arg) { + assert.equal(this, data.map, 'correct this'); + assert.equal(arg, true, 'correct arg'); + } + }); + var data = { map: new MapConstruct() }; + var res = Scope.read(data, observeReader.reads('map.foo'), { isArgument: true }); + res.value(true); + }); + QUnit.test('rooted observable is able to update correctly', function (assert) { + var baseMap = new SimpleMap({ name: new SimpleMap({ first: 'Justin' }) }); + var scope = new Scope(baseMap); + var compute = scope.computeData('name.first').compute; + assert.equal(compute(), 'Justin'); + baseMap.attr('name', new SimpleMap({ first: 'Brian' })); + assert.equal(compute(), 'Brian'); + }); + QUnit.test('computeData reading an object with a compute', function (assert) { + var age = new SimpleObservable(21); + var scope = new Scope({ person: { age: age } }); + var computeData = scope.computeData('person.age'); + var value = computeData.compute(); + assert.equal(value, 21, 'correct value'); + computeData.compute(31); + assert.equal(age.get(), 31, 'age updated'); + }); + QUnit.test('computeData with initial empty compute (#638)', function (assert) { + assert.expect(2); + var c = new SimpleObservable(); + var scope = new Scope({ compute: c }); + var computeData = scope.computeData('compute'); + assert.equal(computeData.compute(), undefined); + computeData.compute.bind('change', function (ev, newVal) { + assert.equal(newVal, 'compute value'); + }); + c.set('compute value'); + }); + QUnit.test('Can read static properties on constructors (#634)', function (assert) { + var Foo = SimpleMap.extend({ static_prop: 'baz' }, { proto_prop: 'thud' }); + var data = new Foo({ own_prop: 'quux' }), scope = new Scope(data); + assert.equal(scope.computeData('constructor.static_prop').compute(), 'baz', 'static prop'); + }); + QUnit.test('Can read static properties on constructors (#634)', function (assert) { + var Foo = SimpleMap.extend({ static_prop: 'baz' }, { proto_prop: 'thud' }); + var data = new Foo({ own_prop: 'quux' }), scope = new Scope(data); + assert.equal(scope.computeData('constructor.static_prop').compute(), 'baz', 'static prop'); + }); + QUnit.test('Scope lookup restricted to current scope with ./ (#874)', function (assert) { + var current; + var scope = new Scope(new SimpleMap({ value: 'A Value' })).add(current = new SimpleMap({})); + var compute = scope.computeData('./value').compute; + assert.equal(compute(), undefined, 'no initial value'); + compute.bind('change', function (ev, newVal) { + assert.equal(newVal, 'B Value', 'changed'); + }); + compute('B Value'); + assert.equal(current.attr('value'), 'B Value', 'updated'); + }); + QUnit.test('reading properties on undefined (#1314)', function (assert) { + var scope = new Scope(undefined); + var compute = scope.compute('property'); + assert.equal(compute(), undefined, 'got back undefined'); + }); + QUnit.test('computeData.compute get/sets computes in maps', function (assert) { + var cmpt = new SimpleObservable(4); + var map = new SimpleMap(); + map.attr('computer', cmpt); + var scope = new Scope(map); + var computeData = scope.computeData('computer', {}); + assert.equal(computeData.compute(), 4, 'got the value'); + computeData.compute(5); + assert.equal(cmpt.get(), 5, 'updated compute value'); + assert.equal(computeData.compute(), 5, 'the compute has the right value'); + }); + QUnit.test('computesData can find update when initially undefined parent scope becomes defined (#579)', function (assert) { + assert.expect(2); + var map = new SimpleMap(); + var scope = new Scope(map); + var top = scope.add(new SimpleMap()); + var computeData = top.computeData('../value', {}); + assert.equal(computeData.compute(), undefined, 'initially undefined'); + computeData.compute.bind('change', function (ev, newVal) { + assert.equal(newVal, 'first'); + }); + map.attr('value', 'first'); + }); + QUnit.test('can read parent context with ../ (#2244)', function (assert) { + var map = new SimpleMap(); + var scope = new Scope(map); + var top = scope.add(new SimpleMap()); + assert.equal(top.peek('../'), map, 'looked up value correctly'); + }); + QUnit.test('trying to read constructor from refs scope is ok', function (assert) { + var map = new TemplateContext(); + var construct = new Observation(function () { + return map.constructor; + }); + canReflect.onValue(construct, function () { + }); + assert.equal(canReflect.getValue(construct), TemplateContext); + }); + QUnit.test('reading from a string in a nested scope doesn\'t throw an error (#22)', function (assert) { + var foo = new SimpleObservable('foo'); + var bar = new SimpleObservable('bar'); + var scope = new Scope(foo); + var localScope = scope.add(bar); + assert.equal(localScope.read('foo').value, undefined); + }); + QUnit.test('Optimize for compute().observableProperty (#29)', function (assert) { + var map = new SimpleMap({ value: 'a' }); + var wrap = new SimpleObservable(map); + var scope = new Scope(wrap); + var scopeKeyData = scope.computeData('value'); + var scopeCompute = scopeKeyData.compute; + var changeNumber = 0; + scopeCompute.on('change', function (ev, newVal, oldVal) { + if (changeNumber === 1) { + assert.equal(newVal, 'b'); + assert.equal(oldVal, 'a'); + assert.ok(scopeKeyData.fastPath, 'still fast path'); + changeNumber++; + wrap.set(new SimpleMap({ value: 'c' })); + } else if (changeNumber === 2) { + assert.equal(newVal, 'c', 'got new value'); + assert.equal(oldVal, 'b', 'got old value'); + assert.notOk(scopeKeyData.fastPath, 'still fast path'); + } + }); + assert.ok(scopeKeyData.fastPath, 'fast path'); + changeNumber++; + map.attr('value', 'b'); + }); + QUnit.test('a compute can observe the ScopeKeyData', function (assert) { + assert.expect(3); + var map = new SimpleMap({ + value: 'a', + other: 'b' + }); + var wrap = new SimpleObservable(map); + var scope = new Scope(wrap); + var scopeKeyData = scope.computeData('value'); + var oldOnValue = scopeKeyData[canSymbol.for('can.onValue')]; + scopeKeyData[canSymbol.for('can.onValue')] = function () { + assert.ok(true, 'bound on the scopeKeyData'); + return oldOnValue.apply(this, arguments); + }; + var c = new Observation(function () { + return scopeKeyData.get() + map.attr('other'); + }); + canReflect.onValue(c, function (newValue) { + assert.equal(newValue, 'Ab', 'observation changed'); + }); + map.attr('value', 'A'); + }); + QUnit.test('unbinding clears all event bindings', function (assert) { + var ready = assert.async(); + var map = new SimpleMap({ + value: 'a', + other: 'b' + }); + var wrap = new SimpleObservable(map); + var scope = new Scope(wrap); + var scopeKeyData = scope.computeData('value'); + var c = new Observation(function () { + return scopeKeyData.get() + map.attr('other'); + }); + var handlers = function (newValue) { + assert.equal(newValue, 'Ab'); + }; + canReflect.onValue(c, handlers); + canReflect.offValue(c, handlers); + setTimeout(function () { + var handlers = map[canSymbol.for('can.meta')].handlers.get([]); + assert.equal(handlers.length, 0, 'there are no bindings'); + ready(); + }, 30); + }); + QUnit.test('computes are read as this and . and ../', function (assert) { + var value = new SimpleObservable(1); + var scope = new Scope(value); + assert.equal(scope.get('this'), 1, 'this read value'); + assert.equal(scope.get('.'), 1, '. read value'); + scope = scope.add({}); + assert.equal(scope.get('..'), 1, '.. read value'); + }); + QUnit.test('maps are set with this.foo and ./foo', function (assert) { + var map = new SimpleObservable(new SimpleMap({ value: 1 })); + var scope = new Scope(map); + scope.set('this.value', 2); + assert.equal(scope.get('this.value'), 2, 'this read value'); + scope.set('./value', 3); + assert.equal(scope.get('./value'), 3, '. read value'); + }); + testHelpers.dev.devOnlyTest('computeData dependencies', function (assert) { + var map = new SimpleMap({ value: 'a' }); + var scope = new Scope(map); + var computeData = scope.computeData('value'); + var c = new Observation(function () { + return computeData.get(); + }); + canReflect.onValue(c, function () { + }); + var dependencies = canReflect.getValueDependencies(c); + assert.ok(dependencies.valueDependencies.has(computeData), 'compute has computeData'); + assert.equal(dependencies.valueDependencies.size, 1, 'compute only has computeData'); + var mapValueDependencies = canReflectDeps.getDependencyDataOf(map, 'value'); + assert.ok(mapValueDependencies.whatIChange.derive.valueDependencies.has(computeData.observation), 'map.value -> computeData internal observation'); + assert.ok(mapValueDependencies.whatChangesMe.mutate.valueDependencies.has(computeData), 'computeData -> map.value'); + var computeDataDependencies = canReflect.getValueDependencies(computeData); + assert.ok(computeDataDependencies.valueDependencies.has(computeData.observation), 'computeData internal observation -> computeData'); + }); + testHelpers.dev.devOnlyTest('computeData dependencies for nested properties', function (assert) { + var justin = new SimpleMap({ name: 'justin' }); + var matthew = new SimpleMap({ name: 'matthew' }); + var map = new SimpleMap({ person: justin }); + var scope = new Scope(map); + var computeData = scope.computeData('person.name'); + var obs = new Observation(function () { + return computeData.get(); + }); + canReflect.onValue(obs, function () { + }); + var observationDependencies = canReflect.getValueDependencies(obs); + assert.ok(observationDependencies.valueDependencies.has(computeData), 'compute has computeData'); + assert.equal(observationDependencies.valueDependencies.size, 1, 'compute only has computeData'); + var mapPersonDependencies = canReflectDeps.getDependencyDataOf(map, 'person'); + assert.ok(mapPersonDependencies.whatIChange.derive.valueDependencies.has(computeData.observation), 'map.person -> computeData internal observation'); + var justinNameDependencies = canReflectDeps.getDependencyDataOf(justin, 'name'); + assert.ok(justinNameDependencies.whatIChange.derive.valueDependencies.has(computeData.observation), 'person.name -> computeData internal observation'); + assert.ok(justinNameDependencies.whatChangesMe.mutate.valueDependencies.has(computeData), 'computeData -> person.name'); + var computeDataDependencies = canReflect.getValueDependencies(computeData); + assert.ok(computeDataDependencies.valueDependencies.has(computeData.observation), 'computeData internal observation -> computeData'); + map.set('person', matthew); + justinNameDependencies = canReflectDeps.getDependencyDataOf(justin, 'name'); + var matthewNameDependencies = canReflectDeps.getDependencyDataOf(matthew, 'name'); + assert.notOk(justinNameDependencies, 'old person.name dependencies are removed'); + assert.ok(matthewNameDependencies.whatIChange.derive.valueDependencies.has(computeData.observation), 'person.name -> computeData internal observation changed'); + assert.ok(matthewNameDependencies.whatChangesMe.mutate.valueDependencies.has(computeData), 'computeData -> person.name changed'); + }); + QUnit.test('scopeKeyData offValue resets dependencyChange/start', function (assert) { + var map = new SimpleMap({ + value: 'a', + other: 'b' + }); + var wrap = new SimpleObservable(map); + var scope = new Scope(wrap); + var scopeKeyData = scope.computeData('value'); + var handler = function () { + }; + canReflect.onValue(scopeKeyData, handler); + canReflect.offValue(scopeKeyData, handler); + assert.equal(scopeKeyData.observation.dependencyChange, Observation.prototype.dependencyChange, 'dependencyChange should be restored'); + assert.equal(scopeKeyData.observation.start, Observation.prototype.start, 'start should be restored'); + }); + QUnit.test('Rendering a template with a custom scope (#55)', function (assert) { + var scope = new Scope({}); + assert.equal(scope.get('name'), undefined, 'No name'); + scope.set('name', 'John'); + assert.equal(scope.get('name'), 'John', 'Got the name'); + scope = scope.add({ name: 'Justin' }); + assert.equal(scope.get('name'), 'Justin', 'Got the top scope name'); + }); + QUnit.test('./ scope lookup should read current scope', function (assert) { + var parent = new SimpleMap(); + var map = new SimpleMap(); + var scope = new Scope(parent).add(map); + assert.equal(scope.get('./'), map); + }); + QUnit.test('getTemplateContext() gives a scope with the templateContext', function (assert) { + var map = new SimpleMap(); + var scope = new Scope(map); + var templateContext = scope.getTemplateContext(); + assert.ok(templateContext instanceof Scope, 'templateContext is a Scope'); + assert.ok(templateContext._context instanceof TemplateContext, 'templateContext context is a TemplateContext object'); + }); + QUnit.test('scope can be used to read from the templateContext', function (assert) { + var map = new SimpleMap(); + var scope = new Scope(map); + assert.deepEqual(scope.peek('scope'), scope, 'scope'); + scope.set('scope.vars.name', 'Kevin'); + assert.equal(scope.peek('scope.vars.name'), 'Kevin', 'scope.vars.name === Kevin'); + var ageFn = function () { + return '30'; + }; + scope.set('scope.vars.age', ageFn); + assert.equal(scope.peek('scope.vars.age')(), '30', 'scope.vars.age === 30'); + }); + QUnit.test('scope.index reads from special scopes', function (assert) { + var originalIndexHelper = canStacheHelpers.index; + delete canStacheHelpers.index; + var map1 = new SimpleMap({ index: 1 }); + var map2 = new SimpleMap({ index: 3 }); + var scope = new Scope(map1); + assert.equal(scope.peek('scope.index'), undefined, 'scope.index returns undefined if no special context exists'); + scope = scope.add({ index: 2 }, { special: true }).add(map2).add({ index: 0 }, { special: true }); + assert.equal(scope.peek('scope.index'), 0, 'scope.index is read correctly'); + assert.equal(scope._parent.peek('scope.index'), 2, 'scope.index is only read from special contexts'); + canStacheHelpers.index = originalIndexHelper; + }); + QUnit.test('scope.index should not return a global helper', function (assert) { + var mockGlobalHelper = function () { + assert.ok(false, 'global helper should not be called'); + }; + var originalIndexHelper = canStacheHelpers.index; + canStacheHelpers.index = mockGlobalHelper; + var scope = new Scope({}); + assert.equal(scope.peek('scope.index'), undefined, 'scope.index returns undefined if no special context exists'); + canStacheHelpers.index = originalIndexHelper; + }); + QUnit.test('scope.key reads from special scopes', function (assert) { + var map1 = new SimpleMap({ key: 'one' }); + var map2 = new SimpleMap({ key: 3 }); + var scope = new Scope(map1).add({ key: 'two' }, { special: true }).add(map2).add({ key: 'four' }, { special: true }); + assert.equal(scope.peek('scope.key'), 'four', 'scope.key is read correctly'); + assert.equal(scope._parent.peek('scope.key'), 'two', 'scope.key is only read from special contexts'); + }); + QUnit.test('variables starting with \'scope\' should not be read from templateContext (#104)', function (assert) { + var map = new SimpleMap({ scope1: 'this is scope1' }); + var scope = new Scope(map); + assert.deepEqual(scope.peek('scope1'), 'this is scope1', 'scope1'); + }); + QUnit.test('nested properties can be read from templateContext.vars', function (assert) { + var foo = new SimpleMap({ bar: 'baz' }); + var map = new SimpleMap(); + var scope = new Scope(map); + assert.ok(!scope.peek('scope.vars.foo.bar'), 'vars.foo.bar === undefined'); + scope.set('scope.vars.foo', foo); + assert.equal(scope.peek('scope.vars.foo.bar'), 'baz', 'vars.foo.bar === baz'); + scope.set('scope.vars.foo.bar', 'quz'); + assert.equal(scope.peek('scope.vars.foo.bar'), 'quz', 'vars.foo.bar === quz'); + }); + QUnit.test('nested properties can be read from scope.root', function (assert) { + var root = new SimpleMap({ bar: 'baz' }); + var map = new SimpleMap({ bar: 'abc' }); + var scope = new Scope(root).add(map); + assert.equal(scope.peek('scope.root.bar'), 'baz', 'root.bar === baz'); + }); + QUnit.test('special scopes are skipped if options.special !== true', function (assert) { + var map1 = new SimpleMap({}); + var scope = new Scope(map1).add({ foo: 'two' }, { special: true }).add({}); + assert.equal(scope.peek('foo', { special: true }), 'two', 'foo is read from special scope'); + }); + QUnit.test('special scopes are skipped when using ../.', function (assert) { + var obj = { foo: 'one' }; + var scope = new Scope(obj).add({ foo: 'two' }, { special: true }).add({}); + assert.equal(scope.peek('../.'), obj); + assert.equal(scope.peek('.././foo'), 'one'); + }); + QUnit.test('special scopes are skipped when using .', function (assert) { + var map = new SimpleMap({ foo: 'one' }); + var scope = new Scope(map).add({ foo: 'two' }, { special: true }); + assert.equal(scope.peek('.'), map); + }); + QUnit.test('this works everywhere (#45)', function (assert) { + var obj = { foo: 'bar' }; + var scope = new Scope(obj); + assert.equal(scope.get('this.foo'), 'bar'); + }); + QUnit.test('\'this\' and %context give the context', function (assert) { + assert.expect(1); + var vm; + var MyMap = SimpleMap.extend({ + doSomething: function () { + assert.equal(this, vm, 'event callback called on context'); + } + }); + vm = new MyMap(); + var compute = new Scope(vm).computeData('this.doSomething', { + isArgument: true, + args: [] + }).compute; + compute()(); + }); + QUnit.test('that .set with ../ is able to skip notContext scopes (#43)', function (assert) { + var instance = new SimpleMap({ prop: 0 }); + var notContextContext = { NAME: 'NOT CONTEXT' }; + var top = { NAME: 'TOP' }; + var scope = new Scope(instance).add(notContextContext, { notContext: true }).add(top); + scope.set('../prop', 1); + assert.equal(instance.attr('prop'), 1); + }); + QUnit.test('undefined props should be a scope hit (#20)', function (assert) { + var MyType = SimpleMap.extend('MyType', { + init: function () { + this.value = undefined; + } + }); + var EmptyType = SimpleMap.extend('EmptyType', {}); + var instance = new MyType(); + var scope = new Scope(instance).add(new EmptyType()); + var c1 = scope.computeData('../value').compute; + c1.on('change', function () { + }); + c1('BAR'); + assert.equal(instance.attr('value'), 'BAR'); + var instance2 = new MyType(); + var scope2 = new Scope(instance2).add(new SimpleObservable()); + var c2 = scope2.computeData('../value').compute; + c2.on('change', function () { + }); + c2('BAR'); + assert.equal(instance2.attr('value'), 'BAR'); + }); + QUnit.test('ScopeKeyData can.valueHasDependencies', function (assert) { + var map = new SimpleMap({ age: 21 }); + var base = new Scope(map); + var age = base.computeData('age'); + assert.equal(canReflect.valueHasDependencies(age), true, 'undefined'); + }); + QUnit.test('get and set Priority', function (assert) { + var map = new SimpleMap({ age: 21 }); + var base = new Scope(map); + var age = base.computeData('age'); + canReflect.setPriority(age, 5); + assert.equal(canReflect.getPriority(age), 5, 'set priority'); + var compute = age.compute; + assert.equal(canReflect.getPriority(compute), 5, 'set priority'); + }); + QUnit.test('fast path checking does not leak ObservationRecord.adds', function (assert) { + var map = new SimpleMap({ age: 21 }); + Object.defineProperty(map, 'age', { + get: function () { + return this.attr('age'); + }, + set: function (newVal) { + this.attr('age', newVal); + } + }); + var base = new Scope(map); + var age = base.computeData('age'); + ObservationRecorder.start(); + age.get(); + var dependencies = ObservationRecorder.stop(); + assert.equal(dependencies.keyDependencies.size, 0, 'no key dependencies'); + assert.equal(dependencies.valueDependencies.size, 1, 'only sees age'); + assert.ok(dependencies.valueDependencies.has(age), 'only sees age'); + }); + QUnit.test('{{scope.set(...)}} works', function (assert) { + var map = new SimpleMap({ foo: 'bar' }); + var scope = new Scope(map); + var set = scope.peek('scope@set'); + set('foo', 'baz'); + assert.equal(map.get('foo'), 'baz', 'map.foo updated using scope.set'); + }); + QUnit.test('can read a method from scope.viewModel', function (assert) { + var viewModel = new SimpleMap({ + method: function () { + return 'method return value'; + } + }); + var scope = new Scope({}).add({ viewModel: viewModel }, { special: true }); + var method = scope.peek('scope.viewModel@method'); + assert.equal(method(), 'method return value'); + }); + QUnit.test('can read a value from scope.element', function (assert) { + var element = { value: 'element value' }; + var scope = new Scope({}).add({ element: element }, { special: true }); + var value = scope.peek('scope.element.value'); + assert.equal(value, 'element value'); + }); + QUnit.test('scope.find can be used to find a value in the first scope it exists', function (assert) { + var a = new SimpleMap({ a: 'a' }); + var b = new SimpleMap({ b: 'b' }); + var c = new SimpleMap({ c: 'c' }); + var scope = new Scope(c).add(b).add(a); + assert.equal(scope.find('a'), 'a', 'a'); + assert.equal(scope.find('b'), 'b', 'b'); + assert.equal(scope.find('c'), 'c', 'c'); + }); + QUnit.test('scope.find accepts readOptions', function (assert) { + var a = new SimpleMap({ a: 'a' }); + a.func = function () { + return this; + }; + var b = new SimpleMap({ b: 'b' }); + var c = new SimpleMap({ c: 'c' }); + var scope = new Scope(c).add(b).add(a); + var aDotFunc = scope.find('func'); + assert.equal(aDotFunc(), a, 'a.func() got correct context'); + aDotFunc = scope.find('func', { proxyMethods: false }); + assert.notEqual(aDotFunc(), a, 'non-proxied a.func() got correct context'); + }); + QUnit.test('scope.read should not walk up normal scopes by default', function (assert) { + var a = new SimpleMap({ a: 'a' }); + var b = new SimpleMap({ b: 'b' }); + var c = new SimpleMap({ c: 'c' }); + var scope = new Scope(c).add(b).add(a); + assert.equal(scope.read('a').value, 'a', 'a'); + assert.equal(scope.read('b').value, undefined, 'b'); + assert.equal(scope.read('c').value, undefined, 'c'); + }); + QUnit.test('scope.read should walk over special scopes', function (assert) { + var map = new SimpleMap({ + a: 'a', + b: 'b', + c: 'c' + }); + var scope = new Scope(map).add({ d: 'd' }, { special: true }); + assert.equal(scope.read('a').value, 'a', 'a'); + assert.equal(scope.read('b').value, 'b', 'b'); + assert.equal(scope.read('c').value, 'c', 'c'); + }); + QUnit.test('scope.read should skip special contexts and read from notContext scope higher in the chain', function (assert) { + var scope = new Scope({ a: 'a' }).add({ b: 'b' }, { notContext: true }).add({ c: 'c' }, { special: true }).add({ d: 'd' }, { notContext: true }).add({ e: 'e' }); + assert.equal(scope.read('a').value, undefined, 'a not read from normal parent context'); + assert.equal(scope.read('b').value, 'b', 'b read correctly from notContext parent context'); + assert.equal(scope.read('c').value, undefined, 'c not read from special context'); + assert.equal(scope.read('d').value, 'd', 'd read correctly from notContext parent context'); + assert.equal(scope.read('e').value, 'e', 'e read correctly'); + scope = scope.add({ f: 'f' }, { notContext: true }).add({ g: 'g' }, { special: true }).add({ h: 'h' }, { notContext: true }).add({ i: 'i' }); + assert.equal(scope.read('e').value, undefined, 'e not read from normal parent context'); + assert.equal(scope.read('f').value, 'f', 'f read correctly from notContext parent context'); + assert.equal(scope.read('g').value, undefined, 'g not read from special context'); + assert.equal(scope.read('h').value, 'h', 'h read correctly from notContext parent context'); + assert.equal(scope.read('i').value, 'i', 'i read correctly'); + assert.equal(scope.read('../a').value, undefined, '../a not read from normal parent context above normal parent context'); + assert.equal(scope.read('../b').value, 'b', '../b read correctly from notContext parent context above normal parent context'); + assert.equal(scope.read('../c').value, undefined, '../c not read from special context above normal parent context'); + assert.equal(scope.read('../d').value, 'd', '../d read correctly from notContext parent context above normal parent context'); + assert.equal(scope.read('../e').value, 'e', '../e read correctly above normal parent context'); + }); + QUnit.test('reading using ../ when there is no parent returns undefined', function (assert) { + var scope = new Scope({}); + try { + assert.equal(scope.read('../foo').value, undefined, 'returns undefined'); + } catch (e) { + assert.ok(false, 'error occured: ' + e); + } + }); + QUnit.test('read checks templateContext helpers then global helpers after checking the scope', function (assert) { + var map = { + scopeFunction: function () { + return 'scopeFunction'; + } + }; + var helperFunction = function () { + return 'helperFunction'; + }; + var localHelperFunction = function () { + return 'localHelperFunction'; + }; + var globalHelperCalledLocalHelperFunction = function () { + return 'global helper function called "localHelperFunction"'; + }; + var scope = new Scope(map); + canStacheHelpers.helperFunction = helperFunction; + canReflect.setKeyValue(scope.templateContext.helpers, 'localHelperFunction', localHelperFunction); + canStacheHelpers.localHelperFunction = globalHelperCalledLocalHelperFunction; + var readScopeFunction = scope.read('scopeFunction').value; + assert.deepEqual(readScopeFunction(), 'scopeFunction', 'scopeFunction'); + var readLocalHelperFunction = scope.read('localHelperFunction').value; + assert.deepEqual(readLocalHelperFunction(), 'localHelperFunction', 'localHelperFunction'); + var readHelperFunction = scope.read('helperFunction').value; + assert.deepEqual(readHelperFunction(), 'helperFunction', 'helperFunction'); + delete canStacheHelpers.helperFunction; + delete canStacheHelpers.localHelperFunction; + canReflect.setKeyValue(scope.templateContext.helpers, 'localHelperFunction', undefined); + }); + QUnit.test('read can handle objects stored on helpers', function (assert) { + var scope = new Scope(); + var fakeConsole = { + log: function () { + return 'fakeConsole.log'; + }, + warn: function () { + return 'fakeConsole.warn'; + } + }; + canStacheHelpers.console = fakeConsole; + var readConsoleLog = scope.read('console.log').value; + assert.deepEqual(readConsoleLog(), 'fakeConsole.log', 'fakeConsole.log'); + var readConsoleWarn = scope.read('console.warn').value; + assert.deepEqual(readConsoleWarn(), 'fakeConsole.warn', 'fakeConsole.warn'); + delete canStacheHelpers.console; + }); + QUnit.test('scope.helpers can be used to read a helper that conflicts with a property in the scope', function (assert) { + var map = { + myIf: function () { + return 'map.myIf'; + } + }; + var myIf = function () { + return 'global.myIf'; + }; + var scope = new Scope(map); + canStacheHelpers.myIf = myIf; + var localIf = scope.read('myIf').value; + assert.deepEqual(localIf(), 'map.myIf', 'scope function'); + var globalIf = scope.read('scope.helpers.myIf').value; + assert.deepEqual(globalIf(), 'global.myIf', 'global function'); + delete canStacheHelpers.myIf; + }); + QUnit.test('functions have correct `thisArg` so they can be called even with `proxyMethods: false`', function (assert) { + var parent = { + name: function () { + return 'parent'; + } + }; + var child = { + name: function () { + return 'child'; + } + }; + var func = function () { + }; + var childData = { + child: child, + func: func + }; + var parentData = { + parent: parent, + func: func + }; + var scope = new Scope(parentData).add(childData); + var childName = scope.read('child.name', { proxyMethods: false }); + assert.equal(childName.value, child.name, 'childName.value === child.name'); + assert.equal(childName.thisArg, child, 'childName.thisArg === child'); + var childNameCompute = scope.computeData('child.name', { proxyMethods: false }); + Observation.temporarilyBind(childNameCompute); + assert.equal(childNameCompute.initialValue, child.name, 'childNameCompute.inititalValue === child.name'); + assert.equal(childNameCompute.thisArg, child, 'childNameCompute.thisArg === child'); + var rootFunc = scope.read('func', { proxyMethods: false }); + assert.equal(rootFunc.value, func, 'rootFunc.value === func'); + assert.equal(rootFunc.thisArg, childData, 'rootFunc.thisArg === childData'); + var myHelper = function () { + }; + canReflect.setKeyValue(scope.templateContext.helpers, 'myHelper', myHelper); + var helper = scope.read('myHelper', { proxyMethods: false }); + assert.equal(helper.value, myHelper, 'helper.value === func'); + assert.equal(helper.thisArg, undefined, 'helper.thisArg === undefined'); + var parentName = scope.read('../parent.name', { proxyMethods: false }); + assert.equal(parentName.value, parent.name, 'parentName.value === parent.name'); + assert.equal(parentName.thisArg, parent, 'parentName.thisArg === parent'); + var parentFunc = scope.read('../func', { proxyMethods: false }); + assert.equal(parentFunc.value, func, 'parentFunc.value === func'); + assert.equal(parentFunc.thisArg, parentData, 'rootFunc.thisArg === parentData'); + }); + QUnit.test('debugger is a reserved scope key for calling debugger helper', function (assert) { + var scope = new Scope({ name: 'Kevin' }); + var debuggerHelper = function (options) { + return options.scope.read('name').value; + }; + canStacheHelpers['debugger'] = debuggerHelper; + var debuggerScopeKey = scope.compute('debugger'); + assert.equal(canReflect.getValue(debuggerScopeKey), 'Kevin', 'debugger called with correct helper options'); + delete canStacheHelpers['debugger']; + }); + QUnit.test('scope.vm and scope.top', function (assert) { + var scope = new Scope({ name: 'foo' }).add({ name: 'Kevin' }, { viewModel: true }).add({ name: 'bar' }).add({ name: 'Ryan' }, { viewModel: true }).add({ name: 'baz' }); + assert.equal(scope.read('scope.vm.name').value, 'Ryan', 'scope.first can be used to read from the _first_ context with viewModel: true'); + assert.equal(scope.read('scope.top.name').value, 'Kevin', 'scope.top can be used to read from the _top_ context with viewModel: true'); + }); + testHelpers.dev.devOnlyTest('scope.root deprecation warning', function (assert) { + var teardown = testHelpers.dev.willWarn(/`scope.root` is deprecated/); + var scope = new Scope({ foo: 'bar' }); + scope.read('scope.root'); + assert.equal(teardown(), 1, 'deprecation warning displayed'); + }); + testHelpers.dev.devOnlyTest('scope.getPathsForKey', function (assert) { + var top = {}; + top[canSymbol.for('can.hasKey')] = function (key) { + return key === 'name'; + }; + var vm = { name: 'Ryan' }; + var nonVm = { name: 'Bianca' }; + var notContext = { index: 0 }; + var special = { myIndex: 0 }; + var scope = new Scope(top, null, { viewModel: true }).add(notContext, { notContext: true }).add(vm, { viewModel: true }).add(special, { special: true }).add(true).add(nonVm); + var paths = scope.getPathsForKey('name'); + assert.deepEqual(paths, { + 'scope.vm.name': vm, + 'scope.top.name': top, + 'name': nonVm, + '../../name': vm, + '../../../name': top + }); + }); + testHelpers.dev.devOnlyTest('scope.getPathsForKey works for functions', function (assert) { + var top = { + name: function () { + return 'Christopher'; + } + }; + var vm = { + name: function () { + return 'Ryan'; + } + }; + var nonVm = { + name: function () { + return 'Bianca'; + } + }; + var notContext = { index: 0 }; + var special = { myIndex: 0 }; + var scope = new Scope(top, null, { viewModel: true }).add(notContext, { notContext: true }).add(vm, { viewModel: true }).add(special, { special: true }).add(true).add(nonVm); + var paths = scope.getPathsForKey('name'); + assert.deepEqual(paths, { + 'scope.vm.name()': vm, + 'scope.top.name()': top, + 'name()': nonVm, + '../../name()': vm, + '../../../name()': top + }); + }); + QUnit.test('scope.hasKey', function (assert) { + var top = { foo: 'bar' }; + var vm = { bar: 'baz' }; + var nonVm = {}; + nonVm[canSymbol.for('can.hasKey')] = function (key) { + return key === 'baz'; + }; + var scope = new Scope(top, null, { viewModel: true }).add(vm, { viewModel: true }).add(nonVm); + assert.equal(canReflect.hasKey(scope, 'scope.top.foo'), true, 'hasKey scope.top.foo === true'); + assert.equal(canReflect.hasKey(scope, 'scope.top.bar'), false, 'hasKey scope.top.bar === false'); + assert.equal(canReflect.hasKey(scope, 'scope.vm.bar'), true, 'hasKey scope.vm.bar === true'); + assert.equal(canReflect.hasKey(scope, 'scope.vm.baz'), false, 'hasKey scope.vm.baz === false'); + assert.equal(canReflect.hasKey(scope, 'baz'), true, 'hasKey baz === true'); + assert.equal(canReflect.hasKey(scope, 'foo'), false, 'hasKey foo === false'); + }); + QUnit.test('read returns correct `parentHasKey` value', function (assert) { + var vm = {}; + canReflect.assignSymbols(vm, { + 'can.hasKey': function (key) { + return key === 'foo'; + } + }); + var scope = new Scope(vm); + assert.ok(scope.read('foo').parentHasKey, 'parent has key \'foo\''); + assert.notOk(scope.read('bar').parentHasKey, 'parent does not have key \'bar\''); + }); + QUnit.test('computeData returns correct `parentHasKey` value', function (assert) { + var vm = {}; + canReflect.assignSymbols(vm, { + 'can.hasKey': function (key) { + return key === 'foo'; + } + }); + var scope = new Scope(vm); + var fooCompute = scope.computeData('foo'); + var barCompute = scope.computeData('bar'); + fooCompute.read(); + barCompute.read(); + assert.ok(fooCompute.parentHasKey, 'parent has key \'foo\''); + assert.notOk(barCompute.parentHasKey, 'parent does not have key \'bar\''); + }); + QUnit.test('can get helpers from parent TemplateContext', function (assert) { + var scope = new Scope(new Scope.TemplateContext({ + helpers: { + foo: function () { + } + } + })).add(new Scope.TemplateContext()).add({}); + assert.ok(scope.get('foo'), 'got helper'); + }); + QUnit.test('do not error when reading a missing parent context (#183)', function (assert) { + var scope = new Scope(new Scope.TemplateContext({})).add({}, {}); + var results = scope.read('../key', {}); + assert.ok(results.noContextAvailable, 'no error'); + }); + QUnit.test('cloneFromRef clones meta', function (assert) { + var scope = new Scope({}).add(new Scope.TemplateContext({})).addLetContext({ tempProp: undefined }); + var copyScope = scope.cloneFromRef(); + assert.deepEqual(copyScope._meta, { variable: true }); + }); + QUnit.test('scope/key walks the scope', function (assert) { + var scope = new Scope({ + foo: 'bar', + baz: function () { + return 'quz'; + } + }).add({}).add({}); + var value = scope.peek('scope/foo'); + assert.equal(value, 'bar'); + value = scope.peek('@scope/baz'); + assert.equal(value(), 'quz'); + }); + QUnit.test('able to read partials', function (assert) { + var myPartial = function () { + }; + var scope = new Scope(new Scope.TemplateContext({ partials: { myPartial: myPartial } })).add({}); + var result = scope.get('myPartial'); + assert.equal(result, myPartial, 'read the value'); + }); + QUnit.test('properties can shadow functions on can-event-queue/map when there is a LetContext', function (assert) { + var scope = new Scope({ one: 'the one property' }).addLetContext(); + assert.equal(scope.get('one'), 'the one property', 'read the value'); + }); + require('./variable-scope-test'); + require('./scope-set-test'); + require('./scope-key-data-test'); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-view-target@5.0.0#test/test*/ +define('can-view-target@5.0.0#test/test', [ + 'require', + 'exports', + 'module', + 'can-view-target', + 'can-simple-dom', + 'steal-qunit', + 'can-globals/mutation-observer/mutation-observer' +], function (require, exports, module) { + (function (global, require, exports, module) { + var target = require('can-view-target'); + var simpleDom = require('can-simple-dom'); + var QUnit = require('steal-qunit'); + var MUTATION_OBSERVER = require('can-globals/mutation-observer/mutation-observer'); + QUnit.module('can-view-target'); + QUnit.test('basics', function (assert) { + var classCallback = function () { + assert.equal(this.nodeName.toLowerCase(), 'h1', 'class on the right element'); + this.className = 'selected'; + }, attributesCallback = function () { + assert.equal(this.nodeName.toLowerCase(), 'h1', 'attributes on the right element'); + }, textNodeCallback = function () { + assert.equal(this.nodeType, 3, 'got a text node'); + this.nodeValue = 'World'; + }; + var data = target([{ + tag: 'h1', + attrs: { + 'id': 'myh1', + 'class': classCallback + }, + attributes: [attributesCallback], + children: [{ + tag: 'span', + children: [ + 'Hello ', + textNodeCallback, + '!' + ] + }] + }]); + assert.equal(data.clone.childNodes.length, 1, 'there is one child'); + var h1 = data.clone.childNodes[0]; + assert.equal(h1.nodeName.toLowerCase(), 'h1', 'there is one h1'); + assert.equal(h1.id, 'myh1', 'the h1 has the right id'); + assert.equal(h1.childNodes.length, 1, 'the h1 has span'); + assert.equal(h1.childNodes[0].childNodes.length, 3, 'the span has 3 children'); + assert.deepEqual(data.paths, [{ + path: [0], + callbacks: [ + { callback: classCallback }, + { callback: attributesCallback } + ], + paths: [{ + path: [ + 0, + 1 + ], + callbacks: [{ callback: target.keepsTextNodes ? textNodeCallback : data.paths[0].paths[0].callbacks[0].callback }] + }] + }]); + var result = data.hydrate(); + var newH1 = result.childNodes[0]; + assert.equal(newH1.className, 'selected', 'got selected class name'); + assert.equal(newH1.innerHTML.toLowerCase(), 'hello world!'); + }); + QUnit.test('replacing items', function (assert) { + var data = target([ + function () { + this.parentNode.insertBefore(document.createTextNode('inserted'), this.nextSibling); + }, + 'hi', + function () { + assert.equal(this.previousSibling.nodeValue, 'hi', 'previous is as expected'); + } + ]); + data.hydrate(); + }); + QUnit.test('comments', function (assert) { + function foo(el) { + el.nodeValue = 'val'; + } + var data = target([ + { tag: 'h1' }, + { comment: 'foo bar' }, + { + comment: 'bax', + callbacks: [foo] + } + ]); + var node = data.clone.childNodes[1]; + assert.equal(node.nodeValue, 'foo bar', 'node value is right'); + assert.equal(node.nodeType, 8, 'node is a comment'); + assert.deepEqual(data.paths[0].path, [2], 'node path is right'); + assert.deepEqual(data.paths[0].callbacks, [{ callback: foo }], 'node callback is right'); + }); + QUnit.test('paths should be run in reverse order (#966)', function (assert) { + var data = target([{ + tag: 'h1', + attributes: [function () { + }], + children: [ + function () { + this.parentNode.insertBefore(document.createElement('div'), this.nextSibling); + }, + { + tag: 'span', + children: [function () { + assert.equal(this.nodeType, 3, 'got an element'); + }] + } + ] + }]); + data.hydrate(); + }); + QUnit.test('renderToVirtualDOM', function (assert) { + var simpleDocument = new simpleDom.Document(); + var innerData = target([{ tag: 'span' }], simpleDocument); + var outerData = target([{ + tag: 'h1', + children: [ + function (data) { + this.parentNode.insertBefore(innerData.hydrate(data), this); + this.parentNode.removeChild(this); + }, + 'foo' + ] + }], simpleDocument); + var out = outerData.hydrate({ foo: true }); + assert.equal(out.firstChild.nodeName, 'H1'); + assert.equal(out.firstChild.firstChild.nodeName, 'SPAN'); + assert.equal(out.firstChild.lastChild.nodeValue, 'foo'); + }); + QUnit.test('cloneNode works in IE11', function (assert) { + var frag = document.createDocumentFragment(); + var text = document.createTextNode('some-text'); + var MO = MUTATION_OBSERVER(); + var observer; + frag.appendChild(text); + var clone = target.cloneNode(frag); + assert.equal(clone.childNodes.length, 1, 'cloneNode should work'); + if (MO) { + observer = new MO(function (mutations) { + }); + observer.observe(document.documentElement, { + childList: true, + subtree: true + }); + clone = target.cloneNode(frag); + assert.equal(clone.childNodes.length, 1, 'cloneNode should work after creating MutationObserver'); + } + }); + QUnit.test('cloneNode keeps non-default element namespace', function (assert) { + var frag = document.createDocumentFragment(); + var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + frag.appendChild(svg); + var clone = target.cloneNode(frag); + assert.equal(clone.firstChild.namespaceURI, 'http://www.w3.org/2000/svg', 'cloneNode should keep non-default element namespace'); + }); + QUnit.test('SVG namespaceURI', function (assert) { + var data = target([{ + tag: 'svg', + attrs: { + 'xmlns': { + value: 'http://www.w3.org/2000/svg', + namespaceURI: 'http://www.w3.org/2000/xmlns/' + } + } + }]); + var frag = data.hydrate(); + assert.equal(frag.firstChild.getAttributeNode('xmlns').namespaceURI, 'http://www.w3.org/2000/xmlns/'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-stache-converters@5.0.0#can-stache-converters*/ +define('can-stache-converters@5.0.0#can-stache-converters', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-stache', + 'can-string-to-any', + 'can-log/dev/dev', + 'can-stache-bindings', + 'can-stache-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var stache = require('can-stache'); + var stringToAny = require('can-string-to-any'); + var dev = require('can-log/dev/dev'); + var stacheBindings = require('can-stache-bindings'); + var stacheHelpers = require('can-stache-helpers'); + stache.addBindings(stacheBindings); + var shouldPop = false; + stache('{{echo(args(1))}}')({ + echo: function () { + }, + args: function () { + shouldPop = arguments.length > 1; + } + }); + stache.registerConverter('boolean-to-inList', { + get: function (item, list) { + if (!list) { + return false; + } else { + return list.indexOf(item) !== -1; + } + }, + set: function (newVal, item, list) { + if (!list) { + return; + } + if (!newVal) { + var idx = list.indexOf(item); + if (idx !== -1) { + list.splice(idx, 1); + } + } else { + list.push(item); + } + } + }); + var converters = { + 'string-to-any': { + get: function (obs) { + return '' + canReflect.getValue(obs); + }, + set: function (newVal, obs) { + var converted = stringToAny(newVal); + canReflect.setValue(obs, converted); + } + }, + 'index-to-selected': { + get: function (item, list) { + var val = canReflect.getValue(item); + var idx = canReflect.getValue(list).indexOf(val); + return idx; + }, + set: function (idx, item, list) { + var newVal = canReflect.getValue(list)[idx]; + canReflect.setValue(item, newVal); + } + }, + 'selected-to-index': { + get: function (idx, list) { + var val = canReflect.getValue(idx), listValue = canReflect.getValue(list); + var item = listValue[val]; + return item; + }, + set: function (item, idx, list) { + var newVal = canReflect.getValue(list).indexOf(item); + canReflect.setValue(idx, newVal); + } + }, + 'either-or': { + get: function (chosen, a, b) { + var chosenVal = canReflect.getValue(chosen), aValue = canReflect.getValue(a), bValue = canReflect.getValue(b); + var matchA = aValue === chosenVal; + var matchB = bValue === chosenVal; + if (!matchA && !matchB) { + return; + } else { + return matchA; + } + }, + set: function (newVal, chosen, a, b) { + var setVal = newVal ? canReflect.getValue(a) : canReflect.getValue(b); + canReflect.setValue(chosen, setVal); + } + }, + 'equal': { + get: function () { + var args = canReflect.toArray(arguments); + if (shouldPop) { + args.pop(); + } + if (args.length > 1) { + var comparer = canReflect.getValue(args.pop()); + return args.every(function (obs) { + var value = canReflect.getValue(obs); + return value === comparer; + }); + } + }, + set: function () { + var args = canReflect.toArray(arguments); + if (shouldPop) { + args.pop(); + } + if (args.length > 2) { + var b = args.shift(); + var comparer = canReflect.getValue(args.pop()); + if (b) { + for (var i = 0; i < args.length; i++) { + canReflect.setValue(args[i], comparer); + } + } + } + } + } + }; + stache.addConverter(converters); + if (!stacheHelpers.not) { + stache.addConverter('not', { + get: function (obs) { + return !canReflect.getValue(obs); + }, + set: function (newVal, obs) { + canReflect.setValue(obs, !newVal); + } + }); + } + module.exports = converters; +}); +/*can-stache-converters@5.0.0#test/boolean-to-inList_test*/ +define('can-stache-converters@5.0.0#test/boolean-to-inList_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/list/list', + 'can-define/map/map', + 'can-stache', + 'can-dom-events', + 'can-reflect', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var stache = require('can-stache'); + var domEvents = require('can-dom-events'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + QUnit.module('boolean-to-inList', { + beforeEach: function (assert) { + this.fixture = document.getElementById('qunit-fixture'); + } + }); + QUnit.test('Works with checkboxes', function (assert) { + var template = stache(''); + var map = new DefineMap({ + item: 2, + list: new DefineList([ + 1, + 2, + 3 + ]) + }); + var frag = template(map); + var input = frag.firstChild; + assert.ok(input.checked, 'it is initially checked'); + assert.equal(map.list.indexOf(2), 1, 'two is in the list'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.list.indexOf(2), -1, 'No longer in the list'); + map.item = 3; + assert.ok(input.checked, '3 is in the list'); + map.item = 5; + assert.ok(!input.checked, '5 is not in the list'); + map.list.push(5); + assert.ok(input.checked, 'Now 5 is in the list'); + map.item = 6; + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.list.indexOf(6), 3, 'pushed into the list'); + }); + QUnit.test('If there is no list, treated as false', function (assert) { + var template = stache(''); + var map = new DefineMap({ + item: 2, + list: undefined + }); + var frag = template(map); + var input = frag.firstChild; + assert.ok(!input.checked, 'not checked because there is no list'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.ok(true, 'no errors thrown'); + }); + QUnit.test('works with radio buttons', function (assert) { + var template = stache('
      '); + var map = new DefineMap({ names: ['Wilbur'] }); + var frag = template(map); + var radioOne = frag.firstChild.firstChild; + var radioTwo = radioOne.nextSibling; + this.fixture.appendChild(frag); + assert.equal(radioOne.checked, false, 'Matthew not checked'); + assert.equal(radioTwo.checked, true, 'Wilbur is checked'); + radioOne.checked = true; + domEvents.dispatch(radioOne, 'change'); + assert.equal(radioOne.checked, true, 'Matthew is checked'); + assert.equal(radioTwo.checked, false, 'Wilbur is not checked'); + }); +}); +/*can-stache-converters@5.0.0#test/index-to-selected_test*/ +define('can-stache-converters@5.0.0#test/index-to-selected_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/list/list', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'can-reflect', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + QUnit.module('index-to-selected'); + QUnit.test('chooses select option by the index from a list', function (assert) { + var template = stache(''); + var map = new DefineMap({ + person: 'Anne', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var select = template(map).firstChild; + assert.equal(select.value, 1, 'initially set to the first value'); + select.value = 2; + domEvents.dispatch(select, 'change'); + assert.equal(map.person, 'Wilbur', 'now it is me'); + map.person = map.people.item(0); + assert.equal(select.value, 0, 'set back'); + select.value = 'none'; + domEvents.dispatch(select, 'change'); + assert.equal(map.person, undefined, 'now undefined because not in the list'); + }); + QUnit.test('chooses select option by the index from a list without ~', function (assert) { + var template = stache(''); + var map = new DefineMap({ + person: 'Anne', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var select = template(map).firstChild; + assert.equal(select.value, 1, 'initially set to the first value'); + select.value = 2; + domEvents.dispatch(select, 'change'); + assert.equal(map.person, 'Wilbur', 'now it is me'); + map.person = map.people.item(0); + assert.equal(select.value, 0, 'set back'); + select.value = 'none'; + domEvents.dispatch(select, 'change'); + assert.equal(map.person, undefined, 'now undefined because not in the list'); + }); +}); +/*can-stache-converters@5.0.0#test/selected-to-index_test*/ +define('can-stache-converters@5.0.0#test/selected-to-index_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + QUnit.module('selected-to-index'); + QUnit.test('sets index by the value from a list', function (assert) { + var template = stache(''); + var map = new DefineMap({ + index: '1', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var input = template(map).firstChild; + assert.equal(input.value, 'Anne', 'initially set to the first value'); + input.value = 'Wilbur'; + domEvents.dispatch(input, 'change'); + assert.equal(map.index, '2', 'now it is me'); + map.index = '0'; + assert.equal(input.value, 'Matthew', 'set back'); + input.value = 'none'; + domEvents.dispatch(input, 'change'); + assert.equal(map.index, -1, 'now -1 because not in the list'); + }); + QUnit.test('sets index by the value from a list without ~', function (assert) { + var template = stache(''); + var map = new DefineMap({ + index: '1', + people: [ + 'Matthew', + 'Anne', + 'Wilbur' + ] + }); + var input = template(map).firstChild; + assert.equal(input.value, 'Anne', 'initially set to the first value'); + input.value = 'Wilbur'; + domEvents.dispatch(input, 'change'); + assert.equal(map.index, '2', 'now it is me'); + map.index = '0'; + assert.equal(input.value, 'Matthew', 'set back'); + input.value = 'none'; + domEvents.dispatch(input, 'change'); + assert.equal(map.index, -1, 'now -1 because not in the list'); + }); +}); +/*can-stache-converters@5.0.0#test/string-to-any_test*/ +define('can-stache-converters@5.0.0#test/string-to-any_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/list/list', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'can-reflect', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + QUnit.module('string-to-any'); + QUnit.test('Works on all the types', function (assert) { + var types = { + '22.3': 22.3, + 'foo': 'foo', + 'true': true, + 'false': false, + 'undefined': undefined, + 'null': null, + 'Infinity': Infinity, + 'NaN': { + expected: NaN, + equalityTest: function (a) { + return isNaN(a); + } + } + }; + var defaultEquality = function (a, b) { + return a === b; + }; + canReflect.eachKey(types, function (expected, type) { + var template = stache(''); + var map = new DefineMap({ val: 'test' }); + var frag = template(map); + var select = frag.firstChild; + var option = select.firstChild.nextSibling; + var equality = defaultEquality; + if (expected != null && expected.equalityTest) { + equality = expected.equalityTest; + expected = expected.expected; + } + select.value = type; + domEvents.dispatch(select, 'change'); + assert.ok(equality(map.val, expected), 'map\'s value updated to: ' + type); + map.val = 'test'; + map.val = expected; + assert.equal(select.value, type, 'select\'s value updated to: ' + type); + }); + }); + QUnit.test('Works on all the types without ~', function (assert) { + var types = { + '22.3': 22.3, + 'foo': 'foo', + 'true': true, + 'false': false, + 'undefined': undefined, + 'null': null, + 'Infinity': Infinity, + 'NaN': { + expected: NaN, + equalityTest: function (a) { + return isNaN(a); + } + } + }; + var defaultEquality = function (a, b) { + return a === b; + }; + canReflect.eachKey(types, function (expected, type) { + var template = stache(''); + var map = new DefineMap({ val: 'test' }); + var frag = template(map); + var select = frag.firstChild; + var option = select.firstChild.nextSibling; + var equality = defaultEquality; + if (expected != null && expected.equalityTest) { + equality = expected.equalityTest; + expected = expected.expected; + } + select.value = type; + domEvents.dispatch(select, 'change'); + assert.ok(equality(map.val, expected), 'map\'s value updated to: ' + type); + map.val = 'test'; + map.val = expected; + assert.equal(select.value, type, 'select\'s value updated to: ' + type); + }); + }); +}); +/*can-stache-converters@5.0.0#test/not_test*/ +define('can-stache-converters@5.0.0#test/not_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-define/list/list', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + QUnit.module('not'); + QUnit.test('saves the inverse of the selected value without ~ (#68)', function (assert) { + var template = stache(''); + var map = new DefineMap({ val: true }); + var input = template(map).firstChild; + assert.equal(input.checked, false, 'initially false'); + map.val = false; + assert.equal(input.checked, true, 'true because map val is false'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.val, true, 'map is now true because checkbox is false'); + }); + QUnit.test('saves the inverse of the selected value', function (assert) { + var template = stache(''); + var map = new DefineMap({ val: true }); + var input = template(map).firstChild; + assert.equal(input.checked, false, 'initially false'); + map.val = false; + assert.equal(input.checked, true, 'true because map val is false'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.val, true, 'map is now true because checkbox is false'); + }); + QUnit.test('works with boolean-to-inList', function (assert) { + var template = stache(''); + var map = new DefineMap({ + item: 2, + list: new DefineList([ + 1, + 2, + 3 + ]) + }); + var input = template(map).firstChild; + assert.equal(input.checked, false, 'not checked because it is in the list'); + map.item = 4; + assert.equal(input.checked, true, 'checked because not in the list'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.list.indexOf(4), 3, 'it was pushed into the list'); + map.list.splice(3, 1); + assert.equal(input.checked, true, 'now it\'s checked because not in the list'); + }); +}); +/*can-compute@4.1.1#proto-compute*/ +define('can-compute@4.1.1#proto-compute', [ + 'require', + 'exports', + 'module', + 'can-observation', + 'can-observation-recorder', + 'can-event-queue/map/map', + 'can-stache-key', + 'can-key/get/get', + 'can-assign', + 'can-reflect', + 'can-single-reference' +], function (require, exports, module) { + 'use strict'; + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var eventQueue = require('can-event-queue/map/map'); + var observeReader = require('can-stache-key'); + var getObject = require('can-key/get/get'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var singleReference = require('can-single-reference'); + var Compute = function (getterSetter, context, eventName, bindOnce) { + var args = []; + for (var i = 0, arglen = arguments.length; i < arglen; i++) { + args[i] = arguments[i]; + } + var contextType = typeof args[1]; + if (typeof args[0] === 'function') { + this._setupGetterSetterFn(args[0], args[1], args[2], args[3]); + } else if (args[1] !== undefined) { + if (contextType === 'string' || contextType === 'number') { + var isListLike = canReflect.isObservableLike(args[0]) && canReflect.isListLike(args[0]); + var isMapLike = canReflect.isObservableLike(args[0]) && canReflect.isMapLike(args[0]); + if (isMapLike || isListLike) { + var map = args[0]; + var propertyName = args[1]; + var mapGetterSetter = function (newValue) { + if (arguments.length) { + observeReader.set(map, propertyName, newValue); + } else { + if (isListLike) { + observeReader.get(map, 'length'); + } + return observeReader.get(map, '' + propertyName); + } + }; + this._setupGetterSetterFn(mapGetterSetter, args[1], args[2], args[3]); + } else { + this._setupProperty(args[0], args[1], args[2]); + } + } else if (contextType === 'function') { + this._setupSetter(args[0], args[1], args[2]); + } else { + if (args[1] && args[1].fn) { + this._setupAsyncCompute(args[0], args[1]); + } else { + this._setupSettings(args[0], args[1]); + } + } + } else { + this._setupSimpleValue(args[0]); + } + this._args = args; + this._primaryDepth = 0; + this.isComputed = true; + }; + var updateOnChange = function (compute, newValue, oldValue, batchNum) { + var valueChanged = newValue !== oldValue && !(newValue !== newValue && oldValue !== oldValue); + if (valueChanged) { + compute.dispatch({ + type: 'change', + batchNum: batchNum + }, [ + newValue, + oldValue + ]); + } + }; + var setupComputeHandlers = function (compute, func, context) { + var observation = new Observation(func, context, compute); + var updater = compute.updater.bind(compute); + compute.observation = observation; + return { + _on: function () { + canReflect.onValue(observation, updater, 'notify'); + if (observation.hasOwnProperty('_value')) { + compute.value = observation._value; + } else { + compute.value = observation.value; + } + }, + _off: function () { + canReflect.offValue(observation, updater, 'notify'); + }, + getDepth: function () { + return observation.getDepth(); + } + }; + }; + eventQueue(Compute.prototype); + assign(Compute.prototype, { + setPrimaryDepth: function (depth) { + this._primaryDepth = depth; + }, + _setupGetterSetterFn: function (getterSetter, context, eventName) { + this._set = context ? getterSetter.bind(context) : getterSetter; + this._get = context ? getterSetter.bind(context) : getterSetter; + this._canObserve = eventName === false ? false : true; + var handlers = setupComputeHandlers(this, getterSetter, context || this); + assign(this, handlers); + }, + _setupProperty: function (target, propertyName, eventName) { + var self = this, handler; + handler = function () { + self.updater(self._get(), self.value); + }; + this._get = function () { + return getObject(target, propertyName); + }; + this._set = function (value) { + var properties = propertyName.split('.'), leafPropertyName = properties.pop(); + if (properties.length) { + var targetProperty = getObject(target, properties.join('.')); + targetProperty[leafPropertyName] = value; + } else { + target[propertyName] = value; + } + }; + this._on = function (update) { + eventQueue.on.call(target, eventName || propertyName, handler); + this.value = this._get(); + }; + this._off = function () { + return eventQueue.off.call(target, eventName || propertyName, handler); + }; + }, + _setupSetter: function (initialValue, setter, eventName) { + this.value = initialValue; + this._set = setter; + assign(this, eventName); + }, + _setupSettings: function (initialValue, settings) { + this.value = initialValue; + this._set = settings.set || this._set; + this._get = settings.get || this._get; + if (!settings.__selfUpdater) { + var self = this, oldUpdater = this.updater; + this.updater = function () { + oldUpdater.call(self, self._get(), self.value); + }; + } + this._on = settings.on ? settings.on : this._on; + this._off = settings.off ? settings.off : this._off; + }, + _setupAsyncCompute: function (initialValue, settings) { + var self = this; + var getter = settings.fn; + var bindings; + this.value = initialValue; + this._setUpdates = true; + this.lastSetValue = new Compute(initialValue); + this._set = function (newVal) { + if (newVal === self.lastSetValue.get()) { + return this.value; + } + return self.lastSetValue.set(newVal); + }; + this._get = function () { + return getter.call(settings.context, self.lastSetValue.get()); + }; + if (getter.length === 0) { + bindings = setupComputeHandlers(this, getter, settings.context); + } else if (getter.length === 1) { + bindings = setupComputeHandlers(this, function () { + return getter.call(settings.context, self.lastSetValue.get()); + }, settings); + } else { + var oldUpdater = this.updater, resolve = ObservationRecorder.ignore(function (newVal) { + oldUpdater.call(self, newVal, self.value); + }); + this.updater = function (newVal) { + oldUpdater.call(self, newVal, self.value); + }; + bindings = setupComputeHandlers(this, function () { + var res = getter.call(settings.context, self.lastSetValue.get(), resolve); + return res !== undefined ? res : this.value; + }, this); + } + assign(this, bindings); + }, + _setupSimpleValue: function (initialValue) { + this.value = initialValue; + }, + _eventSetup: ObservationRecorder.ignore(function () { + this.bound = true; + this._on(this.updater); + }), + _eventTeardown: function () { + this._off(this.updater); + this.bound = false; + }, + clone: function (context) { + if (context && typeof this._args[0] === 'function') { + this._args[1] = context; + } else if (context) { + this._args[2] = context; + } + return new Compute(this._args[0], this._args[1], this._args[2], this._args[3]); + }, + _on: function () { + }, + _off: function () { + }, + get: function () { + var recordingObservation = ObservationRecorder.isRecording(); + if (recordingObservation && this._canObserve !== false) { + ObservationRecorder.add(this, 'change'); + if (!this.bound) { + Compute.temporarilyBind(this); + } + } + if (this.bound) { + if (this.observation) { + return this.observation.get(); + } else { + return this.value; + } + } else { + return this._get(); + } + }, + _get: function () { + return this.value; + }, + set: function (newVal) { + var old = this.value; + var setVal = this._set(newVal, old); + if (this._setUpdates) { + return this.value; + } + if (this.hasDependencies) { + return this._get(); + } + this.updater(setVal === undefined ? this._get() : setVal, old); + return this.value; + }, + _set: function (newVal) { + return this.value = newVal; + }, + updater: function (newVal, oldVal, batchNum) { + this.value = newVal; + var observation = this.observation; + if (observation) { + if (observation.hasOwnProperty('_value')) { + observation._value = newVal; + } else { + observation.value = newVal; + } + } + updateOnChange(this, newVal, oldVal, batchNum); + }, + toFunction: function () { + return this._computeFn.bind(this); + }, + _computeFn: function (newVal) { + if (arguments.length) { + return this.set(newVal); + } + return this.get(); + } + }); + Compute.prototype.on = Compute.prototype.bind = Compute.prototype.addEventListener; + Compute.prototype.off = Compute.prototype.unbind = Compute.prototype.removeEventListener; + var hasDependencies = function hasDependencies() { + return this.observation && this.observation.hasDependencies(); + }; + Object.defineProperty(Compute.prototype, 'hasDependencies', { get: hasDependencies }); + Compute.temporarilyBind = Observation.temporarilyBind; + Compute.async = function (initialValue, asyncComputer, context) { + return new Compute(initialValue, { + fn: asyncComputer, + context: context + }); + }; + Compute.truthy = function (compute) { + return new Compute(function () { + var res = compute.get(); + if (typeof res === 'function') { + res = res.get(); + } + return !!res; + }); + }; + canReflect.assignSymbols(Compute.prototype, { + 'can.isValueLike': true, + 'can.isMapLike': false, + 'can.isListLike': false, + 'can.setValue': Compute.prototype.set, + 'can.getValue': Compute.prototype.get, + 'can.valueHasDependencies': hasDependencies, + 'can.onValue': function onValue(handler, queue) { + function translationHandler(ev, newValue, oldValue) { + handler(newValue, oldValue); + } + singleReference.set(handler, this, translationHandler); + this.addEventListener('change', translationHandler, queue); + }, + 'can.offValue': function offValue(handler, queue) { + this.removeEventListener('change', singleReference.getAndDelete(handler, this), queue); + }, + 'can.getValueDependencies': function getValueDependencies() { + var ret; + if (this.observation) { + ret = { valueDependencies: new Set([this.observation]) }; + } + return ret; + } + }); + module.exports = exports = Compute; +}); +/*can-compute@4.1.1#can-compute*/ +define('can-compute@4.1.1#can-compute', [ + 'require', + 'exports', + 'module', + './proto-compute', + 'can-namespace', + 'can-single-reference', + 'can-reflect/reflections/get-set/get-set', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Compute = require('./proto-compute'); + var namespace = require('can-namespace'); + var singleReference = require('can-single-reference'); + var canReflect = require('can-reflect/reflections/get-set/get-set'); + var canSymbol = require('can-symbol'); + var canOnValueSymbol = canSymbol.for('can.onValue'), canOffValueSymbol = canSymbol.for('can.offValue'), canGetValue = canSymbol.for('can.getValue'), canSetValue = canSymbol.for('can.setValue'), isValueLike = canSymbol.for('can.isValueLike'), isMapLike = canSymbol.for('can.isMapLike'), isListLike = canSymbol.for('can.isListLike'), isFunctionLike = canSymbol.for('can.isFunctionLike'), canValueHasDependencies = canSymbol.for('can.valueHasDependencies'), canGetValueDependencies = canSymbol.for('can.getValueDependencies'); + var addEventListener = function (ev, handler) { + var compute = this; + var translationHandler; + if (handler) { + translationHandler = function () { + handler.apply(compute, arguments); + }; + singleReference.set(handler, this, translationHandler); + } + return compute.computeInstance.addEventListener(ev, translationHandler); + }; + var removeEventListener = function (ev, handler) { + var args = []; + if (typeof ev !== 'undefined') { + args.push(ev); + if (typeof handler !== 'undefined') { + args.push(singleReference.getAndDelete(handler, this)); + } + } + return this.computeInstance.removeEventListener.apply(this.computeInstance, args); + }; + var onValue = function (handler, queue) { + return this.computeInstance[canOnValueSymbol](handler, queue); + }, offValue = function (handler, queue) { + return this.computeInstance[canOffValueSymbol](handler, queue); + }, getValue = function () { + return this.computeInstance.get(); + }, setValue = function (value) { + return this.computeInstance.set(value); + }, hasDependencies = function () { + return this.computeInstance.hasDependencies; + }, getDependencies = function () { + return this.computeInstance[canGetValueDependencies](); + }; + var COMPUTE = function (getterSetter, context, eventName, bindOnce) { + function compute(val) { + if (arguments.length) { + return compute.computeInstance.set(val); + } + return compute.computeInstance.get(); + } + compute.computeInstance = new Compute(getterSetter, context, eventName, bindOnce); + compute.on = compute.bind = compute.addEventListener = addEventListener; + compute.off = compute.unbind = compute.removeEventListener = removeEventListener; + compute.isComputed = compute.computeInstance.isComputed; + compute.clone = function (ctx) { + if (typeof getterSetter === 'function') { + context = ctx; + } + return COMPUTE(getterSetter, context, ctx, bindOnce); + }; + canReflect.set(compute, canOnValueSymbol, onValue); + canReflect.set(compute, canOffValueSymbol, offValue); + canReflect.set(compute, canGetValue, getValue); + canReflect.set(compute, canSetValue, setValue); + canReflect.set(compute, isValueLike, true); + canReflect.set(compute, isMapLike, false); + canReflect.set(compute, isListLike, false); + canReflect.set(compute, isFunctionLike, false); + canReflect.set(compute, canValueHasDependencies, hasDependencies); + canReflect.set(compute, canGetValueDependencies, getDependencies); + return compute; + }; + COMPUTE.truthy = function (compute) { + return COMPUTE(function () { + var res = compute(); + return !!res; + }); + }; + COMPUTE.async = function (initialValue, asyncComputer, context) { + return COMPUTE(initialValue, { + fn: asyncComputer, + context: context + }); + }; + COMPUTE.temporarilyBind = Compute.temporarilyBind; + module.exports = namespace.compute = COMPUTE; +}); +/*can-stache-converters@5.0.0#test/either-or_test*/ +define('can-stache-converters@5.0.0#test/either-or_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-compute', + 'can-define/map/map', + 'can-dom-events', + 'can-stache', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var compute = require('can-compute'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + QUnit.module('either-or'); + QUnit.test('can bind to a checkbox', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ pref: 'Star Trek' }); + var input = renderer(map).firstChild; + assert.equal(input.checked, true, 'initial value is right'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref, 'Star Wars', 'changed because input changed'); + map.pref = 'Star Trek'; + assert.equal(input.checked, true, 'changed because map changed'); + }); + QUnit.test('initial null selection', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ pref: null }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref, 'No', 'null value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref, 'Yes', 'map updated because check was checked'); + }); + QUnit.test('initial undefined selection', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ pref: undefined }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref, 'No', 'undefined value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref, 'Yes', 'map updated because check was checked'); + }); + QUnit.test('initial no match selection', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ pref: 'fubar' }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref, 'No', 'fubar value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref, 'Yes', 'map updated because check was checked'); + }); + QUnit.test('supports computes', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ + pref: compute('Maybe'), + a: compute('Yes'), + b: compute('No') + }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref(), 'No', 'chosen value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref(), 'Yes', 'map updated because check was checked'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref(), 'No', 'map updated because check was unchecked'); + }); + QUnit.test('supports computes without ~', function (assert) { + var renderer = stache(''); + var map = new DefineMap({ + pref: compute('Maybe'), + a: compute('Yes'), + b: compute('No') + }); + var input = renderer(map).firstChild; + assert.equal(input.checked, false, 'checkbox is unchecked'); + assert.strictEqual(map.pref(), 'No', 'chosen value changed to falsey case by checkbox'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref(), 'Yes', 'map updated because check was checked'); + input.checked = false; + domEvents.dispatch(input, 'change'); + assert.equal(map.pref(), 'No', 'map updated because check was unchecked'); + }); +}); +/*can-stache-converters@5.0.0#test/equal_test*/ +define('can-stache-converters@5.0.0#test/equal_test', [ + 'require', + 'exports', + 'module', + 'can-stache-converters', + 'can-compute', + 'can-dom-events', + 'can-stache', + 'can-define/list/list', + 'can-define/map/map', + 'steal-qunit' +], function (require, exports, module) { + require('can-stache-converters'); + var compute = require('can-compute'); + var domEvents = require('can-dom-events'); + var stache = require('can-stache'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var QUnit = require('steal-qunit'); + QUnit.module('can-stache-converters: equal'); + QUnit.test('Basics works', function (assert) { + var template = stache(''); + var attending = compute('yes'); + var yes = template({ attending: attending }).firstChild, no = yes.nextSibling; + assert.equal(yes.checked, true, 'initially a yes'); + assert.equal(no.checked, false, 'initially unchecked'); + attending('no'); + assert.equal(yes.checked, false, 'now not checked'); + assert.equal(no.checked, true, 'now checked'); + yes.checked = true; + domEvents.dispatch(yes, 'change'); + assert.equal(attending(), 'yes', 'now it is yes'); + assert.equal(yes.checked, true, 'yes is checked'); + assert.equal(no.checked, false, 'no is unchecked'); + }); + QUnit.test('works without ~', function (assert) { + var template = stache(''); + var attending = compute('yes'); + var yes = template({ attending: attending }).firstChild, no = yes.nextSibling; + assert.equal(yes.checked, true, 'initially a yes'); + assert.equal(no.checked, false, 'initially unchecked'); + attending('no'); + assert.equal(yes.checked, false, 'now not checked'); + assert.equal(no.checked, true, 'now checked'); + yes.checked = true; + domEvents.dispatch(yes, 'change'); + assert.equal(attending(), 'yes', 'now it is yes'); + assert.equal(yes.checked, true, 'yes is checked'); + assert.equal(no.checked, false, 'no is unchecked'); + }); + QUnit.test('Allows one-way binding when passed a non-compute as the first argument', function (assert) { + var template = stache(''); + var attending = compute(false); + var input = template({ attending: attending }).firstChild; + assert.equal(input.checked, false, 'initially false'); + attending(true); + assert.equal(input.checked, true, 'can be changed to true'); + input.checked = false; + assert.equal(attending(), true, 'does not change compute'); + }); + QUnit.test('Allow multiple expressions to be passed in', function (assert) { + var template = stache(''); + var foo = compute(true); + var bar = compute(false); + var input = template({ + foo: foo, + bar: bar + }).firstChild; + assert.equal(input.checked, false, 'initially unchecked'); + bar(true); + assert.equal(input.checked, true, 'now checked'); + foo(false); + bar(false); + assert.equal(input.checked, false, 'now unchecked'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(foo(), true, 'computed foo value is true'); + assert.equal(bar(), true, 'computed bar value is true'); + }); + QUnit.test('Allow multiple expressions to be passed in without ~', function (assert) { + var template = stache(''); + var foo = compute(true); + var bar = compute(false); + var input = template({ + foo: foo, + bar: bar + }).firstChild; + assert.equal(input.checked, false, 'initially unchecked'); + bar(true); + assert.equal(input.checked, true, 'now checked'); + foo(false); + bar(false); + assert.equal(input.checked, false, 'now unchecked'); + input.checked = true; + domEvents.dispatch(input, 'change'); + assert.equal(foo(), true, 'computed foo value is true'); + assert.equal(bar(), true, 'computed bar value is true'); + }); + QUnit.test('Allow non static values', function (assert) { + var template = stache('{{# each(foo) }}{{/ each}}'); + var foo = new DefineList(['foobar']); + var bar = new DefineMap({ value: 'zed' }); + var input = template({ + foo: foo, + bar: bar + }).querySelector('input'); + assert.equal(input.checked, false, 'initially unchecked'); + bar.value = 'foobar'; + assert.equal(input.checked, true, 'now checked'); + }); +}); +/*can-stache-converters@5.0.0#test/test*/ +define('can-stache-converters@5.0.0#test/test', [ + 'require', + 'exports', + 'module', + './boolean-to-inList_test', + './index-to-selected_test', + './selected-to-index_test', + './string-to-any_test', + './not_test', + './either-or_test', + './equal_test' +], function (require, exports, module) { + require('./boolean-to-inList_test'); + require('./index-to-selected_test'); + require('./selected-to-index_test'); + require('./string-to-any_test'); + require('./not_test'); + require('./either-or_test'); + require('./equal_test'); +}); +/*can-component@5.0.0#test/helpers*/ +define('can-component@5.0.0#test/helpers', [ + 'require', + 'exports', + 'module', + 'can-globals/mutation-observer/mutation-observer', + 'can-globals', + 'can-globals/document/document', + 'can-vdom/make-document/make-document', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-globals', + 'can-child-nodes' +], function (require, exports, module) { + (function (global, require, exports, module) { + var MUTATION_OBSERVER = require('can-globals/mutation-observer/mutation-observer'); + var globals = require('can-globals'); + var DOCUMENT = require('can-globals/document/document'); + var makeDocument = require('can-vdom/make-document/make-document'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var globals = require('can-globals'); + var childNodes = require('can-child-nodes'); + var ArrayFrom = function () { + var toStr = Object.prototype.toString; + var isCallable = function (fn) { + return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; + }; + var toInteger = function (value) { + var number = Number(value); + if (isNaN(number)) { + return 0; + } + if (number === 0 || !isFinite(number)) { + return number; + } + return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); + }; + var maxSafeInteger = Math.pow(2, 53) - 1; + var toLength = function (value) { + var len = toInteger(value); + return Math.min(Math.max(len, 0), maxSafeInteger); + }; + return function from(arrayLike) { + var C = this; + var items = Object(arrayLike); + if (arrayLike == null) { + throw new TypeError('Array.from requires an array-like object - not null or undefined'); + } + var mapFn = arguments.length > 1 ? arguments[1] : void undefined; + var T; + if (typeof mapFn !== 'undefined') { + if (!isCallable(mapFn)) { + throw new TypeError('Array.from: when provided, the second argument must be a function'); + } + if (arguments.length > 2) { + T = arguments[2]; + } + } + var len = toLength(items.length); + var A = isCallable(C) ? Object(new C(len)) : new Array(len); + var k = 0; + var kValue; + while (k < len) { + kValue = items[k]; + if (mapFn) { + A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); + } else { + A[k] = kValue; + } + k += 1; + } + A.length = len; + return A; + }; + }(); + var removePlaceholderNodes = function (node) { + var children = ArrayFrom(childNodes(node)); + for (var i = 0; i < children.length; i++) { + if (children[i].nodeType === Node.COMMENT_NODE) { + node.removeChild(children[i]); + } else if (children[i].nodeType === Node.ELEMENT_NODE) { + removePlaceholderNodes(children[i]); + } + } + return node; + }; + function cloneAndClean(node) { + return removePlaceholderNodes(node.cloneNode(true)); + } + var helpers = { + runTasks: function (tasks, done) { + var nextTask = function () { + var next = tasks.shift(); + next(); + if (tasks.length) { + setTimeout(nextTask, 100); + } else { + done(); + } + }; + setTimeout(nextTask, 100); + }, + makeTest: function (name, doc, mutObs, test, qUnitTest) { + var DOC = DOCUMENT(); + QUnit.module(name, { + beforeEach: function (assert) { + DOCUMENT(doc); + if (!mutObs) { + globals.setKeyValue('MutationObserver', mutObs); + } + if (doc) { + this.document = doc; + this.fixture = doc.createElement('div'); + doc.body.appendChild(this.fixture); + } else { + this.fixture = doc.getElementById('qunit-fixture'); + } + }, + afterEach: function (assert) { + doc.body.removeChild(this.fixture); + var done = assert.async(); + setTimeout(function () { + done(); + DOCUMENT(DOC); + globals.deleteKeyValue('MutationObserver'); + }, 100); + } + }); + test(doc, qUnitTest); + }, + makeTests: function (name, test) { + helpers.makeTest(name + ' - dom', document, MUTATION_OBSERVER(), test, QUnit.test); + helpers.makeTest(name + ' - vdom', makeDocument(), null, test, function () { + }); + }, + afterMutation: function (cb) { + var doc = globals.getKeyValue('document'); + var div = doc.createElement('div'); + var insertionDisposal = domMutate.onNodeInsertion(div, function () { + insertionDisposal(); + doc.body.removeChild(div); + setTimeout(cb, 5); + }); + setTimeout(function () { + domMutateNode.appendChild.call(doc.body, div); + }, 10); + }, + cloneAndClean: cloneAndClean + }; + module.exports = helpers; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@5.0.0#control/control*/ +define('can-component@5.0.0#control/control', [ + 'require', + 'exports', + 'module', + 'can-control', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var Control = require('can-control'); + var canReflect = require('can-reflect'); + var paramReplacer = /\{([^\}]+)\}/g; + var ComponentControl = Control.extend({ + _lookup: function (options) { + return [ + options.scope, + options, + window + ]; + }, + _removeDelegateFromKey: function (key) { + return key.replace(/^(scope|^viewModel)\./, ''); + }, + _isDelegate: function (options, key) { + return key === 'scope' || key === 'viewModel'; + }, + _getDelegate: function (options, key) { + return options[key]; + }, + _action: function (methodName, options, controlInstance) { + var hasObjectLookup; + paramReplacer.lastIndex = 0; + hasObjectLookup = paramReplacer.test(methodName); + if (!controlInstance && hasObjectLookup) { + return; + } else { + return Control._action.apply(this, arguments); + } + } + }, { + setup: function (el, options) { + this.scope = options.scope; + this.viewModel = options.viewModel; + return Control.prototype.setup.call(this, el, options); + }, + off: function () { + if (this._bindings) { + canReflect.eachKey(this._bindings.readyComputes || {}, function (value) { + canReflect.offValue(value.compute, value.handler); + }); + } + Control.prototype.off.apply(this, arguments); + this._bindings.readyComputes = {}; + }, + destroy: function () { + if (typeof this.options.destroy === 'function') { + this.options.destroy.apply(this, arguments); + } + Control.prototype.destroy.apply(this, arguments); + } + }); + module.exports = ComponentControl; +}); +/*can-component@5.0.0#can-component*/ +define('can-component@5.0.0#can-component', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-bind', + 'can-construct', + 'can-stache', + 'can-stache-bindings', + 'can-view-scope', + 'can-view-callbacks', + 'can-reflect', + 'can-simple-observable', + 'can-simple-map', + 'can-define/map/map', + 'can-log', + 'can-log/dev/dev', + 'can-assign', + 'can-observation-recorder', + 'can-queues', + 'can-dom-data', + 'can-string', + 'can-dom-events', + 'can-dom-mutate', + 'can-dom-mutate/node', + 'can-symbol', + 'can-globals/document/document', + './control/control', + 'can-view-model', + 'can-define/list/list' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var Bind = require('can-bind'); + var Construct = require('can-construct'); + var stache = require('can-stache'); + var stacheBindings = require('can-stache-bindings'); + var Scope = require('can-view-scope'); + var viewCallbacks = require('can-view-callbacks'); + var canReflect = require('can-reflect'); + var SimpleObservable = require('can-simple-observable'); + var SimpleMap = require('can-simple-map'); + var DefineMap = require('can-define/map/map'); + var canLog = require('can-log'); + var canDev = require('can-log/dev/dev'); + var assign = require('can-assign'); + var ObservationRecorder = require('can-observation-recorder'); + var queues = require('can-queues'); + var domData = require('can-dom-data'); + var string = require('can-string'); + var domEvents = require('can-dom-events'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node'); + var canSymbol = require('can-symbol'); + var DOCUMENT = require('can-globals/document/document'); + var ComponentControl = require('./control/control'); + require('can-view-model'); + require('can-define/list/list'); + stache.addBindings(stacheBindings); + var createdByCanComponentSymbol = canSymbol('can.createdByCanComponent'); + var getValueSymbol = canSymbol.for('can.getValue'); + var setValueSymbol = canSymbol.for('can.setValue'); + var viewInsertSymbol = canSymbol.for('can.viewInsert'); + var viewModelSymbol = canSymbol.for('can.viewModel'); + function addContext(el, tagData, insertionElementTagData) { + var vm, newScope; + domData.set(el, 'preventDataBindings', true); + var teardown = stacheBindings.behaviors.viewModel(el, insertionElementTagData, function createViewModel(initialData, hasDataBinding, bindingState) { + if (bindingState && bindingState.isSettingOnViewModel === true) { + newScope = tagData.scope.addLetContext(initialData); + return newScope._context; + } else { + return vm = new SimpleObservable(initialData); + } + }, undefined, true); + if (!teardown) { + return tagData; + } else { + return assign(assign({}, tagData), { + teardown: teardown, + scope: newScope || tagData.scope.add(vm) + }); + } + } + function makeReplacementTagCallback(tagName, componentTagData, shadowTagData, leakScope, getPrimaryTemplate) { + var options = shadowTagData.options; + return function replacementTag(el, insertionElementTagData) { + var template = getPrimaryTemplate(el) || insertionElementTagData.subtemplate, renderingLightContent = template !== insertionElementTagData.subtemplate; + if (template) { + delete options.tags[tagName]; + var tagData; + if (renderingLightContent) { + if (leakScope.toLightContent) { + tagData = addContext(el, { + scope: insertionElementTagData.scope.cloneFromRef(), + options: insertionElementTagData.options + }, insertionElementTagData); + } else { + tagData = addContext(el, componentTagData, insertionElementTagData); + } + } else { + tagData = addContext(el, insertionElementTagData, insertionElementTagData); + } + var fragment = template(tagData.scope, tagData.options); + if (tagData.teardown) { + var placeholder = el.ownerDocument.createComment(tagName); + fragment.insertBefore(placeholder, fragment.firstChild); + domMutate.onNodeRemoved(placeholder, tagData.teardown); + } + el.parentNode.replaceChild(fragment, el); + options.tags[tagName] = replacementTag; + } + }; + } + function getSetupFunctionForComponentVM(componentInitVM) { + return ObservationRecorder.ignore(function (el, componentTagData, makeViewModel, initialVMData) { + var bindingContext = { + element: el, + scope: componentTagData.scope, + parentNodeList: componentTagData.parentNodeList, + viewModel: undefined + }; + var bindingSettings = {}; + var bindings = []; + canReflect.eachKey(componentInitVM, function (parent, propName) { + var canGetParentValue = parent != null && !!parent[getValueSymbol]; + var canSetParentValue = parent != null && !!parent[setValueSymbol]; + if (canGetParentValue === true || canSetParentValue) { + var child = stacheBindings.getObservableFrom.viewModel({ name: propName }, bindingContext, bindingSettings); + var canBinding = new Bind({ + child: child, + parent: parent, + queue: 'dom', + element: el + }); + bindings.push({ + binding: canBinding, + siblingBindingData: { + parent: { + source: 'scope', + exports: canGetParentValue + }, + child: { + source: 'viewModel', + exports: canSetParentValue, + name: propName + } + } + }); + } else { + initialVMData[propName] = parent; + } + }); + var initializeData = stacheBindings.behaviors.initializeViewModel(bindings, initialVMData, function (properties) { + return bindingContext.viewModel = makeViewModel(properties); + }, bindingContext); + return function () { + for (var attrName in initializeData.onTeardowns) { + initializeData.onTeardowns[attrName](); + } + }; + }); + } + var Component = Construct.extend({ + setup: function () { + Construct.setup.apply(this, arguments); + if (Component) { + var self = this; + if (this.prototype.events !== undefined && canReflect.size(this.prototype.events) !== 0) { + this.Control = ComponentControl.extend(this.prototype.events); + } + var protoViewModel = this.prototype.viewModel || this.prototype.scope; + if (protoViewModel && this.prototype.ViewModel) { + throw new Error('Cannot provide both a ViewModel and a viewModel property'); + } + var vmName = string.capitalize(string.camelize(this.prototype.tag)) + 'VM'; + if (this.prototype.ViewModel) { + if (typeof this.prototype.ViewModel === 'function') { + this.ViewModel = this.prototype.ViewModel; + } else { + this.ViewModel = DefineMap.extend(vmName, {}, this.prototype.ViewModel); + } + } else { + if (protoViewModel) { + if (typeof protoViewModel === 'function') { + if (canReflect.isObservableLike(protoViewModel.prototype) && canReflect.isMapLike(protoViewModel.prototype)) { + this.ViewModel = protoViewModel; + } else { + this.viewModelHandler = protoViewModel; + } + } else { + if (canReflect.isObservableLike(protoViewModel) && canReflect.isMapLike(protoViewModel)) { + this.viewModelInstance = protoViewModel; + } else { + canLog.warn('can-component: ' + this.prototype.tag + ' is extending the viewModel into a can-simple-map'); + this.ViewModel = SimpleMap.extend(vmName, {}, protoViewModel); + } + } + } else { + this.ViewModel = SimpleMap.extend(vmName, {}, {}); + } + } + if (this.prototype.template) { + this.view = this.prototype.template; + } + if (this.prototype.view) { + this.view = this.prototype.view; + } + if (typeof this.view === 'string') { + var viewName = string.capitalize(string.camelize(this.prototype.tag)) + 'View'; + this.view = stache(viewName, this.view); + } + this.renderer = this.view; + var renderComponent = function (el, tagData) { + if (el[createdByCanComponentSymbol] === undefined) { + new self(el, tagData); + } + }; + viewCallbacks.tag(this.prototype.tag, renderComponent); + } + } + }, { + setup: function (el, componentTagData) { + this._initialArgs = [ + el, + componentTagData + ]; + var component = this; + var options = { + helpers: {}, + tags: {} + }; + if (componentTagData === undefined) { + if (el === undefined) { + componentTagData = {}; + } else { + componentTagData = el; + el = undefined; + } + } + if (el === undefined) { + el = DOCUMENT().createElement(this.tag); + el[createdByCanComponentSymbol] = true; + } + this.element = el; + if (componentTagData.initializeBindings === false && !this._skippedSetup) { + this._skippedSetup = this._torndown = true; + this.viewModel = Object.create(null); + return; + } + var componentContent = componentTagData.content; + if (componentContent !== undefined) { + if (typeof componentContent === 'function') { + componentTagData.subtemplate = componentContent; + } else if (typeof componentContent === 'string') { + componentTagData.subtemplate = stache(componentContent); + } + } + var componentScope = componentTagData.scope; + if (componentScope !== undefined && componentScope instanceof Scope === false) { + componentTagData.scope = new Scope(componentScope); + } + var componentTemplates = componentTagData.templates; + if (componentTemplates !== undefined) { + canReflect.eachKey(componentTemplates, function (template, name) { + if (typeof template === 'string') { + var debugName = name + ' template'; + componentTemplates[name] = stache(debugName, template); + } + }); + } + var viewModel; + var initialViewModelData = {}; + var preventDataBindings = domData.get(el, 'preventDataBindings'); + var teardownBindings; + if (preventDataBindings) { + viewModel = el[viewModelSymbol]; + } else { + var setupFn; + if (componentTagData.setupBindings) { + setupFn = function (el, componentTagData, callback, initialViewModelData) { + return componentTagData.setupBindings(el, callback, initialViewModelData); + }; + } else if (componentTagData.viewModel) { + setupFn = getSetupFunctionForComponentVM(componentTagData.viewModel); + } else { + setupFn = stacheBindings.behaviors.viewModel; + } + teardownBindings = setupFn(el, componentTagData, function (initialViewModelData) { + var ViewModel = component.constructor.ViewModel, viewModelHandler = component.constructor.viewModelHandler, viewModelInstance = component.constructor.viewModelInstance; + if (viewModelHandler) { + var scopeResult = viewModelHandler.call(component, initialViewModelData, componentTagData.scope, el); + if (canReflect.isObservableLike(scopeResult) && canReflect.isMapLike(scopeResult)) { + viewModelInstance = scopeResult; + } else if (canReflect.isObservableLike(scopeResult.prototype) && canReflect.isMapLike(scopeResult.prototype)) { + ViewModel = scopeResult; + } else { + ViewModel = SimpleMap.extend(scopeResult); + } + } + if (ViewModel) { + viewModelInstance = new ViewModel(initialViewModelData); + } + viewModel = viewModelInstance; + return viewModelInstance; + }, initialViewModelData); + } + this.viewModel = viewModel; + el[viewModelSymbol] = viewModel; + el.viewModel = viewModel; + domData.set(el, 'preventDataBindings', true); + var removedDisposal, connectedDisposal, viewModelDisconnectedCallback; + function teardownComponent() { + if (removedDisposal) { + removedDisposal(); + removedDisposal = null; + } + component._torndown = true; + domEvents.dispatch(el, 'beforeremove', false); + if (teardownBindings) { + teardownBindings(); + } + if (viewModelDisconnectedCallback) { + viewModelDisconnectedCallback(el); + } else if (typeof viewModel.stopListening === 'function') { + viewModel.stopListening(); + } + if (connectedDisposal) { + connectedDisposal(); + connectedDisposal = null; + } + } + if (this.helpers !== undefined) { + canReflect.eachKey(this.helpers, function (val, prop) { + if (typeof val === 'function') { + options.helpers[prop] = val.bind(viewModel); + } + }); + } + if (this.constructor.Control) { + this._control = new this.constructor.Control(el, { + scope: this.viewModel, + viewModel: this.viewModel + }); + } + removedDisposal = domMutate.onNodeRemoved(el, function () { + var doc = el.ownerDocument; + var rootNode = doc.contains ? doc : doc.documentElement; + if (!rootNode || !rootNode.contains(el)) { + teardownComponent(); + } + }); + var leakScope = { + toLightContent: this.leakScope === true, + intoShadowContent: this.leakScope === true + }; + var hasShadowView = !!this.constructor.view; + var shadowFragment; + var betweenTagsView; + var betweenTagsTagData; + if (hasShadowView) { + var shadowTagData; + if (leakScope.intoShadowContent) { + shadowTagData = { + scope: componentTagData.scope.add(this.viewModel, { viewModel: true }), + options: options + }; + } else { + shadowTagData = { + scope: new Scope(this.viewModel, null, { viewModel: true }), + options: options + }; + } + options.tags['can-slot'] = makeReplacementTagCallback('can-slot', componentTagData, shadowTagData, leakScope, function (el) { + var templates = componentTagData.templates; + if (templates) { + return templates[el.getAttribute('name')]; + } + }); + options.tags.content = makeReplacementTagCallback('content', componentTagData, shadowTagData, leakScope, function () { + return componentTagData.subtemplate; + }); + betweenTagsView = this.constructor.view; + betweenTagsTagData = shadowTagData; + } else { + var lightTemplateTagData = { + scope: componentTagData.scope.add(this.viewModel, { viewModel: true }), + options: options + }; + betweenTagsTagData = lightTemplateTagData; + betweenTagsView = componentTagData.subtemplate || el.ownerDocument.createDocumentFragment.bind(el.ownerDocument); + } + shadowFragment = betweenTagsView(betweenTagsTagData.scope, betweenTagsTagData.options); + domMutateNode.appendChild.call(el, shadowFragment); + if (viewModel && viewModel.connectedCallback) { + var body = DOCUMENT().body; + var componentInPage = body && body.contains(el); + if (componentInPage) { + viewModelDisconnectedCallback = viewModel.connectedCallback(el); + } else { + connectedDisposal = domMutate.onNodeConnected(el, function () { + connectedDisposal(); + connectedDisposal = null; + viewModelDisconnectedCallback = viewModel.connectedCallback(el); + }); + } + } + component._torndown = false; + } + }); + Component.prototype[viewInsertSymbol] = function (viewData) { + if (this._torndown) { + this.setup.apply(this, this._initialArgs); + } + return this.element; + }; + module.exports = namespace.Component = Component; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@5.0.0#test/component-tag-test*/ +define('can-component@5.0.0#test/component-tag-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + helpers.makeTests('can-component tag', function () { + QUnit.test('hyphen-less tag names', function (assert) { + Component.extend({ + tag: 'foobar', + view: stache('
      {{name}}
      '), + viewModel: function () { + return new SimpleMap({ name: 'Brian' }); + } + }); + var renderer = stache(''); + var frag = renderer(); + assert.equal(frag.lastChild.firstChild.firstChild.nodeValue, 'Brian'); + }); + }); +}); +/*can-component@5.0.0#test/component-viewmodel-test*/ +define('can-component@5.0.0#test/component-viewmodel-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-dom-data', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component', + 'can-view-model', + 'can-define/map/map', + 'can-define/list/list', + 'can-view-scope', + 'can-simple-observable/setter/setter', + 'can-simple-observable', + 'can-reflect', + 'can-symbol', + 'can-dom-events', + 'can-dom-mutate/node', + 'can-construct', + 'can-view-callbacks' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var canData = require('can-dom-data'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + var canViewModel = require('can-view-model'); + var DefineMap = require('can-define/map/map'); + var DefineList = require('can-define/list/list'); + var Scope = require('can-view-scope'); + var SetterObservable = require('can-simple-observable/setter/setter'); + var SimpleObservable = require('can-simple-observable'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var domEvents = require('can-dom-events'); + var domMutateNode = require('can-dom-mutate/node'); + var Construct = require('can-construct'); + var tag = require('can-view-callbacks').tag; + var innerHTML = function (el) { + return el && el.innerHTML; + }; + helpers.makeTests('can-component viewModels', function () { + QUnit.test('a SimpleMap constructor as .ViewModel', function (assert) { + var map = new SimpleMap({ name: 'Matthew' }); + Component.extend({ + tag: 'can-map-viewmodel', + view: stache('{{name}}'), + ViewModel: function () { + return map; + } + }); + var renderer = stache(''); + assert.equal(renderer().firstChild.firstChild.nodeValue, 'Matthew'); + }); + QUnit.test('a SimpleMap as viewModel', function (assert) { + var me = new SimpleMap({ name: 'Justin' }); + Component.extend({ + tag: 'my-viewmodel', + view: stache('{{name}}}'), + viewModel: me + }); + var renderer = stache(''); + assert.equal(renderer().firstChild.firstChild.nodeValue, 'Justin'); + }); + QUnit.test('a SimpleMap constructor as viewModel', function (assert) { + var MyMap = SimpleMap.extend({ + setup: function (props) { + props.name = 'Matthew'; + return SimpleMap.prototype.setup.apply(this, arguments); + } + }); + Component.extend({ + tag: 'can-map-viewmodel', + view: stache('{{name}}'), + viewModel: MyMap + }); + var renderer = stache(''); + assert.equal(renderer().firstChild.firstChild.nodeValue, 'Matthew'); + }); + QUnit.test('an object is turned into a SimpleMap as viewModel', function (assert) { + Component.extend({ + tag: 'can-map-viewmodel', + view: stache('{{name}}'), + viewModel: { name: 'Matthew' } + }); + var renderer = stache(''); + var fragOne = renderer(); + var vmOne = canViewModel(fragOne.firstChild); + var fragTwo = renderer(); + vmOne.set('name', 'Wilbur'); + assert.equal(fragOne.firstChild.firstChild.nodeValue, 'Wilbur', 'The first map changed values'); + assert.equal(fragTwo.firstChild.firstChild.nodeValue, 'Matthew', 'The second map did not change'); + }); + QUnit.test('Providing viewModel and ViewModel throws', function (assert) { + try { + Component.extend({ + tag: 'viewmodel-test', + view: stache('
      '), + viewModel: {}, + ViewModel: SimpleMap.extend({}) + }); + assert.ok(false, 'Should have thrown because we provided both'); + } catch (er) { + assert.ok(true, 'It threw because we provided both viewModel and ViewModel'); + } + }); + QUnit.test('canViewModel utility', function (assert) { + Component({ + tag: 'my-taggy-tag', + view: stache('

      hello

      '), + viewModel: function () { + return new SimpleMap({ foo: 'bar' }); + } + }); + var frag = stache('')(); + var el = frag.firstChild; + assert.equal(canViewModel(el), el[canSymbol.for('can.viewModel')], 'one argument grabs the viewModel object'); + assert.equal(canViewModel(el, 'foo'), 'bar', 'two arguments fetches a value'); + canViewModel(el, 'foo', 'baz'); + assert.equal(canViewModel(el, 'foo'), 'baz', 'Three arguments sets the value'); + }); + QUnit.test('setting passed variables - two way binding', function (assert) { + Component.extend({ + tag: 'my-toggler', + view: stache('{{#if visible}}{{/if}}'), + leakScope: true, + ViewModel: DefineMap.extend({ + visible: { value: true }, + show: function () { + this.set('visible', true); + }, + hide: function () { + this.set('visible', false); + } + }) + }); + Component.extend({ + tag: 'my-app', + ViewModel: DefineMap.extend({ + visible: { value: true }, + show: function () { + this.set('visible', true); + } + }) + }); + var renderer = stache('' + '{{^visible}}{{/visible}}' + '' + 'content' + '' + '' + ''); + var frag = renderer({}); + var myApp = frag.firstChild, buttons = myApp.getElementsByTagName('button'); + assert.equal(buttons.length, 1, 'there is one button'); + assert.equal(innerHTML(buttons[0]), 'hide', 'the button\'s text is hide'); + domEvents.dispatch(buttons[0], 'click'); + buttons = myApp.getElementsByTagName('button'); + assert.equal(buttons.length, 1, 'there is one button'); + assert.equal(innerHTML(buttons[0]), 'show', 'the button\'s text is show'); + domEvents.dispatch(buttons[0], 'click'); + buttons = myApp.getElementsByTagName('button'); + assert.equal(buttons.length, 1, 'there is one button'); + assert.equal(innerHTML(buttons[0]), 'hide', 'the button\'s text is hide'); + }); + QUnit.test('don\'t update computes unnecessarily', function (assert) { + var sourceAge = new SimpleObservable(30), timesComputeIsCalled = 0; + var age = new SetterObservable(function () { + timesComputeIsCalled++; + if (timesComputeIsCalled === 1) { + assert.ok(true, 'reading initial value to set as years'); + } else if (timesComputeIsCalled === 3) { + assert.ok(true, 'called back another time after set to get the value'); + } else { + assert.ok(false, '(getter) You\'ve called the callback ' + timesComputeIsCalled + ' times'); + } + return sourceAge.get(); + }, function (newVal) { + timesComputeIsCalled++; + if (timesComputeIsCalled === 2) { + assert.ok(true, 'updating value to ' + newVal); + } else { + assert.ok(false, '(setter) You\'ve called the callback ' + timesComputeIsCalled + ' times'); + } + sourceAge.set(newVal); + }); + Component.extend({ tag: 'age-er' }); + var renderer = stache(''); + renderer({ age: age }); + age.set(31); + }); + QUnit.test('viewModel not rebound correctly (#550)', function (assert) { + var nameChanges = 0; + Component.extend({ + tag: 'viewmodel-rebinder', + events: { + '{name}': function () { + nameChanges++; + } + } + }); + var renderer = stache(''); + var frag = renderer(); + var viewModel = canViewModel(frag.firstChild); + var n1 = new SimpleObservable(), n2 = new SimpleObservable(); + viewModel.set('name', n1); + n1.set('updated'); + viewModel.set('name', n2); + n2.set('updated'); + assert.equal(nameChanges, 2); + }); + QUnit.test('id and class should work now (#694)', function (assert) { + Component.extend({ + tag: 'stay-classy', + ViewModel: SimpleMap.extend({ + setup: function (props) { + canReflect.assign(props, { + notid: 'foo', + notclass: 5, + notdataviewid: {} + }); + return SimpleMap.prototype.setup.apply(this, arguments); + } + }) + }); + var data = { + idData: 'id-success', + classData: 'class-success' + }; + var frag = stache('')(data); + var stayClassy = frag.firstChild; + domMutateNode.appendChild.call(this.fixture, frag); + var viewModel = canViewModel(stayClassy); + assert.equal(viewModel.get('id'), 'id-success'); + assert.equal(viewModel.get('class'), 'class-success'); + }); + QUnit.test('Construct are passed normally', function (assert) { + var Constructed = Construct.extend({ foo: 'bar' }, {}); + Component.extend({ + tag: 'con-struct', + view: stache('{{con.foo}}') + }); + var stached = stache(''); + var res = stached({ Constructed: Constructed }); + assert.equal(innerHTML(res.firstChild), 'bar'); + }); + QUnit.test('Component two way binding loop (#1579)', function (assert) { + var changeCount = 0; + Component.extend({ + tag: 'product-swatch-color', + viewModel: { tag: 'product-swatch-color' } + }); + Component.extend({ + tag: 'product-swatch', + view: stache(''), + ViewModel: DefineMap.extend({ + variations: { + set: function (variations) { + if (changeCount > 500) { + return; + } + changeCount++; + return new DefineList(variations.get()); + } + } + }) + }); + var frag = stache('')(), productSwatch = frag.firstChild; + canViewModel(productSwatch).set('variations', new DefineList()); + assert.ok(changeCount < 500, 'more than 500 events'); + }); + QUnit.test('two-way binding syntax INTRODUCED in v2.3 ALLOWS a child property to initialize an undefined parent property', function (assert) { + var renderer = stache(''); + Component.extend({ + tag: 'pa-rent', + view: stache('') + }); + Component.extend({ + tag: 'chi-ld', + ViewModel: { childProp: { value: 'bar' } } + }); + var frag = renderer({}); + var parentVM = canViewModel(frag.firstChild); + var childVM = canViewModel(frag.firstChild.firstChild); + assert.equal(parentVM.get('parentProp'), 'bar', 'parentProp is bar'); + assert.equal(childVM.get('childProp'), 'bar', 'childProp is bar'); + parentVM.set('parentProp', 'foo'); + assert.equal(parentVM.get('parentProp'), 'foo', 'parentProp is foo'); + assert.equal(childVM.get('childProp'), 'foo', 'childProp is foo'); + childVM.set('childProp', 'baz'); + assert.equal(parentVM.get('parentProp'), 'baz', 'parentProp is baz'); + assert.equal(childVM.get('childProp'), 'baz', 'childProp is baz'); + }); + QUnit.test('conditional attributes (#2077)', function (assert) { + Component.extend({ + tag: 'some-comp', + ViewModel: DefineMap.extend({ seal: false }, {}) + }); + var renderer = stache(''); + var map = new SimpleMap({ + preview: true, + nextPage: 2, + swapName: 'preview' + }); + var frag = renderer(map); + var vm = canViewModel(frag.firstChild); + var threads = [ + function () { + assert.equal(vm.next, 2, 'has binding initially'); + assert.equal(vm.swap, true, 'swap - has binding'); + map.attr('preview', false); + }, + function () { + assert.equal(vm.swap, false, 'swap - updated binidng'); + map.attr('nextPage', 3); + assert.equal(vm.next, 2, 'not updating after binding is torn down'); + map.attr('preview', true); + }, + function () { + assert.equal(vm.next, 3, 're-initialized with binding'); + assert.equal(vm.swap, true, 'swap - updated binidng'); + map.attr('swapName', 'nextPage'); + }, + function () { + assert.equal(vm.swap, 3, 'swap - updated binding key'); + map.attr('nextPage', 4); + assert.equal(vm.swap, 4, 'swap - updated binding'); + } + ]; + var done = assert.async(); + var index = 0; + var next = function () { + if (index < threads.length) { + threads[index](); + index++; + setTimeout(next, 150); + } else { + done(); + } + }; + setTimeout(next, 100); + }); + QUnit.test('one-way - child to parent - parent that does not leak scope, but has no view', function (assert) { + Component.extend({ + tag: 'outer-noleak', + ViewModel: DefineMap.extend('Outer', {}, { + name: { default: 'outer' }, + myChild: { default: null } + }), + leakScope: false + }); + Component.extend({ + tag: 'my-child', + ViewModel: DefineMap.extend('Inner', {}, { name: { default: 'inner' } }), + leakScope: false + }); + var renderer = stache(''); + var frag = renderer(); + var vm = canViewModel(frag.firstChild); + assert.equal(vm.myChild.name, 'inner', 'got instance'); + }); + QUnit.test('Can be called on an element using preventDataBindings (#183)', function (assert) { + Component.extend({ + tag: 'prevent-data-bindings', + ViewModel: {}, + view: stache('{{value}}') + }); + var document = this.document; + var el = document.createElement('div'); + var callback = tag('prevent-data-bindings'); + var vm = new DefineMap({ value: 'it worked' }); + el[canSymbol.for('can.viewModel')] = vm; + canData.set(el, 'preventDataBindings', true); + callback(el, { scope: new Scope({ value: 'it did not work' }) }); + canData.set(el, 'preventDataBindings', false); + assert.equal(el.firstChild.nodeValue, 'it worked'); + }); + QUnit.test('viewModel available as viewModel property (#282)', function (assert) { + Component.extend({ + tag: 'can-map-viewmodel', + view: stache('{{name}}'), + viewModel: { name: 'Matthew' } + }); + var renderer = stache(''); + var fragOne = renderer(); + var vmOne = fragOne.firstChild.viewModel; + var fragTwo = renderer(); + vmOne.set('name', 'Wilbur'); + assert.equal(fragOne.firstChild.firstChild.nodeValue, 'Wilbur', 'The first map changed values'); + assert.equal(fragTwo.firstChild.firstChild.nodeValue, 'Matthew', 'The second map did not change'); + }); + QUnit.test('connectedCallback without a disconnect calls stopListening', function (assert) { + assert.expect(1); + var done = assert.async(); + var map = new SimpleMap(); + Component.extend({ + tag: 'connected-component-listen', + view: stache('rendered'), + ViewModel: { + connectedCallback: function (element) { + this.listenTo(map, 'foo', function () { + }); + } + } + }); + var template = stache(''); + var frag = template(); + var first = frag.firstChild; + domMutateNode.appendChild.call(this.fixture, frag); + helpers.afterMutation(function () { + domMutateNode.removeChild.call(first.parentNode, first); + helpers.afterMutation(function () { + assert.notOk(canReflect.isBound(map), 'stopListening no matter what on vm'); + done(); + }); + }); + }); + }); +}); +/*can-observe@2.3.2#src/-symbols*/ +define('can-observe@2.3.2#src/-symbols', [ + 'require', + 'exports', + 'module', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + module.exports = { + metaSymbol: canSymbol.for('can.meta'), + patchesSymbol: 'can.patches', + keysSymbol: 'can.keys' + }; +}); +/*can-observe@2.3.2#src/-observable-store*/ +define('can-observe@2.3.2#src/-observable-store', function (require, exports, module) { + 'use strict'; + module.exports = { + proxiedObjects: new WeakMap(), + proxies: new WeakSet() + }; +}); +/*can-observe@2.3.2#src/-helpers*/ +define('can-observe@2.3.2#src/-helpers', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-symbol' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getGlobal = require('can-globals/global/global'); + var canSymbol = require('can-symbol'); + var metaSymbol = canSymbol.for('can.meta'); + var classTest = /^\s*class\s+/; + var helpers = { + assignEverything: function (d, s) { + Object.getOwnPropertyNames(s).concat(Object.getOwnPropertySymbols(s)).forEach(function (key) { + Object.defineProperty(d, key, Object.getOwnPropertyDescriptor(s, key)); + }); + return d; + }, + isBuiltInButNotArrayOrPlainObjectOrElement: function (obj) { + if (obj instanceof getGlobal().Element) { + return false; + } + return helpers.isBuiltInButNotArrayOrPlainObject(obj); + }, + isBuiltInButNotArrayOrPlainObject: function (obj) { + if (Array.isArray(obj)) { + return false; + } + if (typeof obj === 'function') { + var fnCode = obj.toString(); + if (fnCode.indexOf('[native code]') > 0) { + return true; + } else { + return false; + } + } else { + var toString = Object.prototype.toString.call(obj); + return toString !== '[object Object]' && toString.indexOf('[object ') !== -1; + } + }, + inheritsFromArray: function (obj) { + var cur = obj; + do { + if (Array.isArray(cur)) { + return true; + } + cur = Object.getPrototypeOf(cur); + } while (cur); + return false; + }, + isClass: function (obj) { + return typeof obj === 'function' && classTest.test(obj.toString()); + }, + supportsClass: function () { + try { + eval('"use strict"; class A{};'); + return true; + } catch (e) { + return false; + } + }(), + makeSimpleExtender: function (BaseType) { + return function extend(name, staticProps, prototypeProps) { + var Type = function () { + var source = this; + var instance = BaseType.apply(this, arguments); + if (source.init) { + instance[metaSymbol].preventSideEffects++; + source.init.apply(instance, arguments); + instance[metaSymbol].preventSideEffects--; + } + return instance; + }; + helpers.assignEverything(Type, BaseType); + helpers.assignEverything(Type, staticProps || {}); + Type.extend = helpers.makeSimpleExtender(Type); + Type.prototype = Object.create(BaseType.prototype); + helpers.assignEverything(Type.prototype, prototypeProps || {}); + Type.prototype.constructor = Type; + return Type; + }; + }, + assignNonEnumerable: function (obj, key, value) { + return Object.defineProperty(obj, key, { + enumerable: false, + writable: true, + configurable: true, + value: value + }); + } + }; + module.exports = helpers; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-observe@2.3.2#src/-computed-helpers*/ +define('can-observe@2.3.2#src/-computed-helpers', [ + 'require', + 'exports', + 'module', + 'can-observation', + 'can-observation-recorder', + 'can-event-queue/map/map', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var Observation = require('can-observation'); + var ObservationRecorder = require('can-observation-recorder'); + var mapBindings = require('can-event-queue/map/map'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var canMeta = canSymbol.for('can.meta'); + var computedPropertyDefinitionSymbol = canSymbol.for('can.computedPropertyDefinitions'); + var onKeyValueSymbol = canSymbol.for('can.onKeyValue'); + var offKeyValueSymbol = canSymbol.for('can.offKeyValue'); + function ComputedObjectObservationData(instance, prop, observation) { + this.instance = instance; + this.prop = prop; + this.observation = observation; + this.forward = this.forward.bind(this); + } + ComputedObjectObservationData.prototype.bind = function () { + this.bindingCount++; + if (this.bindingCount === 1) { + this.observation.on(this.forward, 'notify'); + } + }; + ComputedObjectObservationData.prototype.unbind = function () { + this.bindingCount--; + if (this.bindingCount === 0) { + this.observation.off(this.forward, 'notify'); + } + }; + ComputedObjectObservationData.prototype.forward = function (newValue, oldValue) { + mapBindings.dispatch.call(this.instance, { + type: this.prop, + target: this.instance + }, [ + newValue, + oldValue + ]); + }; + ComputedObjectObservationData.prototype.bindingCount = 0; + function findComputed(instance, key) { + var meta = instance[canMeta]; + var target = meta.target; + var computedPropertyDefinitions = target[computedPropertyDefinitionSymbol]; + if (computedPropertyDefinitions === undefined) { + return; + } + var computedPropertyDefinition = computedPropertyDefinitions[key]; + if (computedPropertyDefinition === undefined) { + return; + } + if (meta.computedKeys[key] === undefined) { + meta.computedKeys[key] = new ComputedObjectObservationData(instance, key, computedPropertyDefinition(instance, key)); + } + return meta.computedKeys[key]; + } + var computedHelpers = module.exports = { + get: function (instance, key) { + var computedObj = findComputed(instance, key); + if (computedObj === undefined) { + return; + } + ObservationRecorder.add(instance, key.toString()); + if (computedObj.bindingCount === 0 && ObservationRecorder.isRecording()) { + Observation.temporarilyBind(computedObj.observation); + } + return { value: canReflect.getValue(computedObj.observation) }; + }, + set: function (instance, key, value) { + var computedObj = findComputed(instance, key); + if (computedObj === undefined) { + return false; + } + canReflect.setValue(computedObj.observation, value); + return true; + }, + bind: function (instance, key) { + var computedObj = findComputed(instance, key); + if (computedObj === undefined) { + return; + } + computedObj.bind(); + }, + unbind: function (instance, key) { + var computedObj = findComputed(instance, key); + if (computedObj === undefined) { + return; + } + computedObj.unbind(); + }, + addKeyDependencies: function (proxyKeys) { + var onKeyValue = proxyKeys[onKeyValueSymbol]; + var offKeyValue = proxyKeys[offKeyValueSymbol]; + canReflect.assignSymbols(proxyKeys, { + 'can.onKeyValue': function (key, handler, queue) { + computedHelpers.bind(this, key); + return onKeyValue.apply(this, arguments); + }, + 'can.offKeyValue': function (key, handler, queue) { + computedHelpers.unbind(this, key); + return offKeyValue.apply(this, arguments); + }, + 'can.getKeyDependencies': function (key) { + var computedObj = findComputed(this, key); + if (computedObj === undefined) { + return; + } + return { valueDependencies: new Set([computedObj.observation]) }; + } + }); + }, + addMethodsAndSymbols: function (Type) { + Type.prototype.addEventListener = function (key, handler, queue) { + computedHelpers.bind(this, key); + return mapBindings.addEventListener.call(this, key, handler, queue); + }; + Type.prototype.removeEventListener = function (key, handler, queue) { + computedHelpers.unbind(this, key); + return mapBindings.removeEventListener.call(this, key, handler, queue); + }; + }, + ensureDefinition: function (prototype) { + if (!prototype.hasOwnProperty(computedPropertyDefinitionSymbol)) { + var parent = prototype[computedPropertyDefinitionSymbol]; + var definitions = prototype[computedPropertyDefinitionSymbol] = Object.create(parent || null); + Object.getOwnPropertyNames(prototype).forEach(function (prop) { + if (prop === 'constructor') { + return; + } + var descriptor = Object.getOwnPropertyDescriptor(prototype, prop); + if (descriptor.get !== undefined) { + var getter = descriptor.get; + definitions[prop] = function (instance, property) { + return new Observation(getter, instance); + }; + } + }); + } + return prototype[computedPropertyDefinitionSymbol]; + } + }; +}); +/*can-observe@2.3.2#src/-make-object*/ +define('can-observe@2.3.2#src/-make-object', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-observation-recorder', + 'can-event-queue/map/map', + './-symbols', + './-observable-store', + './-helpers', + './-computed-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var mapBindings = require('can-event-queue/map/map'); + var symbols = require('./-symbols'); + var observableStore = require('./-observable-store'); + var helpers = require('./-helpers'); + var computedHelpers = require('./-computed-helpers'); + var hasOwn = Object.prototype.hasOwnProperty; + var isSymbolLike = canReflect.isSymbolLike; + var proxyKeys = Object.create(null); + Object.getOwnPropertySymbols(mapBindings).forEach(function (symbol) { + helpers.assignNonEnumerable(proxyKeys, symbol, mapBindings[symbol]); + }); + computedHelpers.addKeyDependencies(proxyKeys); + var makeObject = { + observable: function (object, options) { + if (options.shouldRecordObservation === undefined) { + options.shouldRecordObservation = makeObject.shouldRecordObservationOnOwnAndMissingKeys; + } + var meta = { + target: object, + proxyKeys: options.proxyKeys !== undefined ? options.proxyKeys : Object.create(makeObject.proxyKeys()), + computedKeys: Object.create(null), + options: options, + preventSideEffects: 0 + }; + helpers.assignNonEnumerable(meta.proxyKeys, symbols.metaSymbol, meta); + var traps = { + get: makeObject.get.bind(meta), + set: makeObject.set.bind(meta), + ownKeys: makeObject.ownKeys.bind(meta), + deleteProperty: makeObject.deleteProperty.bind(meta), + getOwnPropertyDescriptor: makeObject.getOwnPropertyDescriptor.bind(meta), + meta: meta + }; + if (options.getPrototypeOf) { + traps.getPrototypeOf = options.getPrototypeOf; + } + meta.proxy = new Proxy(object, traps); + mapBindings.addHandlers(meta.proxy, meta); + return meta.proxy; + }, + proxyKeys: function () { + return proxyKeys; + }, + get: function (target, key, receiver) { + var proxyKey = this.proxyKeys[key]; + if (proxyKey !== undefined) { + return proxyKey; + } + if (isSymbolLike(key)) { + return target[key]; + } + var computedValue = computedHelpers.get(receiver, key); + if (computedValue !== undefined) { + return computedValue.value; + } + var keyInfo = makeObject.getKeyInfo(target, key, receiver, this); + var value = keyInfo.targetValue; + if (!keyInfo.valueIsInvariant) { + value = makeObject.getValueFromStore(key, value, this); + } + if (this.options.shouldRecordObservation(keyInfo, this)) { + ObservationRecorder.add(this.proxy, key.toString()); + } + if (keyInfo.parentObservableGetCalledOn) { + ObservationRecorder.add(keyInfo.parentObservableGetCalledOn, key.toString()); + } + return value; + }, + set: function (target, key, value, receiver) { + if (receiver !== this.proxy && this.options.proxiedPrototype !== true) { + return makeObject.setKey(receiver, key, value, this); + } + var computedValue = computedHelpers.set(receiver, key, value); + if (computedValue === true) { + return true; + } + value = makeObject.getValueToSet(key, value, this); + makeObject.setValueAndOnChange(key, value, this, function (key, value, meta, hadOwn, old) { + var dispatchArgs = { + type: key, + patches: [{ + key: key, + type: hadOwn ? 'set' : 'add', + value: value + }], + keyChanged: !hadOwn ? key : undefined + }; + mapBindings.dispatch.call(meta.proxy, dispatchArgs, [ + value, + old + ]); + }); + return true; + }, + deleteProperty: function (target, key) { + var old = this.target[key], deleteSuccessful = delete this.target[key]; + if (deleteSuccessful && this.preventSideEffects === 0 && old !== undefined) { + var dispatchArgs = { + type: key, + patches: [{ + key: key, + type: 'delete' + }], + keyChanged: key + }; + mapBindings.dispatch.call(this.proxy, dispatchArgs, [ + undefined, + old + ]); + } + return deleteSuccessful; + }, + ownKeys: function (target) { + ObservationRecorder.add(this.proxy, symbols.keysSymbol); + return Object.getOwnPropertyNames(this.target).concat(Object.getOwnPropertySymbols(this.target)).concat(Object.getOwnPropertySymbols(this.proxyKeys)); + }, + getOwnPropertyDescriptor: function (target, key) { + var desc = Object.getOwnPropertyDescriptor(target, key); + if (!desc && key in this.proxyKeys) { + return Object.getOwnPropertyDescriptor(this.proxyKeys, key); + } + return desc; + }, + getKeyInfo: function (target, key, receiver, meta) { + var descriptor = Object.getOwnPropertyDescriptor(target, key); + var propertyInfo = { + key: key, + descriptor: descriptor, + targetHasOwnKey: Boolean(descriptor), + getCalledOnParent: receiver !== meta.proxy, + protoHasKey: false, + valueIsInvariant: false, + targetValue: undefined, + isAccessor: false + }; + if (propertyInfo.getCalledOnParent === true) { + propertyInfo.parentObservableGetCalledOn = observableStore.proxiedObjects.get(receiver); + } + if (descriptor !== undefined) { + propertyInfo.valueIsInvariant = descriptor.writable === false; + if (descriptor.get !== undefined) { + propertyInfo.targetValue = descriptor.get.call(propertyInfo.parentObservableGetCalledOn || receiver); + propertyInfo.isAccessor = true; + } else { + propertyInfo.targetValue = descriptor.value; + } + } else { + propertyInfo.targetValue = meta.target[key]; + propertyInfo.protoHasKey = propertyInfo.targetValue !== undefined ? true : key in target; + } + return propertyInfo; + }, + shouldRecordObservationOnOwnAndMissingKeys: function (keyInfo, meta) { + return meta.preventSideEffects === 0 && !keyInfo.isAccessor && (keyInfo.targetHasOwnKey || !keyInfo.protoHasKey && !Object.isSealed(meta.target)); + }, + setKey: function (receiver, key, value) { + Object.defineProperty(receiver, key, { + value: value, + configurable: true, + enumerable: true, + writable: true + }); + return true; + }, + getValueToSet: function (key, value, meta) { + if (!canReflect.isSymbolLike(key) && meta.handlers.getNode([key])) { + return makeObject.getValueFromStore(key, value, meta); + } + return value; + }, + getValueFromStore: function (key, value, meta) { + if (!canReflect.isPrimitive(value) && !canReflect.isObservableLike(value) && !observableStore.proxies.has(value)) { + if (observableStore.proxiedObjects.has(value)) { + value = observableStore.proxiedObjects.get(value); + } else if (!helpers.isBuiltInButNotArrayOrPlainObject(value)) { + value = meta.options.observe(value); + } + } + return value; + }, + setValueAndOnChange: function (key, value, data, onChange) { + var old, change; + var hadOwn = hasOwn.call(data.target, key); + var descriptor = Object.getOwnPropertyDescriptor(data.target, key); + if (descriptor && descriptor.set) { + descriptor.set.call(data.proxy, value); + } else { + old = data.target[key]; + change = old !== value; + if (change) { + data.target[key] = value; + if (data.preventSideEffects === 0) { + onChange(key, value, data, hadOwn, old); + } + } + } + } + }; + module.exports = makeObject; +}); +/*can-observe@2.3.2#src/-make-array*/ +define('can-observe@2.3.2#src/-make-array', [ + 'require', + 'exports', + 'module', + 'can-observation-recorder', + 'can-event-queue/map/map', + 'can-reflect', + './-make-object', + './-symbols', + './-observable-store', + './-helpers', + './-computed-helpers' +], function (require, exports, module) { + 'use strict'; + var ObservationRecorder = require('can-observation-recorder'); + var mapBindings = require('can-event-queue/map/map'); + var canReflect = require('can-reflect'); + var makeObject = require('./-make-object'); + var symbols = require('./-symbols'); + var observableStore = require('./-observable-store'); + var helpers = require('./-helpers'); + var computedHelpers = require('./-computed-helpers'); + var isSymbolLike = canReflect.isSymbolLike; + var isInteger = Number.isInteger || function (value) { + return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; + }; + function didLengthChangeCauseDeletions(key, value, old) { + return key === 'length' && value < old; + } + var mutateMethods = { + 'push': function (arr, args) { + return [{ + index: arr.length - args.length, + deleteCount: 0, + insert: args, + type: 'splice' + }]; + }, + 'pop': function (arr) { + return [{ + index: arr.length, + deleteCount: 1, + insert: [], + type: 'splice' + }]; + }, + 'shift': function () { + return [{ + index: 0, + deleteCount: 1, + insert: [], + type: 'splice' + }]; + }, + 'unshift': function (arr, args) { + return [{ + index: 0, + deleteCount: 0, + insert: args, + type: 'splice' + }]; + }, + 'splice': function (arr, args) { + return [{ + index: args[0], + deleteCount: args[1], + insert: args.slice(2), + type: 'splice' + }]; + }, + 'sort': function (arr) { + return [{ + index: 0, + deleteCount: arr.length, + insert: arr, + type: 'splice' + }]; + }, + 'reverse': function (arr, args, old) { + return [{ + index: 0, + deleteCount: arr.length, + insert: arr, + type: 'splice' + }]; + } + }; + canReflect.eachKey(mutateMethods, function (makePatches, prop) { + var protoFn = Array.prototype[prop]; + var mutateMethod = function () { + var meta = this[symbols.metaSymbol], makeSideEffects = meta.preventSideEffects === 0, oldLength = meta.target.length; + meta.preventSideEffects++; + var ret = protoFn.apply(meta.target, arguments); + var patches = makePatches(meta.target, Array.from(arguments), oldLength); + if (makeSideEffects === true) { + var dispatchArgs = { + type: 'length', + patches: patches + }; + mapBindings.dispatch.call(meta.proxy, dispatchArgs, [ + meta.target.length, + oldLength + ]); + } + meta.preventSideEffects--; + return ret; + }; + observableStore.proxiedObjects.set(protoFn, mutateMethod); + observableStore.proxies.add(mutateMethod); + }); + Object.getOwnPropertyNames(Array.prototype).forEach(function (prop) { + var protoFn = Array.prototype[prop]; + if (observableStore.proxiedObjects.has(protoFn)) { + return; + } + if (prop !== 'constructor' && typeof protoFn === 'function') { + var arrayMethod = function () { + ObservationRecorder.add(this, symbols.patchesSymbol); + var meta = this[symbols.metaSymbol]; + meta.preventSideEffects++; + var ret = protoFn.apply(this, arguments); + meta.preventSideEffects--; + return meta.options.observe(ret); + }; + observableStore.proxiedObjects.set(protoFn, arrayMethod); + observableStore.proxies.add(arrayMethod); + } + }); + var proxyKeys = helpers.assignEverything(Object.create(null), makeObject.proxyKeys()); + var makeArray = { + observable: function (array, options) { + if (options.shouldRecordObservation === undefined) { + options.shouldRecordObservation = makeObject.shouldRecordObservationOnOwnAndMissingKeys; + } + var meta = { + target: array, + proxyKeys: options.proxyKeys !== undefined ? options.proxyKeys : Object.create(makeArray.proxyKeys()), + computedKeys: Object.create(null), + options: options, + preventSideEffects: 0 + }; + meta.proxyKeys[symbols.metaSymbol] = meta; + meta.proxy = new Proxy(array, { + get: makeObject.get.bind(meta), + set: makeArray.set.bind(meta), + ownKeys: makeObject.ownKeys.bind(meta), + deleteProperty: makeObject.deleteProperty.bind(meta), + meta: meta + }); + mapBindings.addHandlers(meta.proxy, meta); + return meta.proxy; + }, + proxyKeys: function () { + return proxyKeys; + }, + set: function (target, key, value, receiver) { + if (receiver !== this.proxy) { + return makeObject.setKey(receiver, key, value, this); + } + var computedValue = computedHelpers.set(receiver, key, value); + if (computedValue === true) { + return true; + } + value = makeObject.getValueToSet(key, value, this); + var startingLength = target.length; + makeObject.setValueAndOnChange(key, value, this, function (key, value, meta, hadOwn, old) { + var patches = [{ + key: key, + type: hadOwn ? 'set' : 'add', + value: value + }]; + var numberKey = !isSymbolLike(key) && +key; + if (isInteger(numberKey)) { + if (!hadOwn && numberKey > startingLength) { + patches.push({ + index: startingLength, + deleteCount: 0, + insert: target.slice(startingLength), + type: 'splice' + }); + } else { + patches.push.apply(patches, mutateMethods.splice(target, [ + numberKey, + 1, + value + ])); + } + } + if (didLengthChangeCauseDeletions(key, value, old, meta)) { + patches.push({ + index: value, + deleteCount: old - value, + insert: [], + type: 'splice' + }); + } + var dispatchArgs = { + type: key, + patches: patches, + keyChanged: !hadOwn ? key : undefined + }; + mapBindings.dispatch.call(meta.proxy, dispatchArgs, [ + value, + old + ]); + }); + return true; + } + }; + module.exports = makeArray; +}); +/*can-observe@2.3.2#src/-make-observe*/ +define('can-observe@2.3.2#src/-make-observe', [ + 'require', + 'exports', + 'module', + 'can-globals/global/global', + 'can-reflect', + './-observable-store', + './-helpers' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var getGlobal = require('can-globals/global/global'); + var canReflect = require('can-reflect'); + var observables = require('./-observable-store'); + var helpers = require('./-helpers'); + var makeObserve = { + observe: function (value) { + if (canReflect.isPrimitive(value)) { + return value; + } + var observable = observables.proxiedObjects.get(value); + if (observable) { + return observable; + } + if (observables.proxies.has(value)) { + return value; + } + if (helpers.isBuiltInButNotArrayOrPlainObjectOrElement(value)) { + return value; + } + if (typeof value === 'function') { + observable = makeObserve.function(value); + } else if (helpers.inheritsFromArray(value)) { + observable = makeObserve.array(value); + } else if (value instanceof getGlobal().Element) { + observable = makeObserve.prototype(value); + } else { + observable = makeObserve.object(value); + } + observables.proxiedObjects.set(value, observable); + observables.proxies.add(observable); + return observable; + }, + 'object': null, + 'array': null, + 'function': null + }; + module.exports = makeObserve; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-observe@2.3.2#src/-make-function*/ +define('can-observe@2.3.2#src/-make-function', [ + 'require', + 'exports', + 'module', + 'can-reflect', + './-make-object', + './-make-observe', + './-symbols', + './-observable-store', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + './-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var makeObject = require('./-make-object'); + var makeObserve = require('./-make-observe'); + var symbols = require('./-symbols'); + var observableStore = require('./-observable-store'); + var mapBindings = require('can-event-queue/map/map'); + var typeBindings = require('can-event-queue/type/type'); + var helpers = require('./-helpers'); + var proxyKeys = helpers.assignEverything(Object.create(null), makeObject.proxyKeys()); + typeBindings(proxyKeys); + canReflect.assignSymbols(proxyKeys, { + 'can.defineInstanceKey': function (prop, value) { + this[symbols.metaSymbol].definitions[prop] = value; + } + }); + var makeFunction = { + observable: function (object, options) { + if (options.shouldRecordObservation === undefined) { + options.shouldRecordObservation = makeObject.shouldRecordObservationOnOwnAndMissingKeys; + } + var proxyKeys = Object.create(makeFunction.proxyKeys()); + var meta = { + target: object, + proxyKeys: proxyKeys, + computedKeys: Object.create(null), + options: options, + definitions: {}, + isClass: helpers.isClass(object), + preventSideEffects: 0 + }; + proxyKeys[symbols.metaSymbol] = meta; + meta.proxy = new Proxy(object, { + get: makeObject.get.bind(meta), + set: makeObject.set.bind(meta), + ownKeys: makeObject.ownKeys.bind(meta), + deleteProperty: makeObject.deleteProperty.bind(meta), + construct: makeFunction.construct.bind(meta), + apply: makeFunction.apply.bind(meta), + meta: meta + }); + mapBindings.addHandlers(meta.proxy, meta); + typeBindings.addHandlers(meta.proxy, meta); + observableStore.proxiedObjects.set(object, meta.proxy); + observableStore.proxies.add(meta.proxy); + if (meta.target.prototype && meta.target.prototype.constructor === meta.target) { + var newPrototype = makeObject.observable(meta.target.prototype, { + getPrototypeOf: function () { + return meta.target.prototype; + }, + observe: makeObserve.observe + }); + observableStore.proxiedObjects.set(meta.target.prototype, newPrototype); + observableStore.proxies.add(newPrototype); + var prototype = meta.proxy.prototype; + prototype.constructor = meta.proxy; + } + return meta.proxy; + }, + construct: function (target, argumentsList, newTarget) { + var instanceTarget, key; + if (this.isClass) { + instanceTarget = Reflect.construct(target, argumentsList, newTarget); + for (key in this.definitions) { + Object.defineProperty(instanceTarget, key, this.definitions[key]); + } + return this.options.observe(instanceTarget); + } else { + instanceTarget = Object.create(this.proxy.prototype); + for (key in this.definitions) { + Object.defineProperty(instanceTarget, key, this.definitions[key]); + } + var instance = this.options.observe(instanceTarget); + instance[symbols.metaSymbol].preventSideEffects++; + var res = target.apply(instance, argumentsList); + instance[symbols.metaSymbol].preventSideEffects--; + if (res) { + return res; + } else { + return instance; + } + } + }, + apply: function (target, thisArg, argumentsList) { + var ret = this.target.apply(thisArg, argumentsList); + return this.options.observe(ret); + }, + proxyKeys: function () { + return proxyKeys; + } + }; + module.exports = makeFunction; +}); +/*can-observe@2.3.2#src/-make-prototype*/ +define('can-observe@2.3.2#src/-make-prototype', [ + 'require', + 'exports', + 'module', + './-make-object', + './-helpers', + './-symbols', + 'can-event-queue/map/map', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var makeObject = require('./-make-object'); + var helpers = require('./-helpers'); + var symbols = require('./-symbols'); + var mapBindings = require('can-event-queue/map/map'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var isSymbolLike = canReflect.isSymbolLike; + var proxyMetaSymbol = canSymbol.for('can.proxyMeta'); + function getMetadata(instance, options) { + if (instance.hasOwnProperty(proxyMetaSymbol)) { + return instance[proxyMetaSymbol]; + } + if (options.shouldRecordObservation === undefined) { + options.shouldRecordObservation = makeObject.shouldRecordObservationOnOwnAndMissingKeys; + } + options.proxiedPrototype = true; + var meta = { + target: makeObject.observable({}, options), + proxyKeys: options.proxyKeys !== undefined ? options.proxyKeys : Object.create(makeObject.proxyKeys()), + computedKeys: Object.create(null), + options: options, + preventSideEffects: 0, + proxy: instance + }; + helpers.assignNonEnumerable(meta.proxyKeys, symbols.metaSymbol, meta); + mapBindings.addHandlers(meta.proxy, meta); + instance[proxyMetaSymbol] = meta; + return meta; + } + var makePrototype = { + observable: function (proto, options) { + var protoProxy = new Proxy(proto, { + set: function (target, key, value, receiver) { + if (isSymbolLike(key) || key in target) { + return Reflect.set(target, key, value, receiver); + } + var meta = getMetadata(receiver, options); + return makeObject.set.call(meta, target, key, value, receiver); + }, + get: function (target, key, receiver) { + if (key in target) { + return Reflect.get(target, key, receiver); + } + var meta = getMetadata(receiver, options); + return makeObject.get.call(meta, target, key, receiver); + } + }); + return protoProxy; + } + }; + module.exports = makePrototype; +}); +/*can-observe@2.3.2#src/-type-helpers*/ +define('can-observe@2.3.2#src/-type-helpers', [ + 'require', + 'exports', + 'module', + 'can-queues', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var queues = require('can-queues'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var canMeta = canSymbol.for('can.meta'); + var typeDefinitionsSymbol = canSymbol.for('can.typeDefinitions'); + var helpers = module.exports = { + ensureDefinition: function (prototype) { + var typeDefs = prototype[typeDefinitionsSymbol]; + if (!typeDefs) { + var parent = prototype[typeDefinitionsSymbol]; + typeDefs = prototype[typeDefinitionsSymbol] = Object.create(parent || null); + } + return typeDefs; + }, + addMethodsAndSymbols: function (Type) { + canReflect.assignSymbols(Type, { + 'can.defineInstanceKey': function (prop, value) { + helpers.ensureDefinition(this.prototype)[prop] = value; + }, + 'can.dispatchInstanceBoundChange': function (obj, isBound) { + var meta = this[canMeta]; + if (meta) { + var lifecycleHandlers = meta.lifecycleHandlers; + if (lifecycleHandlers) { + queues.enqueueByQueue(lifecycleHandlers.getNode([]), this, [ + obj, + isBound + ]); + } + } + } + }); + }, + shouldRecordObservationOnAllKeysExceptFunctionsOnProto: function (keyInfo, meta) { + return meta.preventSideEffects === 0 && !keyInfo.isAccessor && (keyInfo.targetHasOwnKey || !keyInfo.protoHasKey && !Object.isSealed(meta.target) || keyInfo.protoHasKey && typeof targetValue !== 'function'); + } + }; +}); +/*can-observe@2.3.2#object/object*/ +define('can-observe@2.3.2#object/object', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-symbol', + '../src/-make-observe', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + '../src/-helpers', + '../src/-make-object', + '../src/-observable-store', + '../src/-computed-helpers', + '../src/-type-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var makeObserve = require('../src/-make-observe'); + var eventMixin = require('can-event-queue/map/map'); + var typeEventMixin = require('can-event-queue/type/type'); + var helpers = require('../src/-helpers'); + var makeObject = require('../src/-make-object'); + var observableStore = require('../src/-observable-store'); + var definitionsSymbol = canSymbol.for('can.typeDefinitions'); + var computedHelpers = require('../src/-computed-helpers'); + var typeHelpers = require('../src/-type-helpers'); + var proxyKeys = helpers.assignEverything({}, makeObject.proxyKeys()); + computedHelpers.addKeyDependencies(proxyKeys); + var ObserveObject = function (props) { + var prototype = Object.getPrototypeOf(this); + computedHelpers.ensureDefinition(prototype); + typeHelpers.ensureDefinition(prototype); + var sourceInstance = this; + var definitions = prototype[definitionsSymbol] || {}; + for (var key in definitions) { + Object.defineProperty(sourceInstance, key, definitions[key]); + } + if (props !== undefined) { + canReflect.assign(sourceInstance, props); + } + var localProxyKeys = Object.create(proxyKeys); + localProxyKeys.constructor = this.constructor; + var observable = makeObject.observable(sourceInstance, { + observe: makeObserve.observe, + proxyKeys: localProxyKeys, + shouldRecordObservation: typeHelpers.shouldRecordObservationOnAllKeysExceptFunctionsOnProto + }); + observableStore.proxiedObjects.set(sourceInstance, observable); + observableStore.proxies.add(observable); + return observable; + }; + eventMixin(ObserveObject.prototype); + typeEventMixin(ObserveObject); + computedHelpers.addMethodsAndSymbols(ObserveObject); + typeHelpers.addMethodsAndSymbols(ObserveObject); + ObserveObject.extend = helpers.makeSimpleExtender(ObserveObject); + module.exports = ObserveObject; +}); +/*can-observe@2.3.2#array/array*/ +define('can-observe@2.3.2#array/array', [ + 'require', + 'exports', + 'module', + 'can-symbol', + '../src/-make-array', + '../src/-make-observe', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + '../src/-helpers', + '../src/-observable-store', + '../src/-computed-helpers', + '../src/-type-helpers' +], function (require, exports, module) { + 'use strict'; + var canSymbol = require('can-symbol'); + var makeArray = require('../src/-make-array'); + var makeObserve = require('../src/-make-observe'); + var eventMixin = require('can-event-queue/map/map'); + var typeEventMixin = require('can-event-queue/type/type'); + var helpers = require('../src/-helpers'); + var observableStore = require('../src/-observable-store'); + var computedHelpers = require('../src/-computed-helpers'); + var typeHelpers = require('../src/-type-helpers'); + var definitionsSymbol = canSymbol.for('can.typeDefinitions'); + var proxyKeys = helpers.assignEverything({}, makeArray.proxyKeys()); + var ObserveArray; + if (false) { + } else { + var ObserveArray = function (items) { + var prototype = Object.getPrototypeOf(this); + computedHelpers.ensureDefinition(prototype); + typeHelpers.ensureDefinition(prototype); + var instance = this; + var definitions = prototype[definitionsSymbol] || {}; + for (var key in definitions) { + Object.defineProperty(instance, key, definitions[key]); + } + this.push.apply(this, items || []); + var localProxyKeys = Object.create(proxyKeys); + localProxyKeys.constructor = this.constructor; + var observable = makeArray.observable(instance, { + observe: makeObserve.observe, + proxyKeys: localProxyKeys, + shouldRecordObservation: typeHelpers.shouldRecordObservationOnAllKeysExceptFunctionsOnProto + }); + observableStore.proxiedObjects.set(instance, observable); + observableStore.proxies.add(observable); + return observable; + }; + ObserveArray.prototype = Object.create(Array.prototype); + } + eventMixin(ObserveArray.prototype); + typeEventMixin(ObserveArray); + computedHelpers.addMethodsAndSymbols(ObserveArray); + typeHelpers.addMethodsAndSymbols(ObserveArray); + ObserveArray.extend = helpers.makeSimpleExtender(ObserveArray); + module.exports = ObserveArray; +}); +/*can-observe@2.3.2#decorators/decorators*/ +define('can-observe@2.3.2#decorators/decorators', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-simple-observable/async/async', + 'can-simple-observable/resolver/resolver', + '../src/-computed-helpers' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var AsyncObservable = require('can-simple-observable/async/async'); + var ResolverObservable = require('can-simple-observable/resolver/resolver'); + var computedHelpers = require('../src/-computed-helpers'); + function defineProperty(prototype, prop, makeObservable) { + computedHelpers.ensureDefinition(prototype)[prop] = makeObservable; + } + function asyncBase(config) { + return function (target, key, descriptor) { + if (descriptor.get !== undefined) { + var getter = descriptor.get; + return defineProperty(target, key, function (instance, property) { + function fn(lastSet, resolve) { + if (!resolve) { + return config.default; + } + var promise = getter.call(this, true); + if (canReflect.isPromise(promise)) { + promise.then(resolve); + return config.default; + } + } + return new AsyncObservable(fn, instance, config.default); + }); + } + if (descriptor.value !== undefined) { + var method = descriptor.value; + return defineProperty(target, key, function (instance, property) { + return new AsyncObservable(function (lastSet, resolve) { + return method.call(this, resolve); + }, instance, config.default); + }); + } + }; + } + function resolverBase(config) { + return function (target, key, descriptor) { + if (descriptor.value !== undefined) { + var method = descriptor.value; + return defineProperty(target, key, function (instance, property) { + return new ResolverObservable(method, instance); + }); + } + }; + } + function optionalConfig(decorator) { + function wrapper(config) { + if (arguments.length === 3) { + return decorator({}).apply(null, arguments); + } + return decorator(config); + } + return wrapper; + } + module.exports = { + async: optionalConfig(asyncBase), + resolver: optionalConfig(resolverBase) + }; +}); +/*can-observe@2.3.2#can-observe*/ +define('can-observe@2.3.2#can-observe', [ + 'require', + 'exports', + 'module', + './src/-make-object', + './src/-make-array', + './src/-make-function', + './src/-make-observe', + './src/-make-prototype', + './object/object', + './array/array', + './src/-computed-helpers', + './decorators/decorators' +], function (require, exports, module) { + 'use strict'; + var makeObject = require('./src/-make-object'); + var makeArray = require('./src/-make-array'); + var makeFunction = require('./src/-make-function'); + var makeObserve = require('./src/-make-observe'); + var makePrototype = require('./src/-make-prototype'); + var ObserveObject = require('./object/object'); + var ObserveArray = require('./array/array'); + var computedHelpers = require('./src/-computed-helpers'); + var decorators = require('./decorators/decorators'); + makeObserve.object = function (object) { + return makeObject.observable(object, makeObserve); + }; + makeObserve.prototype = function (proto) { + return makePrototype.observable(proto, makeObserve); + }; + makeObserve.array = function (array) { + return makeArray.observable(array, makeObserve); + }; + makeObserve.function = function (fn) { + return makeFunction.observable(fn, makeObserve); + }; + makeObserve.observe.Object = ObserveObject; + makeObserve.observe.Array = ObserveArray; + module.exports = makeObserve.observe; + module.exports.defineProperty = function (prototype, prop, makeObservable) { + computedHelpers.ensureDefinition(prototype)[prop] = makeObservable; + }; + for (var key in decorators) { + module.exports[key] = decorators[key]; + } +}); +/*can-component@5.0.0#test/component-viewmodel-observe-test*/ +define('can-component@5.0.0#test/component-viewmodel-observe-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-stache', + 'can-component', + 'can-dom-events', + 'can-dom-mutate/node', + 'can-observe' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var stache = require('can-stache'); + var Component = require('can-component'); + var domEvents = require('can-dom-events'); + var domMutateNode = require('can-dom-mutate/node'); + var observe = require('can-observe'); + var classSupport = function () { + try { + eval('"use strict"; class A{};'); + return true; + } catch (e) { + return false; + } + }(); + helpers.makeTests('can-component viewModels with observe', function () { + QUnit.test('Basic can-observe type', function (assert) { + Component.extend({ + tag: 'observe-add', + view: stache('{{count}}'), + ViewModel: observe.Object.extend('ObserveAdd', {}, { + count: 0, + add: function () { + this.count++; + } + }) + }); + var frag = stache('')(); + var buttons = frag.firstChild.getElementsByTagName('button'); + var spans = frag.firstChild.getElementsByTagName('span'); + assert.equal(spans[0].innerHTML, '0', 'first value'); + domEvents.dispatch(buttons[0], 'click'); + assert.equal(spans[0].innerHTML, '1', 'second value'); + }); + if (classSupport) { + QUnit.test('ViewModel as observe(class)', function (assert) { + class Add extends observe.Object { + constructor(props) { + super(props); + this.count = 0; + } + add() { + this.count++; + } + } + Component.extend({ + tag: 'observe-class-add', + view: stache('{{count}}'), + ViewModel: Add + }); + var frag = stache('')(); + var buttons = frag.firstChild.getElementsByTagName('button'); + var spans = frag.firstChild.getElementsByTagName('span'); + assert.equal(spans[0].innerHTML, '0', 'first value'); + domEvents.dispatch(buttons[0], 'click'); + assert.equal(spans[0].innerHTML, '1', 'second value'); + }); + QUnit.test('connectedCallback and disconnectedCallback', function (assert) { + assert.expect(3); + var done = assert.async(); + Component.extend({ + tag: 'connected-component', + view: stache('rendered'), + ViewModel: class extends observe.Object { + connectedCallback(element) { + assert.equal(element.innerHTML, 'rendered', 'rendered view'); + assert.equal(element.nodeName, 'CONNECTED-COMPONENT', 'connectedCallback'); + return function () { + assert.equal(element.nodeName, 'CONNECTED-COMPONENT', 'disconnectedCallback'); + }; + } + } + }); + var template = stache(''); + var frag = template(); + var first = frag.firstChild; + domMutateNode.appendChild.call(this.fixture, frag); + helpers.afterMutation(function () { + domMutateNode.removeChild.call(first.parentNode, first); + helpers.afterMutation(function () { + done(); + }); + }); + }); + } + }); +}); +/*can-dom-mutate@2.0.8#dom-events*/ +define('can-dom-mutate@2.0.8#dom-events', [ + 'require', + 'exports', + 'module', + 'can-namespace', + './events/events' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var domMutateEvents = require('./events/events'); + module.exports = namespace.domMutateDomEvents = domMutateEvents; +}); +/*can-component@5.0.0#test/component-view-test*/ +define('can-component@5.0.0#test/component-view-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component', + 'can-dom-events', + 'can-dom-mutate/node', + 'can-dom-mutate/dom-events', + 'can-view-model', + 'can-define/map/map', + 'can-queues', + 'can-fragment', + 'can-view-callbacks', + 'can-view-scope' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + var domEvents = require('can-dom-events'); + var domMutateNode = require('can-dom-mutate/node'); + var domMutateDomEvents = require('can-dom-mutate/dom-events'); + var insertedEvent = domMutateDomEvents.inserted; + var canViewModel = require('can-view-model'); + var DefineMap = require('can-define/map/map'); + var queues = require('can-queues'); + var getFragment = require('can-fragment'); + var viewCallbacks = require('can-view-callbacks'); + var Scope = require('can-view-scope'); + var innerHTML = function (el) { + return el && helpers.cloneAndClean(el).innerHTML; + }; + helpers.makeTests('can-component views', function (doc, runTestInOnlyDocument) { + QUnit.test('lexical scoping', function (assert) { + Component.extend({ + tag: 'hello-world', + view: stache('{{greeting}} World{{exclamation}}'), + viewModel: function () { + return new SimpleMap({ greeting: 'Hello' }); + } + }); + var renderer = stache('{{greeting}}'); + var frag = renderer({ + greeting: 'World', + exclamation: '!' + }); + var hello = frag.firstChild; + assert.equal(hello.innerHTML.trim(), 'Hello World'); + Component.extend({ + tag: 'hello-world-no-template', + leakScope: false, + viewModel: function () { + return new SimpleMap({ greeting: 'Hello' }); + } + }); + renderer = stache('{{greeting}}'); + frag = renderer({ + greeting: 'World', + exclamation: '!' + }); + hello = frag.firstChild; + assert.equal(hello.innerHTML.trim(), 'Hello', 'If no view is provided to Component, treat bindings as dynamic.'); + }); + QUnit.test('dynamic scoping', function (assert) { + Component.extend({ + tag: 'hello-world', + leakScope: true, + view: stache('{{greeting}} World{{../exclamation}}'), + viewModel: function () { + return new SimpleMap({ greeting: 'Hello' }); + } + }); + var renderer = stache('{{greeting}}'); + var frag = renderer({ + greeting: 'World', + exclamation: '!' + }); + var hello = frag.firstChild; + assert.equal(hello.innerHTML.trim(), 'Hello Hello!'); + }); + QUnit.test('hello-world and whitespace around custom elements', function (assert) { + Component.extend({ + tag: 'hello-world', + view: stache('{{#if visible}}{{message}}{{else}}Click me{{/if}}'), + viewModel: function () { + return new SimpleMap({ + visible: false, + message: 'Hello There!' + }); + }, + events: { + click: function () { + this.viewModel.attr('visible', true); + } + } + }); + var renderer = stache(' '); + var frag = renderer({}); + var helloWorld = frag.childNodes.item(1); + domEvents.dispatch(helloWorld, 'click'); + assert.equal(helpers.cloneAndClean(helloWorld).innerHTML, 'Hello There!'); + }); + QUnit.test('self closing content tags', function (assert) { + Component.extend({ + 'tag': 'my-greeting', + view: stache('

      '), + viewModel: function () { + return new SimpleMap({ title: 'Component' }); + } + }); + var renderer = stache('{{site}} - {{title}}'); + var frag = renderer({ site: 'CanJS' }); + assert.equal(frag.firstChild.getElementsByTagName('span').length, 1, 'there is an h1'); + }); + QUnit.test('content extension stack overflow error', function (assert) { + Component({ + tag: 'outer-tag', + view: stache('inner-tag CONTENT ') + }); + Component({ + tag: 'inner-tag', + view: stache('inner-tag TEMPLATE ') + }); + var renderer = stache('outer-tag CONTENT'); + var frag = renderer(); + assert.equal(innerHTML(frag.firstChild.firstChild), 'inner-tag TEMPLATE inner-tag CONTENT outer-tag CONTENT'); + }); + QUnit.test('inserted event fires twice if component inside live binding block', function (assert) { + var undo = domEvents.addEvent(insertedEvent); + var inited = 0, inserted = 0; + Component.extend({ + tag: 'child-tag', + ViewModel: DefineMap.extend({ + init: function () { + inited++; + } + }), + events: { + ' inserted': function () { + inserted++; + } + } + }); + Component.extend({ + tag: 'parent-tag', + view: stache('{{#shown}}{{/shown}}'), + viewModel: DefineMap.extend('ParentTag', {}, { shown: { default: false } }), + events: { + ' inserted': function () { + this.viewModel.shown = true; + } + } + }); + var frag = stache('')({}); + domMutateNode.appendChild.call(this.fixture, frag); + var done = assert.async(); + var attempts = 0; + function checkCount() { + if (inserted >= 1 || attempts > 100) { + assert.equal(inited, 1, 'inited'); + assert.equal(inserted, 1, 'inserted'); + undo(); + done(); + } else { + attempts += 1; + setTimeout(checkCount, 30); + } + } + checkCount(); + }); + QUnit.test('Same component tag nested', function (assert) { + Component({ + 'tag': 'my-tag', + view: stache('

      ') + }); + var renderer = stache('
      OutterInner
      '); + var renderer2 = stache('
      3210
      '); + var renderer3 = stache('
      FirstSecond
      '); + assert.equal(renderer({}).firstChild.getElementsByTagName('p').length, 2, 'proper number of p tags'); + assert.equal(renderer2({}).firstChild.getElementsByTagName('p').length, 4, 'proper number of p tags'); + assert.equal(renderer3({}).firstChild.getElementsByTagName('p').length, 2, 'proper number of p tags'); + }); + QUnit.test('nested component within an #if is not live bound(#1025)', function (assert) { + Component.extend({ + tag: 'parent-component', + view: stache('{{#if shown}}{{/if}}'), + viewModel: function () { + return new SimpleMap({ shown: false }); + } + }); + Component.extend({ + tag: 'child-component', + view: stache('Hello world.') + }); + var renderer = stache(''); + var frag = renderer({}); + assert.equal(innerHTML(frag.firstChild), '', 'child component is not inserted'); + canViewModel(frag.firstChild).attr('shown', true); + assert.equal(innerHTML(helpers.cloneAndClean(frag).firstChild.firstChild), 'Hello world.', 'child component is inserted'); + canViewModel(frag.firstChild).attr('shown', false); + assert.equal(innerHTML(frag.firstChild), '', 'child component is removed'); + }); + QUnit.test('references scopes are available to bindings nested in components (#2029)', function (assert) { + var renderer = stache('' + ''); + Component.extend({ tag: 'wrap-er' }); + Component.extend({ + tag: 'export-er', + events: { + 'init': function () { + var self = this.viewModel; + var done = assert.async(); + setTimeout(function () { + self.set('value', 100); + var wrapper = frag.lastChild, simpleExample = wrapper.firstChild, textNode = simpleExample.firstChild; + assert.equal(textNode.nodeValue, '100', 'updated value with reference'); + done(); + }, 100); + } + } + }); + Component.extend({ + tag: 'simple-example', + view: stache('{{key}}') + }); + var frag = renderer({}); + }); + QUnit.test(' (#2151)', function (assert) { + var mapInstance = new DefineMap({ + items: [ + { + id: 1, + context: 'Item 1', + render: false + }, + { + id: 2, + context: 'Item 2', + render: false + } + ] + }); + Component.extend({ + tag: 'list-items', + view: stache('
        ' + '{{#items}}' + '{{#if render}}' + '
      • ' + '{{/if}}' + '{{/items}}' + '
      '), + viewModel: mapInstance, + leakScope: true + }); + Component.extend({ + tag: 'list-item', + view: stache('{{item.context}}') + }); + var renderer = stache(''); + var frag = renderer(); + queues.batch.start(); + canViewModel(frag.firstChild).get('items').forEach(function (item, index) { + item.set('render', true); + }); + queues.batch.stop(); + var lis = frag.firstChild.getElementsByTagName('li'); + assert.ok(innerHTML(lis[0]).indexOf('Item 1') >= 0, 'Item 1 written out'); + assert.ok(innerHTML(lis[1]).indexOf('Item 2') >= 0, 'Item 2 written out'); + }); + QUnit.test('two-way - reference - with tag', function (assert) { + Component.extend({ + tag: 'other-export', + viewModel: function () { + return new SimpleMap({ name: 'OTHER-EXPORT' }); + } + }); + Component.extend({ + tag: 'ref-export', + view: stache('{{*otherExport}}') + }); + var t1 = stache(''); + var f1 = t1(); + assert.equal(canViewModel(f1.firstChild.firstChild).get('name'), 'OTHER-EXPORT', 'viewModel set correctly'); + assert.equal(f1.firstChild.lastChild.nodeValue, 'OTHER-EXPORT', 'content'); + }); + runTestInOnlyDocument('custom renderer can provide setupBindings', function (assert) { + var rendererFactory = function (tmpl) { + var frag = getFragment(tmpl); + return function (scope, options) { + scope = scope || new Scope(); + options = options || {}; + if (frag.firstChild.nodeName === 'CUSTOM-RENDERER') { + viewCallbacks.tagHandler(frag.firstChild, 'custom-renderer', { + scope: scope, + options: options, + templateType: 'my-renderer', + setupBindings: function (el, callback, data) { + callback({ foo: 'qux' }); + } + }); + } else { + var tn = frag.firstChild.firstChild; + tn.nodeValue = scope.read('foo').value; + } + return frag; + }; + }; + Component.extend({ + tag: 'custom-renderer', + view: rendererFactory('
      {{foo}}
      '), + ViewModel: SimpleMap.extend({}) + }); + var renderer = rendererFactory(''); + var frag = renderer(); + var tn = frag.firstChild.firstChild.firstChild; + assert.equal(tn.nodeValue, 'qux', 'was bound!'); + }); + QUnit.test('view defaults to stache if set to a string', function (assert) { + Component.extend({ + tag: 'hello-world', + leakScope: true, + view: '{{greeting}} World{{../exclamation}}', + viewModel: function () { + return new SimpleMap({ greeting: 'Hello' }); + } + }); + var renderer = stache(''); + var frag = renderer({ exclamation: '!' }); + var hello = frag.firstChild; + assert.equal(hello.innerHTML.trim(), 'Hello World!'); + }); + QUnit.test('content tag available (#279)', function (assert) { + var template = stache('CT-OUTER-LIGHT-DOM'); + Component.extend({ + tag: 'ct-outer', + view: 'CT-OUTER-SHADOW-START CT-OUTER-SHADOW-END' + }); + Component.extend({ + tag: 'ct-inner', + leakScope: true, + view: stache('') + }); + var frag = template(); + var span = frag.firstChild.getElementsByTagName('span')[0]; + assert.equal(span.innerHTML, 'CT-OUTER-LIGHT-DOM'); + }); + }); +}); +/*can-component@5.0.0#test/component-helpers-test*/ +define('can-component@5.0.0#test/component-helpers-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-stache', + 'can-component' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var stache = require('can-stache'); + var Component = require('can-component'); + helpers.makeTests('can-component helpers', function () { + QUnit.test('helpers reference the correct instance (#515)', function (assert) { + assert.expect(2); + Component({ + tag: 'my-text', + view: stache('

      {{valueHelper()}}

      '), + helpers: { + valueHelper: function () { + return this.get('value'); + } + } + }); + var renderer = stache(''); + var frag = renderer({}); + assert.equal(frag.firstChild.firstChild.firstChild.nodeValue, 'value1'); + assert.equal(frag.lastChild.firstChild.firstChild.nodeValue, 'value2'); + }); + }); +}); +/*can-component@5.0.0#test/component-events-test*/ +define('can-component@5.0.0#test/component-events-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component', + 'can-view-model', + 'can-simple-observable', + 'can-dom-events', + 'can-dom-mutate/node', + 'can-dom-mutate/dom-events' +], function (require, exports, module) { + (function (global, require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + var canViewModel = require('can-view-model'); + var SimpleObservable = require('can-simple-observable'); + var domEvents = require('can-dom-events'); + var domMutateNode = require('can-dom-mutate/node'); + var domMutateDomEvents = require('can-dom-mutate/dom-events'); + var insertedEvent = domMutateDomEvents.inserted; + var removedEvent = domMutateDomEvents.removed; + helpers.makeTests('can-component events', function () { + QUnit.test('value observables formerly (#550)', function (assert) { + var nameChanges = 0; + Component.extend({ + tag: 'viewmodel-rebinder', + events: { + '{name}': function () { + nameChanges++; + } + } + }); + var renderer = stache(''); + var frag = renderer(); + var viewModel = canViewModel(frag.firstChild); + var n1 = new SimpleObservable(), n2 = new SimpleObservable(); + viewModel.set('name', n1); + n1.set('updated'); + viewModel.set('name', n2); + n2.set('updated'); + assert.equal(nameChanges, 2); + }); + QUnit.test('Component events bind to window', function (assert) { + window.tempMap = new SimpleMap(); + Component.extend({ + tag: 'window-events', + events: { + '{tempMap} prop': function () { + assert.ok(true, 'called templated event'); + } + } + }); + var renderer = stache(''); + renderer(); + window.tempMap.set('prop', 'value'); + window.tempMap = undefined; + try { + delete window.tempMap; + } catch (e) { + } + }); + QUnit.test('stache conditionally nested components calls inserted once (#967)', function (assert) { + assert.expect(1); + var undo = domEvents.addEvent(insertedEvent); + Component.extend({ + tag: 'can-parent-stache', + viewModel: function () { + return new SimpleMap({ shown: true }); + }, + view: stache('{{#if shown}}{{/if}}') + }); + Component.extend({ + tag: 'can-child', + events: { + inserted: function () { + assert.ok(true, 'called inserted once'); + } + } + }); + var renderer = stache(''); + var frag = renderer(); + domMutateNode.appendChild.call(this.fixture, frag); + var done = assert.async(); + setTimeout(function () { + undo(); + done(); + }, 100); + }); + QUnit.test('viewModel objects with Constructor functions as properties do not get converted (#1261)', function (assert) { + assert.expect(1); + var done = assert.async(); + var HANDLER; + var Test = SimpleMap.extend({ + addEventListener: function (ev, handler) { + HANDLER = handler; + }, + removeEventListener: function () { + } + }, { + setup: function (props) { + props.test = 'Yeah'; + return SimpleMap.prototype.setup.apply(this, arguments); + } + }); + Component.extend({ + tag: 'my-app', + viewModel: SimpleMap.extend({ + setup: function (props) { + props.MyConstruct = Test; + return SimpleMap.prototype.setup.apply(this, arguments); + } + }), + events: { + '{MyConstruct} something': function () { + assert.ok(true, 'Event got triggered'); + done(); + } + } + }); + var frag = stache('')(); + domMutateNode.appendChild.call(this.fixture, frag); + HANDLER.call(Test, { type: 'something' }); + }); + QUnit.test('removing bound viewModel properties on connectedCallback #1415', function (assert) { + var state = new SimpleMap({ + product: new SimpleMap({ + id: 1, + name: 'Tom' + }) + }); + Component.extend({ + tag: 'destroyable-component', + ViewModel: { + connectedCallback: function () { + this.set('product', null); + } + } + }); + var frag = stache('')(state); + domMutateNode.appendChild.call(this.fixture, frag); + domMutateNode.removeChild.call(this.fixture, this.fixture.firstChild); + var done = assert.async(); + helpers.afterMutation(function () { + assert.ok(state.attr('product') == null, 'product was removed'); + done(); + }); + }); + QUnit.test('changing viewModel property rebinds {viewModel.<...>} events (#1529)', function (assert) { + assert.expect(2); + Component.extend({ + tag: 'rebind-viewmodel', + events: { + init: function () { + this.viewModel.set('anItem', new SimpleMap({})); + }, + '{scope.anItem} name': function () { + assert.ok(true, 'Change event on scope'); + }, + '{viewModel.anItem} name': function () { + assert.ok(true, 'Change event on viewModel'); + } + } + }); + var frag = stache('')(); + var rebind = frag.firstChild; + domMutateNode.appendChild.call(this.fixture, rebind); + canViewModel(rebind).get('anItem').set('name', 'CDN'); + }); + QUnit.test('DOM trees not releasing when referencing CanMap inside CanMap in view (#1593)', function (assert) { + var undo = domEvents.addEvent(removedEvent); + var baseTemplate = stache('{{#if show}}{{/if}}'), show = new SimpleObservable(true), state = new SimpleMap({ inner: 1 }); + var removeCount = 0; + Component.extend({ + tag: 'my-inside', + events: { + removed: function () { + removeCount++; + } + }, + leakScope: true + }); + Component.extend({ + tag: 'my-outside', + view: stache('{{#if ../state.inner}}{{/if}}'), + leakScope: true + }); + domMutateNode.appendChild.call(this.fixture, baseTemplate({ + show: show, + state: state + })); + var done = assert.async(); + helpers.runTasks([ + function () { + show.set(false); + }, + function () { + state.set('inner', null); + }, + function () { + assert.equal(removeCount, 1, 'internal removed once'); + show.set(true); + }, + function () { + state.set('inner', 2); + }, + function () { + state.set('inner', null); + }, + function () { + assert.equal(removeCount, 2, 'internal removed twice'); + undo(); + } + ], done); + }); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@5.0.0#test/example-test*/ +define('can-component@5.0.0#test/example-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + './helpers', + 'can-simple-map', + 'can-stache', + 'can-component', + 'can-define/list/list', + 'can-define/map/map', + 'can-dom-events', + 'can-view-model', + 'can-dom-mutate/node', + 'can-dom-mutate/dom-events', + 'can-log', + 'can-queues' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var helpers = require('./helpers'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var Component = require('can-component'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var domEvents = require('can-dom-events'); + var canViewModel = require('can-view-model'); + var domMutateNode = require('can-dom-mutate/node'); + var domMutateDomEvents = require('can-dom-mutate/dom-events'); + var insertedEvent = domMutateDomEvents.inserted; + var canLog = require('can-log'); + var queues = require('can-queues'); + var innerHTML = function (el) { + return el && el.innerHTML; + }; + helpers.makeTests('can-component examples', function (doc) { + var Paginate = DefineMap.extend({ + count: { default: Infinity }, + offset: { default: 0 }, + limit: { default: 100 }, + setCount: function (newCount, success, error) { + return newCount < 0 ? 0 : newCount; + }, + setOffset: function (newOffset) { + return newOffset < 0 ? 0 : Math.min(newOffset, !isNaN(this.count - 1) ? this.count - 1 : Infinity); + }, + next: function () { + this.set('offset', this.offset + this.limit); + }, + prev: function () { + this.set('offset', this.offset - this.limit); + }, + canNext: function () { + return this.get('offset') < this.get('count') - this.get('limit'); + }, + canPrev: function () { + return this.get('offset') > 0; + }, + page: function (newVal) { + if (newVal === undefined) { + return Math.floor(this.get('offset') / this.get('limit')) + 1; + } else { + this.set('offset', (parseInt(newVal) - 1) * this.get('limit')); + } + }, + pageCount: function () { + return this.get('count') ? Math.ceil(this.get('count') / this.get('limit')) : null; + } + }); + QUnit.test('treecombo', function (assert) { + var TreeComboViewModel = DefineMap.extend('TreeComboViewModel', { + items: { Default: DefineList }, + breadcrumb: { Default: DefineList }, + selected: { Default: DefineList }, + selectableItems: function () { + var breadcrumb = this.get('breadcrumb'); + if (breadcrumb.length) { + return breadcrumb[breadcrumb.length - 1].children; + } else { + return this.get('items'); + } + }, + showChildren: function (item, ev) { + ev.stopPropagation(); + this.get('breadcrumb').push(item); + }, + emptyBreadcrumb: function () { + this.get('breadcrumb').update([]); + }, + updateBreadcrumb: function (item) { + var breadcrumb = this.get('breadcrumb'), index = breadcrumb.indexOf(item); + breadcrumb.splice(index + 1, breadcrumb.length - index - 1); + }, + toggle: function (item) { + var selected = this.get('selected'), index = selected.indexOf(item); + if (index === -1) { + selected.push(item); + } else { + selected.splice(index, 1); + } + }, + isSelected: function (item) { + return this.get('selected').indexOf(item) > -1; + } + }); + Component.extend({ + tag: 'treecombo', + view: stache('
        ' + '
      • {{title}}
      • ' + '{{#each breadcrumb}}' + '
      • {{title}}
      • ' + '{{/each}}' + '
      ' + '
        ' + '' + '{{#selectableItems()}}' + '
      • ' + '' + '{{title}}' + '{{#if children.length}}' + '' + '{{/if}}' + '
      • ' + '{{/selectableItems}}' + '
        ' + '
      '), + ViewModel: TreeComboViewModel + }); + var renderer = stache(''); + var BaseViewModel = DefineMap.extend('BaseViewModel', { seal: false }, {}); + var base = new BaseViewModel({}); + var frag = renderer(base); + var root = doc.createElement('div'); + root.appendChild(frag); + var items = [ + { + id: 1, + title: 'Midwest', + children: [ + { + id: 5, + title: 'Illinois', + children: [ + { + id: 23423, + title: 'Chicago' + }, + { + id: 4563, + title: 'Springfield' + }, + { + id: 4564, + title: 'Naperville' + } + ] + }, + { + id: 6, + title: 'Wisconsin', + children: [ + { + id: 232423, + title: 'Milwaulkee' + }, + { + id: 45463, + title: 'Green Bay' + }, + { + id: 45464, + title: 'Madison' + } + ] + } + ] + }, + { + id: 2, + title: 'East Coast', + children: [ + { + id: 25, + title: 'New York', + children: [ + { + id: 3413, + title: 'New York' + }, + { + id: 4613, + title: 'Rochester' + }, + { + id: 4516, + title: 'Syracuse' + } + ] + }, + { + id: 6, + title: 'Pennsylvania', + children: [ + { + id: 2362423, + title: 'Philadelphia' + }, + { + id: 454663, + title: 'Harrisburg' + }, + { + id: 454664, + title: 'Scranton' + } + ] + } + ] + } + ]; + var done = assert.async(); + setTimeout(function () { + base.set('locations', items); + var itemsList = base.get('locations'); + var treecombo = root.firstChild, breadcrumb = treecombo.firstChild, breadcrumbLIs = function () { + return breadcrumb.getElementsByTagName('li'); + }, options = treecombo.lastChild, optionsLis = function () { + return options.getElementsByTagName('li'); + }; + assert.equal(breadcrumbLIs().length, 1, 'Only the default title is shown'); + assert.equal(breadcrumbLIs()[0].innerHTML, 'Locations', 'The correct title from the attribute is shown'); + assert.equal(itemsList.length, optionsLis().length, 'first level items are displayed'); + domEvents.dispatch(optionsLis()[0], 'click'); + assert.equal(optionsLis()[0].className, 'active', 'toggling something not selected adds active'); + assert.ok(optionsLis()[0].getElementsByTagName('input')[0].checked, 'toggling something not selected checks checkbox'); + assert.equal(canViewModel(treecombo, 'selected').length, 1, 'there is one selected item'); + assert.equal(canViewModel(treecombo).selected[0], itemsList[0], 'the midwest is in selected'); + var selectedList = canViewModel(treecombo, 'selected'); + selectedList.pop(); + assert.equal(optionsLis()[0].className, '', 'removing selected item in viewModel removes \'active\' class'); + domEvents.dispatch(optionsLis()[0].getElementsByTagName('button')[0], 'click'); + assert.equal(breadcrumbLIs().length, 2, 'Only the default title is shown'); + assert.equal(breadcrumbLIs()[1].innerHTML, 'Midwest', 'The breadcrumb has an item in it'); + assert.ok(/Illinois/.test(optionsLis()[0].innerHTML), 'A child of the top breadcrumb is displayed'); + domEvents.dispatch(optionsLis()[0].getElementsByTagName('button')[0], 'click'); + assert.ok(/Chicago/.test(optionsLis()[0].innerHTML), 'A child of the top breadcrumb is displayed'); + assert.ok(!optionsLis()[0].getElementsByTagName('button').length, 'no show children button'); + domEvents.dispatch(breadcrumbLIs()[1], 'click'); + assert.equal(innerHTML(breadcrumbLIs()[1]), 'Midwest', 'The breadcrumb has an item in it'); + assert.ok(/Illinois/.test(innerHTML(optionsLis()[0])), 'A child of the top breadcrumb is displayed'); + domEvents.dispatch(breadcrumbLIs()[0], 'click'); + assert.equal(breadcrumbLIs().length, 1, 'Only the default title is shown'); + assert.equal(innerHTML(breadcrumbLIs()[0]), 'Locations', 'The correct title from the attribute is shown'); + done(); + }, 100); + }); + QUnit.test('deferred grid', function (assert) { + var GridViewModel = DefineMap.extend({ + items: { Default: DefineList }, + waiting: { default: true } + }); + Component.extend({ + tag: 'grid', + ViewModel: GridViewModel, + view: stache('
      '), + leakScope: true, + events: { + init: function () { + this.update(); + }, + '{viewModel} deferreddata': 'update', + update: function () { + var deferred = this.viewModel.get('deferreddata'), viewModel = this.viewModel; + if (deferred && deferred.then) { + this.viewModel.set('waiting', true); + deferred.then(function (items) { + viewModel.get('items').update(items); + }); + } else { + viewModel.get('items').update(deferred); + } + }, + '{items} length': function () { + this.viewModel.set('waiting', false); + } + } + }); + var SimulatedScope = DefineMap.extend({ + set: { default: 0 }, + deferredData: function () { + var deferred = {}; + var promise = new Promise(function (resolve, reject) { + deferred.resolve = resolve; + deferred.reject = reject; + }); + var set = this.get('set'); + if (set === 0) { + setTimeout(function () { + deferred.resolve([{ + first: 'Justin', + last: 'Meyer' + }]); + }, 100); + } else if (set === 1) { + setTimeout(function () { + deferred.resolve([{ + first: 'Brian', + last: 'Moschel' + }]); + }, 100); + } + return promise; + } + }); + var viewModel = new SimulatedScope(); + var renderer = stache('' + '{{#each items}}' + '' + '{{first}}' + '{{last}}' + '' + '{{/each}}' + ''); + domMutateNode.appendChild.call(this.fixture, renderer({ viewModel: viewModel })); + var gridScope = canViewModel(this.fixture.firstChild); + assert.equal(gridScope.get('waiting'), true, 'The grid is initially waiting on the deferreddata to resolve'); + var done = assert.async(); + var self = this; + var waitingHandler = function () { + gridScope.off('waiting', waitingHandler); + setTimeout(function () { + var tds = self.fixture.getElementsByTagName('td'); + assert.equal(tds.length, 2, 'there are 2 tds'); + gridScope.on('waiting', function (ev, newVal) { + if (newVal === false) { + setTimeout(function () { + tds = self.fixture.getElementsByTagName('td'); + assert.equal(innerHTML(tds[0]), 'Brian', 'td changed to brian'); + done(); + }, 100); + } + }); + viewModel.set = 1; + }, 100); + }; + gridScope.on('waiting', waitingHandler); + }); + QUnit.test('nextprev', function (assert) { + Component.extend({ + tag: 'next-prev', + view: stache('Prev' + 'Next') + }); + var paginator = new Paginate({ + limit: 20, + offset: 0, + count: 100 + }); + var renderer = stache(''); + var frag = renderer({ paginator: paginator }); + var nextPrev = frag.firstChild; + var prev = nextPrev.firstChild, next = nextPrev.lastChild; + assert.ok(!/enabled/.test(prev.className), 'prev is not enabled'); + assert.ok(/enabled/.test(next.className), 'next is enabled'); + domEvents.dispatch(next, 'click'); + assert.ok(/enabled/.test(prev.getAttribute('class')), 'prev is enabled'); + }); + QUnit.test('page-count', function (assert) { + Component.extend({ + tag: 'page-count', + view: stache('Page {{page()}}.') + }); + var paginator = new Paginate({ + limit: 20, + offset: 0, + count: 100 + }); + var renderer = stache(''); + var frag = renderer(new SimpleMap({ paginator: paginator })); + var span = frag.firstChild.getElementsByTagName('span')[0]; + assert.equal(span.firstChild.nodeValue, '1'); + paginator.next(); + assert.equal(span.firstChild.nodeValue, '2'); + paginator.next(); + assert.equal(span.firstChild.nodeValue, '3'); + }); + if (System.env !== 'canjs-test') { + QUnit.test('basic tabs', function (assert) { + var undo = domEvents.addEvent(insertedEvent); + var TabsViewModel = DefineMap.extend({ + active: 'any', + panels: { Default: DefineList }, + addPanel: function (panel) { + if (this.panels.length === 0) { + this.makeActive(panel); + } + this.panels.push(panel); + }, + removePanel: function (panel) { + var panels = this.panels; + queues.batch.start(); + var index = panels.indexOf(panel); + canLog.log(index); + panels.splice(index, 1); + if (panel === this.active) { + if (panels.length) { + this.makeActive(panels[0]); + } else { + this.active = null; + } + } + queues.batch.stop(); + }, + makeActive: function (panel) { + this.active = panel; + this.panels.forEach(function (panel) { + panel.active = false; + }); + panel.active = true; + }, + isActive: function (panel) { + return this.active === panel; + } + }); + Component.extend({ + tag: 'tabs', + ViewModel: TabsViewModel, + view: stache('
        ' + '{{#panels}}' + '
      • {{title}}
      • ' + '{{/panels}}' + '
      ' + '') + }); + Component.extend({ + view: stache('{{#if active}}{{/if}}'), + tag: 'panel', + ViewModel: DefineMap.extend({ active: { default: false } }), + events: { + ' inserted': function () { + canViewModel(this.element.parentNode).addPanel(this.viewModel); + this.parent = this.element.parentNode.viewModel; + }, + ' beforeremove': function () { + this.parent.removePanel(this.viewModel); + } + } + }); + var renderer = stache('{{#each foodTypes}}{{content}}{{/each}}'); + var foodTypes = new DefineList([ + { + title: 'Fruits', + content: 'oranges, apples' + }, + { + title: 'Breads', + content: 'pasta, cereal' + }, + { + title: 'Sweets', + content: 'ice cream, candy' + } + ]); + var frag = renderer({ foodTypes: foodTypes }); + domMutateNode.appendChild.call(this.fixture, frag); + var testArea = this.fixture; + var done = assert.async(); + helpers.runTasks([ + function () { + var lis = testArea.getElementsByTagName('li'); + assert.equal(lis.length, 3, 'three lis added'); + foodTypes.forEach(function (type, i) { + assert.equal(innerHTML(lis[i]), type.title, 'li ' + i + ' has the right content'); + }); + foodTypes.push({ + title: 'Vegies', + content: 'carrots, kale' + }); + }, + function () { + var lis = testArea.getElementsByTagName('li'); + assert.equal(lis.length, 4, 'li added'); + foodTypes.forEach(function (type, i) { + assert.equal(innerHTML(lis[i]), type.title, 'li ' + i + ' has the right content'); + }); + assert.equal(testArea.getElementsByTagName('panel').length, 4, 'panel added'); + canLog.log('SHIFTY'); + foodTypes.shift(); + }, + function () { + var lis = testArea.getElementsByTagName('li'); + assert.equal(lis.length, 3, 'removed li after shifting a foodType'); + foodTypes.forEach(function (type, i) { + assert.equal(innerHTML(lis[i]), type.title, 'li ' + i + ' has the right content'); + }); + var panels = testArea.getElementsByTagName('panel'); + assert.equal(lis[0].className, 'active', 'the first element is active'); + assert.equal(innerHTML(helpers.cloneAndClean(panels[0])), 'pasta, cereal', 'the first content is shown'); + assert.equal(innerHTML(helpers.cloneAndClean(panels[1])), '', 'the second content is removed'); + domEvents.dispatch(lis[1], 'click'); + lis = testArea.getElementsByTagName('li'); + assert.equal(lis[1].className, 'active', 'the second element is active'); + assert.equal(lis[0].className, '', 'the first element is not active'); + assert.equal(innerHTML(helpers.cloneAndClean(panels[0])), '', 'the second content is removed'); + assert.equal(innerHTML(helpers.cloneAndClean(panels[1])), 'ice cream, candy', 'the second content is shown'); + undo(); + } + ], done); + }); + } + }); +}); +/*can-component@5.0.0#test/component-slot-test*/ +define('can-component@5.0.0#test/component-slot-test', [ + 'require', + 'exports', + 'module', + 'can-component', + 'can-stache', + 'steal-qunit', + 'can-define/map/map', + 'can-view-model', + 'can-symbol', + './helpers' +], function (require, exports, module) { + var Component = require('can-component'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + var DefineMap = require('can-define/map/map'); + var viewModel = require('can-view-model'); + var canSymbol = require('can-symbol'); + var helpers = require('./helpers'); + QUnit.module('can-components - can-slots'); + QUnit.test(' Works', function (assert) { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + ''), + ViewModel: ViewModel, + leakScope: true + }); + var renderer = stache('' + '' + '{{subject}}' + '' + '' + '{{body}}' + '' + ''); + var testView = renderer(); + assert.equal(testView.firstChild.childNodes[0].nodeValue, 'Hello World'); + assert.equal(testView.firstChild.childNodes[1].nodeValue, 'Later Gator'); + }); + QUnit.test(' leakScope false acts as expected', function (assert) { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + ''), + ViewModel: ViewModel + }); + var renderer = stache('' + '' + '{{subject}}' + '' + '' + '{{body}}' + '' + ''); + var testView = renderer({ + subject: 'foo', + body: 'bar' + }); + assert.equal(testView.firstChild.childNodes[0].nodeValue, 'foo'); + assert.equal(testView.firstChild.childNodes[1].nodeValue, 'bar'); + }); + QUnit.test(' Re-use templates', function (assert) { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + ''), + ViewModel: ViewModel, + leakScope: true + }); + var renderer = stache('' + '' + '{{subject}}' + '' + ''); + var testView = renderer(); + assert.equal(testView.firstChild.childNodes[0].nodeValue, 'Hello World'); + assert.equal(testView.firstChild.childNodes[1].nodeValue, 'Hello World'); + }); + QUnit.test(' Works with default content', function (assert) { + var ViewModel = DefineMap.extend({}); + Component.extend({ + tag: 'my-email', + view: stache('' + 'Default Content' + ''), + ViewModel: ViewModel + }); + var renderer = stache('' + '' + ''); + var testView = renderer(); + assert.equal(testView.firstChild.innerHTML, 'Default Content'); + }); + QUnit.test(' Works in a self-closing template', function (assert) { + var ViewModel = DefineMap.extend({}); + Component.extend({ + tag: 'my-email', + view: stache('' + 'Default Content' + ''), + ViewModel: ViewModel + }); + var renderer = stache(''); + var testView = renderer(); + assert.equal(testView.firstChild.innerHTML, 'Default Content'); + }); + QUnit.test(' Context one-way binding works', function (assert) { + var ViewModel = DefineMap.extend('MyEmailVM', { subject: { default: 'Hello World' } }); + Component.extend({ + tag: 'my-email', + view: stache(''), + ViewModel: ViewModel + }); + var renderer = stache('' + '{{this}}' + ''); + var frag = renderer(); + var vm = viewModel(frag.firstChild); + assert.equal(helpers.cloneAndClean(frag).firstChild.firstChild.innerHTML, 'Hello World'); + vm.subject = 'Later Gator'; + assert.equal(helpers.cloneAndClean(frag).firstChild.firstChild.innerHTML, 'Later Gator'); + }); + QUnit.test(' Context two-way binding works', function (assert) { + var ViewModel = DefineMap.extend('MyEmailVM', {}, { subject: { default: 'Hello World' } }); + Component.extend({ + tag: 'my-email', + view: stache(''), + ViewModel: ViewModel + }); + Component.extend({ + tag: 'my-subject', + view: stache('{{subject}}'), + ViewModel: DefineMap.extend('SubjectVM') + }); + var renderer = stache('' + '' + ''); + var frag = renderer(); + var vm = viewModel(frag.firstChild); + var childVM = viewModel(frag.firstChild.getElementsByTagName('my-subject')[0]); + assert.equal(helpers.cloneAndClean(frag).firstChild.firstChild.innerHTML, 'Hello World'); + vm.subject = 'Later Gator'; + assert.equal(helpers.cloneAndClean(frag).firstChild.firstChild.innerHTML, 'Later Gator'); + childVM.subject = 'After a while crocodile'; + assert.equal(vm.subject, 'After a while crocodile'); + }); + QUnit.test(' Context child-to-parent binding works', function (assert) { + var ViewModel = DefineMap.extend({ subject: { default: 'Hello World' } }); + Component.extend({ + tag: 'my-email', + view: stache(''), + ViewModel: ViewModel + }); + Component.extend({ + tag: 'my-subject', + view: stache('{{subject}}'), + ViewModel: DefineMap.extend({ subject: { default: 'Yo' } }) + }); + var renderer = stache('' + '' + ''); + var frag = renderer(); + var vm = viewModel(frag.firstChild); + var childVM = viewModel(frag.firstChild.getElementsByTagName('my-subject')[0]); + assert.equal(helpers.cloneAndClean(frag.firstChild).firstChild.innerHTML, 'Yo'); + childVM.subject = 'bar'; + assert.equal(helpers.cloneAndClean(frag.firstChild).firstChild.innerHTML, 'bar'); + assert.equal(vm.subject, 'bar'); + }); + QUnit.test(' Works alongside ', function (assert) { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + ''), + ViewModel: ViewModel, + leakScope: true + }); + var renderer = stache('' + '' + '

      {{subject}}

      ' + '
      ' + 'Some content' + '
      '); + var testView = renderer(); + assert.equal(testView.firstChild.childNodes[0].firstChild.nodeValue, 'Hello World'); + assert.equal(testView.firstChild.childNodes[1].firstChild.nodeValue, 'Some content'); + }); + QUnit.test(' Works alongside with default content', function (assert) { + var ViewModel = DefineMap.extend({ + subject: { default: 'Hello World' }, + body: { default: 'Later Gator' } + }); + Component.extend({ + tag: 'my-email', + view: stache('' + 'Default content'), + ViewModel: ViewModel, + leakScope: true + }); + var renderer = stache('' + '' + '

      {{subject}}

      ' + '
      ' + '
      '); + var testView = renderer(); + assert.equal(testView.firstChild.childNodes[0].firstChild.nodeValue, 'Hello World'); + assert.equal(testView.firstChild.childNodes[1].nodeValue, 'Default content'); + }); + QUnit.test(' Can be used conditionally and will remove bindings', function (assert) { + var ViewModel = DefineMap.extend('MyEmailVM', { + subject: { default: 'Hello World' }, + showSubject: { default: true } + }); + Component.extend({ + tag: 'my-email', + view: stache('{{#if showSubject}}{{/if}}'), + ViewModel: ViewModel + }); + var renderer = stache('' + '' + '

      {{this}}

      ' + '
      ' + '
      '); + var testView = renderer(); + assert.equal(helpers.cloneAndClean(testView.firstChild).firstChild.firstChild.nodeValue, 'Hello World'); + var vm = viewModel(testView.firstChild); + vm.showSubject = false; + var done = assert.async(); + assert.equal(helpers.cloneAndClean(testView.firstChild).children.length, 0, 'items removed'); + setTimeout(function () { + var handlers = vm[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get(['subject']).length, 0, 'no handlers'); + done(); + }, 50); + }); + QUnit.test('blocks directly nested within template', function (assert) { + var template = stache('' + '' + '{{#if(showIf)}}' + '.showIf is true' + '{{else}}' + '.showIf is false' + '{{/if}}' + '' + ''); + var viewModel = new DefineMap({ + showSlot: true, + showIf: true + }); + Component.extend({ + tag: 'home-page', + view: stache('{{#if(showSlot)}}' + '' + '{{/if}}'), + viewModel: viewModel + }); + var frag = template(); + var homePage = frag.firstChild; + viewModel.showIf = false; + viewModel.showSlot = false; + var spans = homePage.getElementsByTagName('span'); + assert.equal(spans.length, 0, 'all spans removed'); + }); + QUnit.test('able to pass individual values (#291)', function (assert) { + Component.extend({ + tag: 'pass-values-to-slots', + view: '', + ViewModel: { + count: { + type: 'number', + default: 0 + }, + add: function (increment) { + this.count += increment; + } + } + }); + var template = stache('' + '' + '{{count}}' + '' + ''); + var frag = template(); + var passValuesToSlots = frag.firstElementChild || frag.firstChild; + passValuesToSlots.viewModel.add(5); + var count = passValuesToSlots.querySelector('.count'); + assert.equal(count.innerHTML, '10', 'updated count value'); + }); + QUnit.test('slots are passed as variables', function (assert) { + Component.extend({ + tag: 'pass-values-to-slots', + view: '', + ViewModel: { + count: { + type: 'number', + default: 0 + } + } + }); + var template = stache('' + '' + '{{count}}-{{this.count}}' + '' + ''); + var frag = template({ count: 1 }); + var passValuesToSlots = frag.firstElementChild || frag.firstChild; + var count = passValuesToSlots.querySelector('.count'); + assert.equal(count.innerHTML, '0-1', 'updated count value'); + }); +}); +/*can-component@5.0.0#test/component-define-test*/ +define('can-component@5.0.0#test/component-define-test', [ + 'require', + 'exports', + 'module', + 'can-component', + 'can-stache', + 'steal-qunit', + 'can-define', + 'can-define/map/map', + 'can-view-model', + 'can-log/dev/dev', + 'can-test-helpers' +], function (require, exports, module) { + var Component = require('can-component'); + var stache = require('can-stache'); + var QUnit = require('steal-qunit'); + var define = require('can-define'); + var DefineMap = require('can-define/map/map'); + var viewModel = require('can-view-model'); + var canDev = require('can-log/dev/dev'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-component with can-define'); + QUnit.test('Works with can-define', function (assert) { + var VM = define.Constructor({ + firstName: { type: 'string' }, + lastName: { type: 'string' }, + fullName: { + get: function () { + return [ + this.firstName, + this.lastName + ].join(' '); + } + } + }); + Component.extend({ + tag: 'can-define-component', + ViewModel: VM, + view: stache('Name: {{fullName}}') + }); + var frag = stache('')({ + firstName: 'Chris', + lastName: 'Gomez' + }); + var vm = viewModel(frag.firstChild); + assert.ok(vm instanceof VM, 'Constructor was called'); + assert.equal(vm.firstName, 'Chris', 'ViewModel was set from scope'); + assert.equal(vm.lastName, 'Gomez', 'ViewModel was set from scope'); + assert.equal(frag.firstChild.innerHTML, 'Name: Chris Gomez', 'Rendered fullName'); + vm.firstName = 'Justin'; + vm.lastName = 'Meyer'; + assert.equal(frag.firstChild.innerHTML, 'Name: Justin Meyer', 'Rendered fullName after change'); + }); + QUnit.test('scope method works', function (assert) { + Component.extend({ + tag: 'my-element', + viewModel: function (properties, scope, element) { + assert.deepEqual(properties, { + first: 'Justin', + last: 'Meyer' + }); + return new DefineMap(properties); + } + }); + stache('')({ + firstName: 'Justin', + middleName: 'Barry' + }); + }); + QUnit.test('33 - works when instantiated with an object for ViewModel', function (assert) { + Component.extend({ + tag: 'test-element', + view: stache('{{someMethod()}}'), + ViewModel: { + someMethod: function () { + assert.ok(true, 'Function got called'); + return true; + } + } + }); + var renderer = stache(''); + renderer(); + }); + QUnit.test('helpers do not leak when leakscope is false (#77)', function (assert) { + var called = 0; + Component.extend({ + tag: 'inner-el', + view: stache('inner{{test}}'), + leakScope: false + }); + Component.extend({ + tag: 'outer-el', + view: stache('outer:'), + helpers: { + test: function () { + called++; + return 'heyo'; + } + } + }); + var renderer = stache(''); + renderer(); + assert.equal(called, 0, 'Outer helper not called'); + }); + QUnit.test('helpers do leak when leakscope is true (#77)', function (assert) { + var called = 0; + Component.extend({ + tag: 'inner-el', + view: stache('inner{{../test()}}'), + leakScope: true + }); + Component.extend({ + tag: 'outer-el', + view: stache('outer:'), + helpers: { + test: function () { + called++; + return 'heyo'; + } + } + }); + var renderer = stache(''); + renderer(); + assert.equal(called, 1, 'Outer helper called once'); + }); + if (System.env.indexOf('production') < 0) { + QUnit.test('warn if viewModel is assigned a DefineMap (#14)', function (assert) { + assert.expect(1); + var oldwarn = canDev.warn; + canDev.warn = function (mesg) { + assert.equal(mesg, 'can-component: Assigning a DefineMap or constructor type to the viewModel property may not be what you intended. Did you mean ViewModel instead? More info: https://canjs.com/doc/can-component.prototype.ViewModel.html', 'Warning is expected message'); + }; + var VM = DefineMap.extend({}); + Component.extend({ + tag: 'can-vm1-test-component', + viewModel: VM + }); + Component.extend({ + tag: 'can-vm2-test-component', + viewModel: function () { + } + }); + canDev.warn = oldwarn; + }); + } + QUnit.test('ViewModel defaults to DefineMap if set to an Object', function (assert) { + Component.extend({ + tag: 'can-define-component', + ViewModel: { + firstName: { type: 'string' }, + lastName: { type: 'string' }, + fullName: { + get: function () { + return [ + this.firstName, + this.lastName + ].join(' '); + } + } + }, + view: stache('Name: {{fullName}}') + }); + var frag = stache('')({ + firstName: 'Chris', + lastName: 'Gomez' + }); + var vm = viewModel(frag.firstChild); + assert.ok(vm instanceof DefineMap, 'vm is a DefineMap'); + assert.equal(vm.firstName, 'Chris', 'ViewModel was set from scope'); + assert.equal(vm.lastName, 'Gomez', 'ViewModel was set from scope'); + assert.equal(frag.firstChild.innerHTML, 'Name: Chris Gomez', 'Rendered fullName'); + vm.firstName = 'Justin'; + vm.lastName = 'Meyer'; + assert.equal(frag.firstChild.innerHTML, 'Name: Justin Meyer', 'Rendered fullName after change'); + }); + QUnit.test('ViewModel properties default to DefineList if set to an Array (#225)', function (assert) { + Component.extend({ + tag: 'viewmodel-lists', + view: 'Hello, World', + ViewModel: { + items: { + default: function () { + return [ + 'one', + 'two' + ]; + } + } + } + }); + var renderer = stache(''); + var fragOne = renderer(); + var vm = viewModel(fragOne.firstChild); + assert.ok(vm.items instanceof define.DefineList, 'vm is a DefineList'); + }); + testHelpers.dev.devOnlyTest('filename should be passed to stache() for inline views', function (assert) { + Component.extend({ + tag: 'my-filename-component', + ViewModel: {}, + view: '{{scope.filename}}' + }); + var renderer = stache(''); + var frag = renderer(); + assert.equal(frag.firstChild.innerHTML, 'MyFilenameComponentView', 'filename was provided to stache()'); + }); +}); +/*can-component@5.0.0#test/component-instantiation-test*/ +define('can-component@5.0.0#test/component-instantiation-test', [ + 'require', + 'exports', + 'module', + 'can-component', + 'can-define/map/map', + 'steal-qunit', + 'can-simple-map', + 'can-stache', + 'can-value', + 'can-globals', + './helpers' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Component = require('can-component'); + var DefineMap = require('can-define/map/map'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var stache = require('can-stache'); + var value = require('can-value'); + var globals = require('can-globals'); + var helpers = require('./helpers'); + QUnit.module('can-component instantiation'); + QUnit.test('Components can be instantiated with new', function (assert) { + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation', + view: 'Hello {{message}}', + ViewModel: { message: 'string' } + }); + var componentInstance = new ComponentConstructor(); + var element = componentInstance.element; + var viewModel = componentInstance.viewModel; + assert.ok(element, 'instance has element property'); + assert.equal(element.textContent, 'Hello ', 'element has correct text content'); + assert.ok(viewModel, 'instance has viewModel property'); + viewModel.message = 'world'; + assert.equal(element.textContent, 'Hello world', 'element has correct text content after updating viewModel'); + }); + QUnit.test('Components can be instantiated with - no scope', function (assert) { + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation-content-no-scope', + view: 'Hello {{message}}', + ViewModel: { message: { default: 'world' } } + }); + var componentInstance = new ComponentConstructor({ content: stache('mundo') }); + var element = componentInstance.element; + assert.equal(element.innerHTML, 'Hello mundo', 'content is rendered'); + }); + QUnit.test('Components can be instantiated with - with plain content and scope', function (assert) { + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation-plain-content-and-scope', + view: 'Hello {{message}}', + ViewModel: { message: { default: 'world' } } + }); + var componentInstance = new ComponentConstructor({ + content: '{{message}}', + scope: { message: 'mundo' } + }); + var element = componentInstance.element; + assert.equal(element.innerHTML, 'Hello mundo', 'content is rendered'); + }); + QUnit.test('Components can be instantiated with - with scope - leakScope false', function (assert) { + var ComponentConstructor = Component.extend({ + leakScope: false, + tag: 'new-instantiation-content-leakscope-false', + view: 'Hello {{message}}', + ViewModel: { message: { default: 'world' } } + }); + var scopeVM = new DefineMap({}); + var componentInstance = new ComponentConstructor({ + content: '{{message}}', + scope: scopeVM + }); + var element = componentInstance.element; + assert.equal(element.innerHTML, 'Hello ', 'content is rendered with the provided scope'); + scopeVM.set('message', 'mundo'); + assert.equal(element.innerHTML, 'Hello mundo', 'content updates with the provided scope'); + }); + QUnit.test('Components can be instantiated with - with scope - leakScope true', function (assert) { + var ComponentConstructor = Component.extend({ + leakScope: true, + tag: 'new-instantiation-content-leakscope-true', + view: 'Hello {{message}}', + ViewModel: { message: { default: 'world' } } + }); + var componentInstance = new ComponentConstructor({ + content: '{{scope.find(\'message\')}}', + scope: { message: 'mundo' } + }); + var element = componentInstance.element; + assert.equal(element.innerHTML, 'Hello world', 'content is rendered with the component\u2019s scope'); + }); + QUnit.test('Components can be instantiated with templates', function (assert) { + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation-templates', + view: '' + }); + var scopeVM = new DefineMap({ message: 'world' }); + var componentInstance = new ComponentConstructor({ + scope: scopeVM, + templates: { messageInput: '' } + }); + var element = componentInstance.element; + var inputElement = element.querySelector('input'); + assert.ok(inputElement, 'template rendered'); + assert.equal(inputElement.value, 'world', 'input has correct value'); + scopeVM.message = 'mundo'; + assert.equal(inputElement.value, 'mundo', 'input has correct value after updating scopeVM'); + }); + QUnit.test('Components can be instantiated with viewModel', function (assert) { + var bindMap = new SimpleMap({ inner: new SimpleMap({ key: 'original bind value' }) }); + var fromMap = new SimpleMap({ inner: new SimpleMap({ key: 'original from value' }) }); + var toMap = new SimpleMap({ inner: new SimpleMap({ key: 'original to value' }) }); + var ComponentConstructor = Component.extend({ + tag: 'new-instantiation-viewmodel', + view: 'Hello', + ViewModel: { + fromChildProp: 'string', + plainProp: 'string', + toParentProp: 'string', + twoWayProp: 'string', + nullProp: { + default: function () { + return 'bar'; + } + } + } + }); + var componentInstance = new ComponentConstructor({ + viewModel: { + plainProp: 'plain value', + fromChildProp: value.from(fromMap, 'inner.key'), + toParentProp: value.to(toMap, 'inner.key'), + twoWayProp: value.bind(bindMap, 'inner.key'), + nullProp: null + } + }); + var viewModel = componentInstance.viewModel; + assert.equal(viewModel.fromChildProp, 'original from value', 'fromChildProp init'); + assert.equal(viewModel.plainProp, 'plain value', 'plainProp init'); + assert.equal(viewModel.toParentProp, undefined, 'toParentProp init'); + assert.equal(viewModel.twoWayProp, 'original bind value', 'twoWayProp init'); + assert.equal(viewModel.nullProp, null, 'nullProp init'); + fromMap.get('inner').set('key', 'new from value'); + assert.equal(viewModel.fromChildProp, 'new from value', 'viewModel updated after fromMap set'); + viewModel.toParentProp = 'new to value'; + assert.equal(toMap.get('inner').get('key'), 'new to value', 'toMap updated after viewModel set'); + bindMap.get('inner').set('key', 'new bind value'); + assert.equal(viewModel.twoWayProp, 'new bind value', 'viewModel updated after bindMap set'); + viewModel.twoWayProp = 'newest bind value'; + assert.equal(bindMap.get('inner').get('key'), 'newest bind value', 'bindMap updated after viewModel set'); + }); + QUnit.test('Components can be instantiated with all options', function (assert) { + var HelloWorld = Component.extend({ + tag: 'hello-world', + view: 'Hello world
        {{#each(items)}} {{/each}}
      ', + ViewModel: { items: {} } + }); + var componentInstance = new HelloWorld({ + content: '{{message}}', + scope: { message: 'friend' }, + templates: { itemTemplate: '
    1. {{this}}
    2. ' }, + viewModel: { items: ['eat'] } + }); + var element = componentInstance.element; + var viewModel = componentInstance.viewModel; + assert.equal(helpers.cloneAndClean(element).innerHTML, 'Hello friend
      • eat
      ', 'element renders correctly'); + assert.equal(viewModel.items.length, 1, 'viewModel has items'); + viewModel.items.push('sleep'); + assert.equal(helpers.cloneAndClean(element).innerHTML, 'Hello friend
      • eat
      • sleep
      ', 'element updates correctly'); + }); + QUnit.test('Component binding instantiation works as documented', function (assert) { + var appVM = new SimpleMap({ + family: new SimpleMap({ + first: 'Milo', + last: 'Flanders' + }) + }); + var NameComponent = Component.extend({ + tag: 'name-component', + view: '{{fullName}}', + ViewModel: { + givenName: 'string', + familyName: 'string', + get fullName() { + return this.givenName + ' ' + this.familyName; + } + } + }); + var componentInstance = new NameComponent({ + viewModel: { + givenName: value.from(appVM, 'family.first'), + familyName: value.bind(appVM, 'family.last'), + fullName: value.to(appVM, 'family.full') + } + }); + var viewModel = componentInstance.viewModel; + assert.equal(viewModel.familyName, 'Flanders', 'component \u201Cbind\u201D prop is correct'); + assert.equal(viewModel.givenName, 'Milo', 'component \u201Cfrom\u201D prop is correct'); + assert.equal(viewModel.fullName, 'Milo Flanders', 'component \u201Cto\u201D prop is correct'); + var family = appVM.get('family'); + assert.equal(family.get('last'), 'Flanders', 'map \u201Cbind\u201D prop is correct'); + assert.equal(family.get('first'), 'Milo', 'map \u201Cfrom\u201D prop is correct'); + assert.equal(family.get('full'), 'Milo Flanders', 'map \u201Cto\u201D prop is correct'); + }); + QUnit.test('component instantiation is not observable', function (assert) { + var innerViewModel; + var InnerComponent = Component.extend({ + tag: 'inner-component-to-make', + view: '{{this.innerValue}}', + ViewModel: { + init: function () { + innerViewModel = this; + }, + innerValue: 'any' + } + }); + var count = 0; + Component.extend({ + tag: 'outer-component-creator', + view: '{{{ this.innerComponent }}}', + ViewModel: { + get innerComponent() { + count++; + return new InnerComponent({ viewModel: { innerValue: value.bind(this, 'outerValue') } }); + }, + outerValue: 'any' + } + }); + var view = stache(''); + view(); + innerViewModel.innerValue = 'SOME-VALUE'; + assert.equal(count, 1, 'only updated once'); + }); + QUnit.test('Can render in a document with no body', function (assert) { + var doc = document.implementation.createHTMLDocument('Testing'); + globals.setKeyValue('document', doc); + doc.documentElement.removeChild(doc.body); + var ComponentConstructor = Component.extend({ + tag: 'with-no-body', + view: 'test', + ViewModel: { + connectedCallback: function () { + } + } + }); + try { + new ComponentConstructor(); + assert.ok(true, 'rendered without throwing'); + } catch (e) { + assert.ok(false, 'threw' + e.toString()); + } finally { + globals.setKeyValue('document', document); + } + }); + QUnit.test('{initializeBindings: false} prevents setting up bindings until insert', function (assert) { + var ComponentConstructor = Component.extend({ + tag: 'some-random-tag', + view: '{{color}}', + ViewModel: { color: { default: 'red' } } + }); + var inst = new ComponentConstructor({ initializeBindings: false }); + assert.equal(inst.viewModel.color, undefined, 'ViewModel not yet setup'); + var view = stache('{{component}}'); + var frag = view({ component: inst }); + assert.equal(inst.viewModel.color, 'red', 'is red'); + assert.equal(frag.firstChild.firstChild.data, 'red', 'Now it is setup'); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@5.0.0#test/component-in-stache-test*/ +define('can-component@5.0.0#test/component-in-stache-test', [ + 'require', + 'exports', + 'module', + 'can-component', + 'can-simple-map', + 'can-simple-observable', + 'can-stache', + 'can-reflect', + 'steal-qunit', + 'can-dom-mutate', + 'can-dom-mutate/node/node', + 'can-globals' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Component = require('can-component'); + var SimpleMap = require('can-simple-map'); + var SimpleObservable = require('can-simple-observable'); + var stache = require('can-stache'); + var canReflect = require('can-reflect'); + var QUnit = require('steal-qunit'); + var domMutate = require('can-dom-mutate'); + var domMutateNode = require('can-dom-mutate/node/node'); + var globals = require('can-globals'); + QUnit.module('can-component can be rendered by can-stache'); + QUnit.test('basics work', function (assert) { + var ComponentConstructor = Component.extend({ + tag: 'component-in-stache', + view: 'Hello {{message}}', + ViewModel: { message: 'string' } + }); + var componentInstance = new ComponentConstructor(); + var fragment = stache('
      {{{componentInstance}}}
      ')({ componentInstance: componentInstance }); + var viewModel = componentInstance.viewModel; + assert.equal(fragment.textContent, 'Hello ', 'fragment has correct text content'); + viewModel.message = 'world'; + assert.equal(fragment.textContent, 'Hello world', 'fragment has correct text content after updating viewModel'); + }); + QUnit.test('wrapped in a conditional', function (assert) { + var done = assert.async(); + var ComponentConstructor = Component.extend({ + tag: 'component-in-stache', + view: 'Hello {{message}}', + ViewModel: { message: 'string' } + }); + var componentInstance = new ComponentConstructor(); + var templateVM = new SimpleMap({ + componentInstance: componentInstance, + showComponent: false + }); + var componentVM = componentInstance.viewModel; + var fragment = stache('
      {{#if(showComponent)}}{{{componentInstance}}}{{/if}}
      ')(templateVM); + assert.equal(fragment.textContent, '', 'fragment starts off without content'); + templateVM.set('showComponent', true); + assert.equal(fragment.textContent, 'Hello ', 'fragment updates to include the component'); + componentVM.message = 'world'; + assert.equal(fragment.textContent, 'Hello world', 'fragment has correct text content after updating componentVM'); + var waitingCount = 0; + function finishOn2() { + waitingCount++; + if (waitingCount === 2) { + done(); + } + } + canReflect.onInstanceBoundChange(ComponentConstructor.ViewModel, function (instance, isBound) { + assert.equal(isBound, false, 'view model is no longer bound'); + finishOn2(); + }); + templateVM.set('showComponent', false); + assert.equal(fragment.textContent, '', 'fragment ends without content'); + finishOn2(); + }); + QUnit.test('Component can be removed from the page', function (assert) { + assert.expect(3); + var ToBeRemoved = Component.extend({ + tag: 'to-be-removed', + view: '{{prop}}', + ViewModel: { prop: 'string' }, + events: { + '{element} beforeremove': function () { + assert.ok(true, 'torn down'); + } + } + }); + var prop = new SimpleObservable(3); + var toBeRemoved = new ToBeRemoved({ viewModel: { prop: prop } }); + var show = new SimpleObservable(true); + var template = stache('
      {{# if(show) }} {{{toBeRemoved}}} {{/ if}}
      '); + var frag = template({ + show: show, + toBeRemoved: toBeRemoved + }); + show.set(false); + assert.ok(true, 'got here without an error'); + show.set(true); + prop.set(4); + assert.equal(frag.firstChild.getElementsByTagName('to-be-removed')[0].innerHTML, '4', 'innerHTML is 4'); + }); + QUnit.test('Cleans up itself on the documentElement removal', function (assert) { + Component.extend({ + tag: 'ssr-cleanup', + view: 'hello world', + ViewModel: {} + }); + var doc = document.implementation.createHTMLDocument('Test'); + var realDoc = globals.getKeyValue('document'); + globals.setKeyValue('document', doc); + var frag = stache('')({}); + doc.body.appendChild(frag); + domMutate.onNodeDisconnected(doc.body.firstChild, function () { + globals.setKeyValue('document', realDoc); + assert.ok(true, 'Called back without throwing'); + done(); + }); + var done = assert.async(); + domMutateNode.removeChild.call(doc, doc.documentElement); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-component@5.0.0#test/component-can-bind-test*/ +define('can-component@5.0.0#test/component-can-bind-test', [ + 'require', + 'exports', + 'module', + 'can-bind', + 'can-component', + './helpers', + 'steal-qunit', + 'can-simple-map', + 'can-value', + 'can-dom-mutate/node/node', + 'can-queues', + 'can-test-helpers' +], function (require, exports, module) { + var Bind = require('can-bind'); + var Component = require('can-component'); + var helpers = require('./helpers'); + var QUnit = require('steal-qunit'); + var SimpleMap = require('can-simple-map'); + var value = require('can-value'); + var domMutateNode = require('can-dom-mutate/node/node'); + var queues = require('can-queues'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-component integration with can-bind'); + QUnit.test('Using can-bind in connectedCallback works as documented', function (assert) { + var done = assert.async(); + var connectedCallbackCallCount = 0; + var BindComponent = Component.extend({ + tag: 'bind-component', + view: '{{object.prop}}', + ViewModel: { + eventualProp: { default: undefined }, + object: { + default: function () { + return new SimpleMap({ prop: 15 }); + } + }, + connectedCallback: function () { + connectedCallbackCallCount += 1; + var binding = new Bind({ + parent: value.from(this, 'eventualProp'), + child: value.to(this, 'object.prop') + }); + binding.start(); + return binding.stop.bind(binding); + } + } + }); + var componentInstance = new BindComponent({}); + var element = componentInstance.element; + var viewModel = componentInstance.viewModel; + assert.equal(viewModel.object.get('prop'), 15, 'view model prop starts off with initial value'); + var fixture = document.getElementById('qunit-fixture'); + domMutateNode.appendChild.call(fixture, element); + helpers.afterMutation(function () { + assert.equal(viewModel.object.get('prop'), undefined, 'binding updates view model prop'); + viewModel.eventualProp = 22; + assert.equal(viewModel.object.get('prop'), 22, 'new value for one prop updates the other'); + assert.equal(connectedCallbackCallCount, 1, 'connectedCallback only called once'); + fixture.removeChild(element); + done(); + }); + }); + testHelpers.dev.devOnlyTest('logStack should include `new Component()` mutations', function (assert) { + var ComponentConstructor = Component.extend({ + tag: 'a-tag', + view: '{{foo}}', + ViewModel: { + setup: function () { + var expected = queues.stack().length > 0; + assert.ok(expected, 'At least one task on the stack'); + }, + foo: 'string' + } + }); + new ComponentConstructor({ viewModel: { foo: 'bar' } }); + }); +}); +/*can-component@5.0.0#test/test*/ +define('can-component@5.0.0#test/test', [ + 'require', + 'exports', + 'module', + './component-tag-test', + './component-viewmodel-test', + './component-viewmodel-observe-test', + './component-view-test', + './component-helpers-test', + './component-events-test', + './example-test', + './component-slot-test', + './component-define-test', + './component-instantiation-test', + './component-in-stache-test', + './component-can-bind-test' +], function (require, exports, module) { + require('./component-tag-test'); + require('./component-viewmodel-test'); + require('./component-viewmodel-observe-test'); + require('./component-view-test'); + require('./component-helpers-test'); + require('./component-events-test'); + require('./example-test'); + require('./component-slot-test'); + require('./component-define-test'); + require('./component-instantiation-test'); + require('./component-in-stache-test'); + require('./component-can-bind-test'); +}); +/*can-define@2.8.0#test/test-define-only*/ +define('can-define@2.8.0#test/test-define-only', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-define', + 'can-queues', + 'can-symbol', + 'can-simple-observable', + 'can-test-helpers', + 'can-reflect', + 'can-observation-recorder' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var define = require('can-define'); + var queues = require('can-queues'); + var canSymbol = require('can-symbol'); + var SimpleObservable = require('can-simple-observable'); + var testHelpers = require('can-test-helpers'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + QUnit.module('can-define'); + QUnit.test('basics on a prototype', function (assert) { + assert.expect(5); + var Person = function (first, last) { + this.first = first; + this.last = last; + }; + define(Person.prototype, { + first: '*', + last: '*', + fullName: { + get: function () { + return this.first + ' ' + this.last; + } + } + }); + var p = new Person('Mohamed', 'Cherif'); + p.bind('fullName', function (ev, newVal, oldVal) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.bind('first', function (el, newVal, oldVal) { + assert.equal(newVal, 'Justin', 'first new value'); + assert.equal(oldVal, 'Mohamed', 'first old value'); + }); + queues.batch.start(); + p.first = 'Justin'; + p.last = 'Meyer'; + queues.batch.stop(); + }); + QUnit.test('basics set', function (assert) { + assert.expect(2); + var Defined = function (prop) { + this.prop = prop; + }; + define(Defined.prototype, { + prop: { + set: function (newVal) { + return 'foo' + newVal; + } + } + }); + var def = new Defined(); + def.prop = 'bar'; + assert.equal(def.prop, 'foobar', 'setter works'); + var DefinedCB = function (prop) { + this.prop = prop; + }; + define(DefinedCB.prototype, { + prop: { + set: function (newVal, setter) { + setter('foo' + newVal); + } + } + }); + var defCallback = new DefinedCB(); + defCallback.prop = 'bar'; + assert.equal(defCallback.prop, 'foobar', 'setter callback works'); + }); + QUnit.test('basic Type', function (assert) { + var Foo = function (name) { + this.name = name; + }; + Foo.prototype.getName = function () { + return this.name; + }; + var Typer = function (foo) { + this.foo = foo; + }; + define(Typer.prototype, { foo: { Type: Foo } }); + var t = new Typer('Justin'); + assert.equal(t.foo.getName(), 'Justin', 'correctly created an instance'); + var brian = new Foo('brian'); + t.foo = brian; + assert.equal(t.foo, brian, 'same instances'); + }); + QUnit.test('type converters', function (assert) { + var Typer = function (date, string, number, bool, htmlbool, leaveAlone) { + this.date = date; + this.string = string; + this.number = number; + this.bool = bool; + this.htmlbool = htmlbool; + this.leaveAlone = leaveAlone; + }; + define(Typer.prototype, { + date: { type: 'date' }, + string: { type: 'string' }, + number: { type: 'number' }, + bool: { type: 'boolean' }, + htmlbool: { type: 'htmlbool' }, + leaveAlone: { type: '*' } + }); + var obj = {}; + var t = new Typer(1395896701516, 5, '5', 'false', '', obj); + assert.ok(t.date instanceof Date, 'converted to date'); + assert.equal(t.string, '5', 'converted to string'); + assert.equal(t.number, 5, 'converted to number'); + assert.equal(t.bool, false, 'converted to boolean'); + assert.equal(t.htmlbool, true, 'converted to htmlbool'); + assert.equal(t.leaveAlone, obj, 'left as object'); + t.number = '15'; + assert.ok(t.number === 15, 'converted to number'); + }); + QUnit.test('basics value', function (assert) { + var Typer = function (prop) { + if (prop !== undefined) { + this.prop = prop; + } + }; + define(Typer.prototype, { prop: { default: 'foo' } }); + var t = new Typer(); + assert.equal(t.prop, 'foo', 'value is used as default value'); + var Typer2 = function (prop) { + if (prop !== undefined) { + this.prop = prop; + } + }; + define(Typer2.prototype, { + prop: { + default: function () { + return []; + }, + type: '*' + } + }); + var t1 = new Typer2(), t2 = new Typer2(); + assert.ok(t1.prop !== t2.prop, 'different array instances'); + assert.ok(Array.isArray(t1.prop), 'its an array'); + }); + QUnit.test('basics Value', function (assert) { + var Typer = function (prop) { + }; + define(Typer.prototype, { + prop: { + Default: Array, + type: '*' + } + }); + var t1 = new Typer(), t2 = new Typer(); + assert.ok(t1.prop !== t2.prop, 'different array instances'); + assert.ok(Array.isArray(t1.prop), 'its an array'); + }); + QUnit.test('setter with no arguments and returns undefined does the default behavior, the setter is for side effects only', function (assert) { + var Typer = function (prop) { + }; + define(Typer.prototype, { + prop: { + set: function () { + this.foo = 'bar'; + } + }, + foo: '*' + }); + var t = new Typer(); + t.prop = false; + assert.deepEqual({ + foo: t.foo, + prop: t.prop + }, { + foo: 'bar', + prop: false + }, 'got the right props'); + }); + QUnit.test('type happens before the set', function (assert) { + assert.expect(2); + var Typer = function () { + }; + define(Typer.prototype, { + prop: { + type: 'number', + set: function (newValue) { + assert.equal(typeof newValue, 'number', 'got a number'); + return newValue + 1; + } + } + }); + var map = new Typer(); + map.prop = '5'; + assert.equal(map.prop, 6, 'number'); + }); + QUnit.test('getter and setter work', function (assert) { + assert.expect(5); + var Paginate = define.Constructor({ + limit: '*', + offset: '*', + page: { + set: function (newVal) { + this.offset = (parseInt(newVal) - 1) * this.limit; + }, + get: function () { + return Math.floor(this.offset / this.limit) + 1; + } + } + }); + var p = new Paginate({ + limit: 10, + offset: 20 + }); + assert.equal(p.page, 3, 'page get right'); + p.bind('page', function (ev, newValue, oldValue) { + assert.equal(newValue, 2, 'got new value event'); + assert.equal(oldValue, 3, 'got old value event'); + }); + p.page = 2; + assert.equal(p.page, 2, 'page set right'); + assert.equal(p.offset, 10, 'page offset set'); + }); + QUnit.test('getter with initial value', function (assert) { + var comp = new SimpleObservable(1); + var Grabber = define.Constructor({ + vals: { + type: '*', + Default: Array, + get: function (current, setVal) { + if (setVal) { + current.push(comp.get()); + } + return current; + } + } + }); + var g = new Grabber(); + assert.equal(g.vals.length, 0, 'zero items in array'); + }); + QUnit.test('default behaviors with "*" work for attributes', function (assert) { + assert.expect(6); + var DefaultMap = define.Constructor({ + '*': { + type: 'number', + set: function (newVal) { + assert.ok(true, 'set called'); + return newVal; + } + }, + someNumber: { default: '5' }, + number: {} + }); + var map = new DefaultMap(); + assert.equal(map.someNumber, '5', 'default values are not type converted anymore'); + map.someNumber = '5'; + assert.equal(map.someNumber, 5, 'on a set, they should be type converted'); + map.number = '10'; + assert.equal(map.number, 10, 'value of number should be converted to a number'); + }); + QUnit.test('nested define', function (assert) { + var nailedIt = 'Nailed it'; + var Example = define.Constructor({ name: { default: nailedIt } }); + var NestedMap = define.Constructor({ + isEnabled: { default: true }, + test: { Default: Example }, + examples: { + type: { + one: { Default: Example }, + two: { + type: { deep: { Default: Example } }, + Default: Object + } + }, + Default: Object + } + }); + var nested = new NestedMap(); + assert.equal(nested.test.name, nailedIt); + assert.equal(nested.examples.one.name, nailedIt); + assert.equal(nested.examples.two.deep.name, nailedIt); + assert.ok(nested.test instanceof Example); + assert.ok(nested.examples.one instanceof Example); + assert.ok(nested.examples.two.deep instanceof Example); + }); + QUnit.test('Can make an attr alias a compute (#1470)', function (assert) { + assert.expect(9); + var computeValue = new SimpleObservable(1); + var GetMap = define.Constructor({ + value: { + set: function (newValue, setVal, oldValue) { + if (newValue instanceof SimpleObservable) { + return newValue; + } + if (oldValue && oldValue instanceof SimpleObservable) { + oldValue.set(newValue); + return oldValue; + } + return newValue; + }, + get: function (value) { + return value instanceof SimpleObservable ? value.get() : value; + } + } + }); + var getMap = new GetMap(); + getMap.value = computeValue; + assert.equal(getMap.value, 1, 'initial value read from compute'); + var bindCallbacks = 0; + getMap.bind('value', function (ev, newVal, oldVal) { + switch (bindCallbacks) { + case 0: + assert.equal(newVal, 2, '0 - bind called with new val'); + assert.equal(oldVal, 1, '0 - bind called with old val'); + break; + case 1: + assert.equal(newVal, 3, '1 - bind called with new val'); + assert.equal(oldVal, 2, '1 - bind called with old val'); + break; + case 2: + assert.equal(newVal, 4, '2 - bind called with new val'); + assert.equal(oldVal, 3, '2 - bind called with old val'); + break; + } + bindCallbacks++; + }); + computeValue.set(2); + getMap.value = 3; + assert.equal(getMap.value, 3, 'read value is 3'); + assert.equal(computeValue.get(), 3, 'the compute value is 3'); + var newComputeValue = new SimpleObservable(4); + getMap.value = newComputeValue; + }); + QUnit.test('One event on getters (#1585)', function (assert) { + var Person = define.Constructor({ + name: '*', + id: 'number' + }); + var AppState = define.Constructor({ + person: { + get: function appState_person_get(lastSetValue, resolve) { + if (lastSetValue) { + return lastSetValue; + } else if (this.personId) { + resolve(new Person({ + name: 'Jose', + id: 5 + })); + } else { + return null; + } + }, + Type: Person + }, + personId: '*' + }); + var appState = new AppState(); + var personEvents = 0; + appState.bind('person', function addPersonEvents(ev, person) { + personEvents++; + }); + assert.equal(appState.person, null, 'no personId and no lastSetValue'); + appState.personId = 5; + assert.equal(appState.person.name, 'Jose', 'a personId, providing Jose'); + assert.ok(appState.person instanceof Person, 'got a person instance'); + appState.person = { name: 'Julia' }; + assert.ok(appState.person instanceof Person, 'got a person instance'); + assert.equal(personEvents, 2); + }); + QUnit.test('Can read a defined property with a set/get method (#1648)', function (assert) { + var Map = define.Constructor({ + foo: { + default: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + }); + var map = new Map(); + assert.equal(map.foo, '', 'Calling .foo returned the correct value'); + map.foo = 'baz'; + assert.equal(map.foo, 'baz', 'Calling .foo returned the correct value'); + }); + QUnit.test('Can bind to a defined property with a set/get method (#1648)', function (assert) { + assert.expect(3); + var Map = define.Constructor({ + foo: { + default: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + }); + var map = new Map(); + map.bind('foo', function () { + assert.ok(true, 'Bound function is called'); + }); + assert.equal(map.foo, '', 'Calling .attr(\'foo\') returned the correct value'); + map.foo = 'baz'; + assert.equal(map.foo, 'baz', 'Calling .attr(\'foo\') returned the correct value'); + }); + QUnit.test('type converters handle null and undefined in expected ways (1693)', function (assert) { + var Typer = define.Constructor({ + date: { type: 'date' }, + string: { type: 'string' }, + number: { type: 'number' }, + 'boolean': { type: 'boolean' }, + htmlbool: { type: 'htmlbool' }, + leaveAlone: { type: '*' } + }); + var t = new Typer({ + date: undefined, + string: undefined, + number: undefined, + 'boolean': undefined, + htmlbool: undefined, + leaveAlone: undefined + }); + assert.equal(t.date, undefined, 'converted to date'); + assert.equal(t.string, undefined, 'converted to string'); + assert.equal(t.number, undefined, 'converted to number'); + assert.equal(t.boolean, undefined, 'converted to boolean'); + assert.equal(t.htmlbool, false, 'converted to htmlbool'); + assert.equal(t.leaveAlone, undefined, 'left as object'); + t = new Typer({ + date: null, + string: null, + number: null, + 'boolean': null, + htmlbool: null, + leaveAlone: null + }); + assert.equal(t.date, null, 'converted to date'); + assert.equal(t.string, null, 'converted to string'); + assert.equal(t.number, null, 'converted to number'); + assert.equal(t.boolean, null, 'converted to boolean'); + assert.equal(t.htmlbool, false, 'converted to htmlbool'); + assert.equal(t.leaveAlone, null, 'left as object'); + }); + QUnit.test('Initial value does not call getter', function (assert) { + assert.expect(0); + var Map = define.Constructor({ + count: { + get: function (lastVal) { + assert.ok(false, 'Should not be called'); + return lastVal; + } + } + }); + new Map({ count: 100 }); + }); + QUnit.test('getters produce change events', function (assert) { + var Map = define.Constructor({ + count: { + get: function (lastVal) { + return lastVal; + } + } + }); + var map = new Map(); + map.bind('count', function () { + assert.ok(true, 'change called'); + }); + map.count = 22; + }); + QUnit.test('Asynchronous virtual properties cause extra recomputes (#1915)', function (assert) { + var done = assert.async(); + var ran = false; + var VM = define.Constructor({ + foo: { + get: function (lastVal, setVal) { + setTimeout(function () { + if (setVal) { + setVal(5); + } + }, 10); + } + }, + bar: { + get: function () { + var foo = this.foo; + if (foo) { + if (ran) { + assert.ok(false, 'Getter ran twice'); + } + ran = true; + return foo * 2; + } + } + } + }); + var vm = new VM(); + vm.bind('bar', function () { + }); + setTimeout(function () { + assert.equal(vm.bar, 10); + done(); + }, 200); + }); + QUnit.test('Default values cannot be set (#8)', function (assert) { + var Person = function () { + }; + define(Person.prototype, { + first: { + type: 'string', + default: 'Chris' + }, + last: { + type: 'string', + default: 'Gomez' + }, + fullName: { + get: function () { + return this.first + ' ' + this.last; + } + } + }); + var p = new Person(); + assert.equal(p.fullName, 'Chris Gomez', 'Fullname is correct'); + p.first = 'Sara'; + assert.equal(p.fullName, 'Sara Gomez', 'Fullname is correct after update'); + }); + QUnit.test('default type is setable', function (assert) { + var Person = function () { + }; + define(Person.prototype, { + '*': 'string', + first: { default: 1 }, + last: { default: 2 } + }); + var p = new Person(); + assert.ok(p.first === '1', typeof p.first); + assert.ok(p.last === '2', typeof p.last); + }); + QUnit.test('expandos are added in define.setup (#25)', function (assert) { + var MyMap = define.Constructor({}); + var map = new MyMap({ prop: 4 }); + map.on('prop', function () { + assert.ok(true, 'prop event called'); + }); + map.prop = 5; + }); + QUnit.test('Set property with type compute', function (assert) { + var MyMap = define.Constructor({ computeProp: { type: 'compute' } }); + var m = new MyMap(); + m.computeProp = new SimpleObservable(0); + assert.equal(m.computeProp, 0, 'Property has correct value'); + m.computeProp = new SimpleObservable(1); + assert.equal(m.computeProp, 1, 'Property has correct value'); + }); + QUnit.test('Compute type property can have a default value', function (assert) { + var MyMap = define.Constructor({ + computeProp: { + type: 'compute', + default: function () { + return 0; + } + } + }); + var m = new MyMap(); + assert.equal(m.computeProp, 0, 'Property has correct value'); + m.computeProp = 1; + assert.equal(m.computeProp, 1, 'Property has correct value'); + }); + QUnit.test('Compute type property with compute default value triggers change events when updated', function (assert) { + var expected = 0; + var c = new SimpleObservable(0); + var MyMap = define.Constructor({ + computeProp: { + type: 'compute', + default: function () { + return c; + } + } + }); + var m = new MyMap(); + c.on(function (newVal) { + assert.equal(newVal, expected, 'Compute fired change event'); + }); + m.on('computeProp', function (ev, newVal) { + assert.equal(newVal, expected, 'Map fired change event'); + }); + expected = 1; + m.computeProp = expected; + expected = 2; + c.set(expected); + }); + QUnit.test('Compute type property can have a default value that is a compute', function (assert) { + var c = new SimpleObservable(0); + var MyMap = define.Constructor({ + computeProp: { + type: 'compute', + default: function () { + return c; + } + } + }); + var m = new MyMap(); + assert.equal(m.computeProp, 0, 'Property has correct value'); + c.set(1); + assert.equal(m.computeProp, 1, 'Property has correct value'); + }); + QUnit.test('Extensions can modify definitions', function (assert) { + var oldExtensions = define.extensions; + define.behaviors.push('extended'); + define.extensions = function (objPrototype, prop, definition) { + if (definition.extended) { + return { default: 'extended' }; + } + }; + var MyMap = define.Constructor({ + foo: { + default: 'defined', + extended: true + }, + bar: { default: 'defined' } + }); + var map = new MyMap(); + assert.equal(map.foo, 'extended', 'Value was set via extension'); + assert.equal(map.bar, 'defined', 'Value was set via definition'); + define.extensions = oldExtensions; + }); + QUnit.test('Properties are enumerable', function (assert) { + assert.expect(1); + function VM(foo) { + this.foo = foo; + } + define(VM.prototype, { foo: 'string' }); + var vm = new VM('bar'); + vm.baz = 'qux'; + var copy = {}; + for (var key in vm) { + copy[key] = vm[key]; + } + assert.deepEqual(copy, { + foo: 'bar', + baz: 'qux' + }); + }); + QUnit.test('Doesn\'t override canSymbol.iterator if already on the prototype', function (assert) { + function MyMap() { + } + MyMap.prototype[canSymbol.iterator || canSymbol.for('iterator')] = function () { + var i = 0; + return { + next: function () { + if (i === 0) { + i++; + return { + value: [ + 'it', + 'worked' + ], + done: false + }; + } + return { + value: undefined, + done: true + }; + } + }; + }; + define(MyMap.prototype, { foo: 'string' }); + var map = new MyMap(); + map.foo = 'bar'; + canReflect.eachIndex(map, function (value) { + assert.deepEqual(value, [ + 'it', + 'worked' + ]); + }); + }); + QUnit.test('nullish values are not converted for type or Type', function (assert) { + var Foo = function () { + }; + var MyMap = define.Constructor({ + map: { Type: Foo }, + notype: {} + }); + var vm = new MyMap({ + map: {}, + notype: {} + }); + assert.ok(vm.map instanceof Foo, 'map is another type'); + assert.ok(vm.notype instanceof Object, 'notype is an Object'); + vm.map = null; + vm.notype = null; + assert.equal(vm.map, null, 'map is null'); + assert.equal(vm.map, null, 'notype is null'); + }); + QUnit.test('shorthand getter (#56)', function (assert) { + var Person = function (first, last) { + this.first = first; + this.last = last; + }; + define(Person.prototype, { + first: '*', + last: '*', + get fullName() { + return this.first + ' ' + this.last; + } + }); + var p = new Person('Mohamed', 'Cherif'); + p.on('fullName', function (ev, newVal, oldVal) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + queues.batch.start(); + p.first = 'Justin'; + p.last = 'Meyer'; + queues.batch.stop(); + }); + QUnit.test('shorthand getter setter (#56)', function (assert) { + var Person = function (first, last) { + this.first = first; + this.last = last; + }; + define(Person.prototype, { + first: '*', + last: '*', + get fullName() { + return this.first + ' ' + this.last; + }, + set fullName(newVal) { + var parts = newVal.split(' '); + this.first = parts[0]; + this.last = parts[1]; + } + }); + var p = new Person('Mohamed', 'Cherif'); + p.on('fullName', function (ev, newVal, oldVal) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.fullName = 'Justin Meyer'; + }); + QUnit.test('set and value work together (#87)', function (assert) { + var Type = define.Constructor({ + prop: { + default: 2, + set: function (num) { + return num * num; + } + } + }); + var instance = new Type(); + assert.equal(instance.prop, 4, 'used setter'); + }); + QUnit.test('async setter is provided', function (assert) { + assert.expect(5); + var RESOLVE; + var Type = define.Constructor({ + prop: { + default: 2, + set: function (num, resolve) { + resolve(num * num); + } + }, + prop2: { + default: 3, + set: function (num, resolve) { + RESOLVE = resolve; + } + } + }); + var instance = new Type(); + assert.equal(instance.prop, 4, 'used async setter'); + assert.equal(instance.prop2, undefined, 'used async setter'); + instance.on('prop2', function (ev, newVal, oldVal) { + assert.equal(newVal, 9, 'updated'); + assert.equal(oldVal, undefined, 'updated'); + }); + RESOLVE(9); + assert.equal(instance.prop2, 9, 'used async setter updates after'); + }); + QUnit.test('setter with default value causes an infinite loop (#142)', function (assert) { + var A = define.Constructor({ + val: { + default: 'hello', + set: function (val) { + if (this.val) { + } + return val; + } + } + }); + var a = new A(); + assert.equal(a.val, 'hello', 'creating an instance should not cause an inifinte loop'); + }); + QUnit.test('defined properties are configurable', function (assert) { + var A = define.Constructor({ + val: { + get: function () { + return 'foo'; + } + } + }); + var dataInitializers = A.prototype._define.dataInitializers, computedInitializers = A.prototype._define.computedInitializers; + var newDefinition = { + get: function () { + return 'bar'; + } + }; + define.property(A.prototype, 'val', newDefinition, dataInitializers, computedInitializers); + var a = new A(); + assert.equal(a.val, 'bar', 'It was redefined'); + }); + testHelpers.dev.devOnlyTest('warn on using a Constructor for small-t type definitions', function (assert) { + assert.expect(1); + var message = /can-define: the definition for [\w{}\.]+ uses a constructor for "type"\. Did you mean "Type"\?/; + var finishErrorCheck = testHelpers.dev.willWarn(message); + function Currency() { + return this; + } + Currency.prototype = { symbol: 'USD' }; + function VM() { + } + define(VM.prototype, { + currency: { + type: Currency, + default: function () { + return new Currency({}); + } + } + }); + assert.equal(finishErrorCheck(), 1); + }); + testHelpers.dev.devOnlyTest('warn with constructor for Value instead of Default (#340)', function (assert) { + assert.expect(1); + var message = /can-define: Change the 'Value' definition for [\w\.{}]+.currency to 'Default'./; + var finishErrorCheck = testHelpers.dev.willWarn(message); + function Currency() { + return this; + } + Currency.prototype = { symbol: 'USD' }; + function VM() { + } + define(VM.prototype, { currency: { Value: Currency } }); + assert.equal(finishErrorCheck(), 1); + }); + QUnit.test('canReflect.onKeyValue (#363)', function (assert) { + var Greeting = function (message) { + this.message = message; + }; + define(Greeting.prototype, { message: { type: 'string' } }); + var greeting = new Greeting('Hello'); + canReflect.onKeyValue(greeting, 'message', function (newVal, oldVal) { + assert.equal(newVal, 'bye'); + assert.equal(oldVal, 'Hello'); + }); + greeting.message = 'bye'; + }); + QUnit.test('value lastSet has default value (#397)', function (assert) { + var Defaulted = function () { + }; + define(Defaulted.prototype, { + hasDefault: { + default: 42, + value: function hasDefaultValue(props) { + assert.equal(props.lastSet.get(), 42, 'props.lastSet works'); + props.resolve(props.lastSet.get()); + } + } + }); + var defaulted = new Defaulted(); + assert.equal(defaulted.hasDefault, 42, 'hasDefault value.lastSet set default value'); + }); + QUnit.test('binding computed properties do not observation recordings (#406)', function (assert) { + var Type = function () { + }; + define(Type.prototype, { + prop: { + get: function () { + return 'foo'; + } + } + }); + var inst = new Type(); + ObservationRecorder.start(); + inst.on('prop', function () { + }); + var records = ObservationRecorder.stop(); + assert.equal(records.valueDependencies.size, 0, 'nothing recorded'); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get', function (assert) { + var Type = function Type() { + }; + var msg = /.* This can cause infinite loops and performance issues.*/; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + define(Type.prototype, { + prop: { + get: function () { + if (!this.prop2) { + this.prop2 = 'baz'; + } + return ''; + } + }, + prop2: 'string' + }); + var inst = new Type(); + inst.on('prop', function () { + }); + inst.prop2 = ''; + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + inst.prop2 = 'quux'; + teardownWarn(); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get (batched)', function (assert) { + var msg = /.* This can cause infinite loops and performance issues.*/; + var Type = function Type() { + }; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + define(Type.prototype, { + prop: { + get: function () { + if (!this.prop2) { + this.prop2 = 'baz'; + return ''; + } + } + }, + prop2: 'string' + }); + var inst = new Type(); + queues.batch.start(); + inst.on('prop', function () { + }); + inst.prop2 = ''; + queues.batch.stop(); + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + queues.batch.start(); + inst.prop2 = 'quux'; + queues.batch.stop(); + teardownWarn(); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get (setter)', function (assert) { + var msg = /.* This can cause infinite loops and performance issues.*/; + var Type = function Type() { + }; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + var cell; + define(Type.prototype, { + prop: { + get: function () { + if (!this.prop2) { + this.prop2 = 'baz'; + } + return cell; + }, + set: function (val) { + cell = val; + } + }, + prop2: 'string' + }); + var inst = new Type(); + inst.on('prop', function () { + }); + inst.prop2 = ''; + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + inst.prop2 = 'quux'; + teardownWarn(); + }); + testHelpers.dev.devOnlyTest('warnings are given when type or default is ignored', function (assert) { + var testCases = [ + { + name: 'zero-arg getter, no setter when property is set', + definition: { + get: function () { + return 'whatever'; + } + }, + warning: /Set value for property .* ignored/, + setProp: true, + expectedWarnings: 1 + }, + { + name: 'type with zero-arg getter, no setter', + definition: { + type: String, + get: function () { + return 'whatever'; + } + }, + warning: /type value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'Type with zero-arg getter, no setter', + definition: { + Type: {}, + get: function () { + return 'whatever'; + } + }, + warning: /Type value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'only default type with zero-arg getter, no setter - should not warn', + definition: { + get: function () { + return 'whatever'; + } + }, + warning: /type value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'type with zero-arg getter, with setter - should not warn', + definition: { + type: String, + get: function () { + return 'whatever'; + }, + set: function (val) { + return val; + } + }, + warning: /type value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'Type with zero-arg getter, with setter - should not warn', + definition: { + Type: {}, + get: function () { + return 'whatever'; + }, + set: function (val) { + return val; + } + }, + warning: /Type value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'default with zero-arg getter, no setter', + definition: { + default: 'some thing', + get: function () { + return 'whatever'; + } + }, + warning: /default value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'Default with zero-arg getter, no setter', + definition: { + Default: function () { + }, + get: function () { + return 'whatever'; + } + }, + warning: /Default value for property .* ignored/, + setProp: false, + expectedWarnings: 1 + }, + { + name: 'default with zero-arg getter, with setter - should not warn', + definition: { + default: 'some thing', + get: function () { + return 'whatever'; + }, + set: function (val) { + return val; + } + }, + warning: /default value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + }, + { + name: 'Default with zero-arg getter, with setter - should not warn', + definition: { + Default: function () { + }, + get: function () { + return 'whatever'; + }, + set: function (val) { + return val; + } + }, + warning: /Default value for property .* ignored/, + setProp: false, + expectedWarnings: 0 + } + ]; + testCases.forEach(function (testCase) { + var VM = function () { + }; + var warnCount = testHelpers.dev.willWarn(testCase.warning); + define(VM.prototype, { + derivedProp: testCase.definition, + '*': { type: define.types.observable } + }); + var vm = new VM(); + canReflect.onKeyValue(vm, 'derivedProp', function () { + }); + if (testCase.setProp) { + vm.derivedProp = 'smashed it!'; + } + assert.equal(warnCount(), testCase.expectedWarnings, 'got correct number of warnings for ' + testCase.name); + }); + }); +}); +/*can-define@2.8.0#list/list-test*/ +define('can-define@2.8.0#list/list-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-define/list/list', + 'can-define/map/map', + 'can-observation', + 'can-define', + 'can-reflect', + 'can-symbol', + 'can-log/dev/dev', + 'can-test-helpers/lib/dev', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var QUnit = require('steal-qunit'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var Observation = require('can-observation'); + var define = require('can-define'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var dev = require('can-log/dev/dev'); + var canTestHelpers = require('can-test-helpers/lib/dev'); + var assign = require('can-assign'); + QUnit.module('can-define/list/list'); + QUnit.test('List is an event emitter', function (assert) { + var Base = DefineList.extend({}); + assert.ok(Base.on, 'Base has event methods.'); + var List = Base.extend({}); + assert.ok(List.on, 'List has event methods.'); + }); + QUnit.test('creating an instance', function (assert) { + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + list.on('add', function (ev, newVals, index) { + assert.deepEqual(newVals, ['d']); + assert.equal(index, 3); + }); + list.push('d'); + }); + QUnit.test('list attr changes length', function (assert) { + var l = new DefineList([ + 0, + 1, + 2 + ]); + l.set(3, 3); + assert.equal(l.length, 4); + }); + QUnit.test('remove on pop', function (assert) { + var l = new DefineList([ + 0, + 1, + 2 + ]); + l.pop(); + assert.equal(l.length, 2); + assert.deepEqual(l.get(), [ + 0, + 1 + ]); + }); + QUnit.test('list splice', function (assert) { + var l = new DefineList([ + 0, + 1, + 2, + 3 + ]); + l.on('add', function (ev, newVals, index) { + assert.deepEqual(newVals, [ + 'a', + 'b' + ], 'got the right newVals'); + assert.equal(index, 1, 'adding items'); + }); + l.on('remove', function (ev, oldVals, index) { + assert.deepEqual(oldVals, [ + 1, + 2 + ], 'got the right oldVals'); + assert.equal(index, 1, 'no new Vals'); + }); + l.splice(1, 2, 'a', 'b'); + assert.deepEqual(l.get(), [ + 0, + 'a', + 'b', + 3 + ], 'serialized'); + }); + QUnit.test('Array accessor methods', function (assert) { + assert.expect(11); + var l = new DefineList([ + 'a', + 'b', + 'c' + ]), sliced = l.slice(2), joined = l.join(' | '), concatenated = l.concat([ + 2, + 1 + ], new DefineList([0])); + assert.ok(sliced instanceof DefineList, 'Slice is an Observable list'); + assert.equal(sliced.length, 1, 'Sliced off two elements'); + assert.equal(sliced[0], 'c', 'Single element as expected'); + assert.equal(joined, 'a | b | c', 'Joined list properly'); + assert.ok(concatenated instanceof DefineList, 'Concatenated is an Observable list'); + assert.deepEqual(concatenated.serialize(), [ + 'a', + 'b', + 'c', + 2, + 1, + 0 + ], 'DefineList concatenated properly'); + l.forEach(function (letter, index) { + assert.ok(true, 'Iteration'); + if (index === 0) { + assert.equal(letter, 'a', 'First letter right'); + } + if (index === 2) { + assert.equal(letter, 'c', 'Last letter right'); + } + }); + }); + QUnit.test('Concatenated list items Equal original', function (assert) { + var l = new DefineList([ + { firstProp: 'Some data' }, + { secondProp: 'Next data' } + ]), concatenated = l.concat([ + { hello: 'World' }, + { foo: 'Bar' } + ]); + assert.ok(l[0] === concatenated[0], 'They are Equal'); + assert.ok(l[1] === concatenated[1], 'They are Equal'); + }); + QUnit.test('Lists with maps concatenate properly', function (assert) { + var Person = DefineMap.extend(); + var People = DefineList.extend({ '#': Person }); + var Genius = Person.extend(); + var Animal = DefineMap.extend(); + var me = new Person({ name: 'John' }); + var animal = new Animal({ name: 'Tak' }); + var genius = new Genius({ name: 'Einstein' }); + var hero = { name: 'Ghandi' }; + var people = new People([]); + var specialPeople = new People([ + genius, + hero + ]); + people = people.concat([ + me, + animal, + specialPeople + ], specialPeople, [ + 1, + 2 + ], 3); + assert.ok(people.length === 8, 'List length is right'); + assert.ok(people[0] === me, 'Map in list === vars created before concat'); + assert.ok(people[1] instanceof Person, 'Animal got serialized to Person'); + }); + QUnit.test('splice removes items in IE (#562)', function (assert) { + var l = new DefineList(['a']); + l.splice(0, 1); + assert.ok(!l.get(0), 'all props are removed'); + }); + QUnit.test('reverse triggers add/remove events (#851)', function (assert) { + assert.expect(4); + var l = new DefineList([ + 1, + 2, + 3 + ]); + l.on('add', function () { + assert.ok(true, 'add called'); + }); + l.on('remove', function () { + assert.ok(true, 'remove called'); + }); + l.on('length', function () { + assert.ok(true, 'length should be called'); + }); + l.reverse(); + assert.deepEqual(l.get(), [ + 3, + 2, + 1 + ], 'reversed'); + }); + QUnit.test('filter', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'John' + }, + { + id: 2, + name: 'Mary' + } + ]); + var filtered = l.filter(function (item) { + return item.name === 'Mary'; + }); + assert.notDeepEqual(filtered, l, 'not same object'); + assert.equal(filtered.length, 1, 'one item'); + assert.equal(filtered[0].name, 'Mary', 'filter works'); + }); + QUnit.test('No Add Events if DefineList Splice adds the same items that it is removing. (#1277, #1399)', function (assert) { + var list = new DefineList([ + 'a', + 'b' + ]); + list.bind('add', function () { + assert.ok(false, 'Add callback should not be called.'); + }); + list.bind('remove', function () { + assert.ok(false, 'Remove callback should not be called.'); + }); + var result = list.splice(0, 2, 'a', 'b'); + assert.deepEqual(result, [ + 'a', + 'b' + ]); + }); + QUnit.test('add event always returns an array as the value (#998)', function (assert) { + var list = new DefineList([]), msg; + list.bind('add', function (ev, newElements, index) { + assert.deepEqual(newElements, [4], msg); + }); + msg = 'works on push'; + list.push(4); + list.pop(); + msg = 'works on attr()'; + list.set(0, 4); + list.pop(); + msg = 'works on replace()'; + list.replace([4]); + }); + QUnit.test('Setting with .set() out of bounds of length triggers add event with leading undefineds', function (assert) { + var list = new DefineList([1]); + list.bind('add', function (ev, newElements, index) { + assert.deepEqual(newElements, [ + undefined, + undefined, + 4 + ], 'Leading undefineds are included'); + assert.equal(index, 1, 'Index takes into account the leading undefineds from a .set()'); + }); + list.set(3, 4); + }); + QUnit.test('No events should fire if removals happened on empty arrays', function (assert) { + var list = new DefineList([]), msg; + list.bind('remove', function (ev, removed, index) { + assert.ok(false, msg); + }); + msg = 'works on pop'; + list.pop(); + msg = 'works on shift'; + list.shift(); + assert.ok(true, 'No events were fired.'); + }); + QUnit.test('setting an index out of bounds does not create an array', function (assert) { + assert.expect(1); + var l = new DefineList(); + l.set('1', 'foo'); + assert.equal(l.get('1'), 'foo'); + }); + QUnit.test('splice with similar but less items works (#1606)', function (assert) { + var list = new DefineList([ + 'aa', + 'bb', + 'cc' + ]); + list.splice(0, list.length, 'aa', 'cc', 'dd'); + assert.deepEqual(list.get(), [ + 'aa', + 'cc', + 'dd' + ]); + list.splice(0, list.length, 'aa', 'cc'); + assert.deepEqual(list.get(), [ + 'aa', + 'cc' + ]); + }); + QUnit.test('filter returns same list type (#1744)', function (assert) { + var ParentList = DefineList.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + assert.ok(children.filter(function () { + }) instanceof ChildList); + }); + QUnit.test('reverse returns the same list instance (#1744)', function (assert) { + var ParentList = DefineList.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + assert.ok(children.reverse() === children); + }); + QUnit.test('slice and join are observable by a compute (#1884)', function (assert) { + assert.expect(2); + var list = new DefineList([ + 1, + 2, + 3 + ]); + var sliced = new Observation(function () { + return list.slice(0, 1); + }); + canReflect.onValue(sliced, function (newVal) { + assert.deepEqual(newVal.get(), [2], 'got a new DefineList'); + }); + var joined = new Observation(function () { + return list.join(','); + }); + canReflect.onValue(joined, function (newVal) { + assert.equal(newVal, '2,3', 'joined is observable'); + }); + list.shift(); + }); + QUnit.test('list.replace', function (assert) { + var firstArray = [ + { + id: 1, + name: 'Marshall' + }, + { + id: 2, + name: 'Austin' + }, + { + id: 3, + name: 'Hyrum' + } + ]; + var myList = new DefineList(firstArray); + var newArray = [ + { + id: 4, + name: 'Aubree' + }, + { + id: 5, + name: 'Leah' + }, + { + id: 6, + name: 'Lily' + } + ]; + myList.replace(newArray); + assert.equal(myList.length, 3); + assert.equal(myList[0].name, 'Aubree'); + assert.equal(myList[1].name, 'Leah'); + assert.equal(myList[2].name, 'Lily', 'Can replace a List with an Array.'); + myList.replace(firstArray); + assert.equal(myList.length, 3); + assert.equal(myList[0].name, 'Marshall'); + assert.equal(myList[1].name, 'Austin'); + assert.equal(myList[2].name, 'Hyrum', 'Can replace a List with another List.'); + }); + QUnit.test('list.map', function (assert) { + var myArray = [ + { + id: 1, + name: 'Marshall' + }, + { + id: 2, + name: 'Austin' + }, + { + id: 3, + name: 'Hyrum' + } + ]; + var myList = new DefineList(myArray); + var newList = myList.map(function (person) { + person.lastName = 'Thompson'; + return person; + }); + assert.equal(newList.length, 3); + assert.equal(newList[0].name, 'Marshall'); + assert.equal(newList[0].lastName, 'Thompson'); + assert.equal(newList[1].name, 'Austin'); + assert.equal(newList[1].lastName, 'Thompson'); + assert.equal(newList[2].name, 'Hyrum'); + assert.equal(newList[2].lastName, 'Thompson'); + var ExtendedList = DefineList.extend({ + testMe: function () { + return 'It Worked!'; + } + }); + var myExtendedList = new ExtendedList(myArray); + var newExtendedList = myExtendedList.map(function (person) { + person.lastName = 'Thompson'; + return person; + }); + try { + newExtendedList.testMe(); + } catch (err) { + assert.ok(err.message.match(/testMe/), 'Does not return the same type of list.'); + } + }); + QUnit.test('list.sort a simple list', function (assert) { + var myList = new DefineList([ + 'Marshall', + 'Austin', + 'Hyrum' + ]); + myList.sort(); + assert.equal(myList.length, 3); + assert.equal(myList[0], 'Austin'); + assert.equal(myList[1], 'Hyrum'); + assert.equal(myList[2], 'Marshall', 'Basic list was properly sorted.'); + }); + QUnit.test('list.sort a list of objects', function (assert) { + var objList = new DefineList([ + { + id: 1, + name: 'Marshall' + }, + { + id: 2, + name: 'Austin' + }, + { + id: 3, + name: 'Hyrum' + } + ]); + objList.sort(function (a, b) { + if (a.name < b.name) { + return -1; + } else if (a.name > b.name) { + return 1; + } else { + return 0; + } + }); + assert.equal(objList.length, 3); + assert.equal(objList[0].name, 'Austin'); + assert.equal(objList[1].name, 'Hyrum'); + assert.equal(objList[2].name, 'Marshall', 'List of objects was properly sorted.'); + }); + QUnit.test('list.sort a list of objects without losing reference (#137)', function (assert) { + var unSorted = new DefineList([ + { id: 3 }, + { id: 2 }, + { id: 1 } + ]); + var sorted = unSorted.slice(0).sort(function (a, b) { + return a.id > b.id ? 1 : a.id < b.id ? -1 : 0; + }); + assert.equal(unSorted[0], sorted[2], 'items should be equal'); + }); + QUnit.test('list defines', function (assert) { + assert.expect(6); + var Todo = function (props) { + assign(this, props); + }; + define(Todo.prototype, { + completed: 'boolean', + destroyed: { default: false } + }); + Todo.prototype.destroy = function () { + this.destroyed = true; + }; + var TodoList = DefineList.extend({ + '*': Todo, + remaining: { + get: function () { + return this.filter({ completed: false }); + } + }, + completed: { + get: function () { + return this.filter({ completed: true }); + } + }, + destroyCompleted: function () { + this.completed.forEach(function (todo) { + todo.destroy(); + }); + }, + setCompletedTo: function (value) { + this.forEach(function (todo) { + todo.completed = value; + }); + } + }); + var todos = new TodoList([ + { completed: true }, + { completed: false } + ]); + assert.ok(todos.item(0) instanceof Todo, 'correct instance'); + assert.equal(todos.completed.length, 1, 'only one todo'); + todos.on('completed', function (ev, newVal, oldVal) { + assert.ok(newVal instanceof TodoList, 'right type'); + assert.equal(newVal.length, 2, 'all items'); + assert.ok(oldVal instanceof TodoList, 'right type'); + assert.equal(oldVal.length, 1, 'all items'); + }); + todos.setCompletedTo(true); + }); + QUnit.test('extending the base supports overwriting _eventSetup', function (assert) { + var L = DefineList.extend({}); + Object.getOwnPropertyDescriptor(DefineMap.prototype, '_eventSetup'); + L.prototype.arbitraryProp = true; + assert.ok(true, 'set arbitraryProp'); + L.prototype._eventSetup = function () { + }; + assert.ok(true, 'worked'); + }); + QUnit.test('setting expandos on a DefineList', function (assert) { + var DL = DefineList.extend({ count: 'number' }); + var dl = new DL(); + dl.assign({ + count: 5, + skip: 2 + }); + assert.equal(dl.get('count'), 5, 'read with .get defined'); + assert.equal(dl.count, 5, 'read with . defined'); + assert.equal(dl.get('skip'), 2, 'read with .get expando'); + assert.equal(dl.skip, 2, 'read with . expando'); + assert.equal(dl.get('limit'), undefined, 'read with .get undefined'); + }); + QUnit.test('passing a DefineList to DefineList (#33)', function (assert) { + var m = new DefineList([ + {}, + {} + ]); + var m2 = new DefineList(m); + assert.deepEqual(m.get(), m2.get()); + assert.ok(m[0] === m2[0], 'index the same'); + assert.ok(m[1] === m2[1], 'index the same'); + }); + QUnit.test('reading and setting expandos', function (assert) { + var list = new DefineList(); + var countObservation = new Observation(function () { + return list.get('count'); + }, null, function (newValue) { + assert.equal(newValue, 1000, 'got new value'); + }); + countObservation.start(); + list.set('count', 1000); + assert.equal(countObservation.value, 1000); + var list2 = new DefineList(); + list2.on('count', function (ev, newVal) { + assert.equal(newVal, 5); + }); + list2.set('count', 5); + }); + QUnit.test('extending DefineList constructor functions (#61)', function (assert) { + var AList = DefineList.extend('AList', { + aProp: {}, + aMethod: function () { + } + }); + var BList = AList.extend('BList', { + bProp: {}, + bMethod: function () { + } + }); + var CList = BList.extend('CList', { + cProp: {}, + cMethod: function () { + } + }); + var list = new CList([ + {}, + {} + ]); + list.on('aProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'PROP'); + assert.equal(oldVal, undefined); + }); + list.on('bProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'FOO'); + assert.equal(oldVal, undefined); + }); + list.on('cProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR'); + assert.equal(oldVal, undefined); + }); + list.aProp = 'PROP'; + list.bProp = 'FOO'; + list.cProp = 'BAR'; + assert.ok(list.aMethod); + assert.ok(list.bMethod); + assert.ok(list.cMethod); + }); + QUnit.test('extending DefineList constructor functions more than once (#61)', function (assert) { + var AList = DefineList.extend('AList', { + aProp: {}, + aMethod: function () { + } + }); + var BList = AList.extend('BList', { + bProp: {}, + bMethod: function () { + } + }); + var CList = AList.extend('CList', { + cProp: {}, + cMethod: function () { + } + }); + var list1 = new BList([ + {}, + {} + ]); + var list2 = new CList([ + {}, + {}, + {} + ]); + list1.on('aProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'PROP', 'aProp newVal on list1'); + assert.equal(oldVal, undefined); + }); + list1.on('bProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'FOO', 'bProp newVal on list1'); + assert.equal(oldVal, undefined); + }); + list2.on('aProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'PROP', 'aProp newVal on list2'); + assert.equal(oldVal, undefined); + }); + list2.on('cProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR', 'cProp newVal on list2'); + assert.equal(oldVal, undefined); + }); + list1.aProp = 'PROP'; + list1.bProp = 'FOO'; + list2.aProp = 'PROP'; + list2.cProp = 'BAR'; + assert.ok(list1.aMethod, 'list1 aMethod'); + assert.ok(list1.bMethod); + assert.ok(list2.aMethod); + assert.ok(list2.cMethod, 'list2 cMethod'); + }); + QUnit.test('extending DefineList constructor functions - value (#61)', function (assert) { + var AList = DefineList.extend('AList', { aProp: { default: 1 } }); + var BList = AList.extend('BList', {}); + var CList = BList.extend('CList', {}); + var c = new CList([]); + assert.equal(c.aProp, 1, 'got initial value'); + }); + QUnit.test('\'*\' inheritance works (#61)', function (assert) { + var Account = DefineMap.extend({ + name: 'string', + amount: 'number', + slug: { + serialize: true, + get: function () { + return this.name.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, ''); + } + } + }); + var BaseList = DefineList.extend({ '*': Account }); + var ExtendedList = BaseList.extend({}); + var xl = new ExtendedList([{}]); + assert.ok(xl[0] instanceof Account); + }); + QUnit.test('shorthand getter setter (#56)', function (assert) { + var People = DefineList.extend({ + first: '*', + last: '*', + get fullName() { + return this.first + ' ' + this.last; + }, + set fullName(newVal) { + var parts = newVal.split(' '); + this.first = parts[0]; + this.last = parts[1]; + } + }); + var p = new People([]); + p.fullName = 'Mohamed Cherif'; + p.on('fullName', function (ev, newVal, oldVal) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.fullName = 'Justin Meyer'; + }); + QUnit.test('added and removed are called after items are added/removed (#14)', function (assert) { + var Person = DefineMap.extend({ + id: 'number', + name: 'string' + }); + var addedFuncCalled, removedFuncCalled, theList; + var People = DefineList.extend({ + '#': { + added: function (items, index) { + addedFuncCalled = true; + assert.ok(items, 'items added got passed to added'); + assert.ok(typeof index === 'number', 'index of items was passed to added and is a number'); + assert.ok(items[0].name === 'John', 'Name was correct'); + theList = this; + }, + removed: function (items, index) { + removedFuncCalled = true; + assert.ok(items, 'items added got passed to removed'); + assert.ok(typeof index === 'number', 'index of items was passed to removed and is a number'); + theList = this; + }, + Type: Person + }, + outsideProp: { + type: 'boolean', + default: true + } + }); + var people = new People([]); + var me = new Person(); + me.name = 'John'; + me.id = '1234'; + assert.ok(!addedFuncCalled, 'added function has not been called yet'); + people.push(me); + assert.ok(addedFuncCalled, 'added function was called'); + assert.ok(theList.outsideProp === true && theList instanceof People, 'the list was passed correctly as this to added'); + theList = null; + assert.ok(!removedFuncCalled, 'removed function has not been called yet'); + people.splice(people.indexOf(me), 1); + assert.ok(removedFuncCalled, 'removed function was called'); + assert.ok(theList.outsideProp === true && theList instanceof People, 'the list was passed correctly as this to removed'); + }); + QUnit.test('* vs # (#78)', function (assert) { + var MyList = DefineList.extend({ + '*': 'number', + '#': { + added: function () { + assert.ok(true, 'called on init'); + }, + removed: function () { + }, + type: 'string' + } + }); + var list = new MyList([ + 1, + 2, + 3 + ]); + assert.ok(list[0] === '1', 'converted to string'); + list.set('prop', '4'); + assert.ok(list.prop === 4, 'type converted'); + }); + QUnit.test('Array shorthand uses #', function (assert) { + var MyMap = DefineMap.extend({ 'numbers': ['number'] }); + var map = new MyMap({ + numbers: [ + '1', + '2' + ] + }); + assert.ok(map.numbers[0] === 1, 'converted to number'); + map.numbers.set('prop', '4'); + assert.ok(map.numbers.prop === '4', 'type left alone'); + }); + QUnit.test('replace-with-self lists are diffed properly (can-view-live#10)', function (assert) { + var a = new DefineMap({ name: 'A' }); + var b = new DefineMap({ name: 'B' }); + var c = new DefineMap({ name: 'C' }); + var d = new DefineMap({ name: 'D' }); + assert.expect(4); + var list1 = new DefineList([ + a, + b + ]); + list1.on('add', function (ev, newVals, where) { + throw new Error('list1 should not add.'); + }); + list1.on('remove', function (ev, oldVals, where) { + throw new Error('list1 should not remove.'); + }); + list1.replace([ + a, + b + ]); + var list2 = new DefineList([ + a, + b, + c + ]); + list2.on('add', function (ev, newVals, where) { + assert.equal(newVals.length, 1, 'list2 added length'); + assert.equal(where, 2, 'list2 added location'); + }); + list2.on('remove', function (ev, oldVals, where) { + assert.equal(oldVals.length, 1, 'list2 removed length'); + assert.equal(where, 2, 'list2 removed location'); + }); + list2.replace([ + a, + b, + d + ]); + }); + QUnit.test('set >= length - triggers length event (#152)', function (assert) { + var l = new DefineList([ + 1, + 2, + 3 + ]); + var batchNum = null; + l.on('add', function (e) { + assert.ok(true, 'add called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('remove', function (e) { + assert.ok(false, 'remove called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('length', function (e) { + assert.ok(true, 'length called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + assert.expect(4); + l.set(3, 5); + assert.deepEqual(l.get(), [ + 1, + 2, + 3, + 5 + ], 'updated list'); + }); + QUnit.test('set < length - triggers length event (#150)', function (assert) { + var l = new DefineList([ + 1, + 2, + 3 + ]); + var batchNum = null; + l.on('add', function (e) { + assert.ok(true, 'add called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('remove', function (e) { + assert.ok(true, 'remove called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + l.on('length', function (e) { + assert.ok(true, 'length called'); + if (batchNum === null) { + batchNum = e.batchNum; + } else { + assert.equal(batchNum, e.batchNum, 'batch numbers match'); + } + }); + assert.expect(6); + l.set(2, 4); + assert.deepEqual(l.get(), [ + 1, + 2, + 4 + ], 'updated list'); + }); + QUnit.test('set/splice are observable', function (assert) { + var list = new DefineList([ + 1, + 2, + 3, + 4, + 5 + ]); + var count = new Observation(function () { + var count = 0; + for (var i = 0; i < list.length; i++) { + count += list[i] % 2 ? 1 : 0; + } + return count; + }); + canReflect.onValue(count, function () { + assert.ok(true); + }); + assert.expect(3); + list.set(3, 5); + list.set(2, 4); + list.splice(1, 1, 1); + }); + QUnit.test('setting length > current (#147)', function (assert) { + var list = new DefineList([ + 1, + 2 + ]); + list.length = 5; + assert.equal(list.length, 5); + assert.equal(list.hasOwnProperty(0), true); + assert.equal(list.hasOwnProperty(1), true); + assert.equal(list.hasOwnProperty(2), true); + assert.equal(list.hasOwnProperty(3), true); + assert.equal(list.hasOwnProperty(4), true); + assert.equal(list.hasOwnProperty(5), false); + }); + QUnit.test('setting length < current (#147)', function (assert) { + var list = new DefineList([ + 1, + 2, + 3, + 4, + 5 + ]); + list.length = 3; + assert.equal(list.length, 3); + assert.equal(list.hasOwnProperty(0), true); + assert.equal(list.hasOwnProperty(1), true); + assert.equal(list.hasOwnProperty(2), true); + assert.equal(list.hasOwnProperty(3), false); + assert.equal(list.hasOwnProperty(4), false); + assert.equal(list.hasOwnProperty(5), false); + }); + QUnit.test('every', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'Bob' + }, + { + id: 2, + name: 'Bob' + } + ]); + var allBobs = l.every(function (item) { + return item.name === 'Bob'; + }); + assert.ok(allBobs, 'Every works in true case'); + var idOne = l.every(function (item) { + return item.id === 1; + }); + assert.ok(!idOne, 'Every works in false case'); + allBobs = l.every({ name: 'Bob' }); + assert.ok(allBobs, 'Every works in true case'); + idOne = l.every({ + name: 'Bob', + id: 1 + }); + assert.ok(!idOne, 'Every works in false case'); + }); + QUnit.test('some', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'Alice' + }, + { + id: 2, + name: 'Bob' + } + ]); + var allBobs = l.some(function (item) { + return item.name === 'Bob'; + }); + assert.ok(allBobs, 'Some works in true case'); + var idOne = l.some(function (item) { + return item.name === 'Charlie'; + }); + assert.ok(!idOne, 'Some works in false case'); + allBobs = l.some({ name: 'Bob' }); + assert.ok(allBobs, 'Some works in true case'); + idOne = l.some({ + name: 'Bob', + id: 1 + }); + assert.ok(!idOne, 'Some works in false case'); + }); + QUnit.test('lastIndexOf', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'Alice' + }, + { + id: 2, + name: 'Bob' + } + ]); + var bobIdx = l.lastIndexOf(l[1]); + assert.equal(bobIdx, 1, 'lastIndexOf found object'); + var charlieIdx = l.lastIndexOf({ + id: 3, + name: 'Charlie' + }); + assert.equal(charlieIdx, -1, 'lastIndexOf not found object'); + l.push(l[1]); + bobIdx = l.lastIndexOf(l[1]); + assert.equal(bobIdx, 2, 'lastIndexOf found last index of duped object'); + }); + QUnit.test('reduce', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'Alice', + score: 10 + }, + { + id: 2, + name: 'Bob', + score: 20 + } + ]); + var totalScores = l.reduce(function (total, player) { + return total + player.score; + }, 0); + assert.equal(totalScores, 30, 'Reduce works over list'); + }); + QUnit.test('reduceRight', function (assert) { + var l = new DefineList([ + { + id: 1, + name: 'Alice' + }, + { + id: 2, + name: 'Bob' + } + ]); + var concatenatedNames = l.reduceRight(function (string, person) { + return string + person.name; + }, ''); + assert.equal(concatenatedNames, 'BobAlice', 'ReduceRight works over list'); + }); + QUnit.test('can-reflect onKeyValue', function (assert) { + assert.expect(3); + var list = new DefineList([ + 1, + 2, + 3 + ]); + var key = 1; + canReflect.onKeyValue(list, key, function (newVal) { + assert.equal(newVal, 5); + }); + list.set(key, 5); + canReflect.onKeyValue(list, 'length', function (newVal) { + assert.equal(newVal, 4); + }); + list.push(6); + }); + QUnit.test('works with can-reflect', function (assert) { + var a = new DefineMap({ foo: 4 }); + var b = new DefineList([ + 'foo', + 'bar' + ]); + var c; + assert.equal(canReflect.getKeyValue(b, '0'), 'foo', 'unbound value'); + assert.ok(!canReflect.isValueLike(b), 'isValueLike is false'); + assert.ok(canReflect.isObservableLike(b), 'isObservableLike is true'); + assert.ok(canReflect.isMapLike(b), 'isMapLike is true'); + assert.ok(canReflect.isListLike(b), 'isListLike is false'); + assert.ok(!canReflect.keyHasDependencies(b, 'length'), 'keyHasDependencies -- false'); + define(c = Object.create(b), { + length: { + get: function () { + return a.foo; + } + } + }); + assert.ok(canReflect.getKeyDependencies(c, 'length'), 'dependencies exist'); + assert.ok(canReflect.getKeyDependencies(c, 'length').valueDependencies.has(c._computed.length.compute), 'dependencies returned'); + }); + QUnit.test('can-reflect setKeyValue', function (assert) { + var a = new DefineList([ + 'a', + 'b' + ]); + canReflect.setKeyValue(a, 1, 'c'); + assert.equal(a[1], 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect deleteKeyValue', function (assert) { + var a = new DefineList([ + 'a', + 'b' + ]); + a.set('foo', 'bar'); + canReflect.deleteKeyValue(a, 0); + assert.equal(a[1], undefined, 'last value is now undefined'); + assert.equal(a[0], 'b', 'last value is shifted down'); + canReflect.deleteKeyValue(a, 'foo'); + assert.equal(a.foo, undefined, 'value not included in serial'); + assert.ok(!('foo' in a.get()), 'value not included in serial'); + }); + QUnit.test('can-reflect getKeyDependencies', function (assert) { + var a = new DefineMap({ foo: 4 }); + var b = new DefineList([ + 'foo', + 'bar' + ]); + var c; + assert.ok(!canReflect.getKeyDependencies(b, 'length'), 'No dependencies before binding'); + define(c = Object.create(b), { + length: { + get: function () { + return a.foo; + } + } + }); + assert.ok(canReflect.getKeyDependencies(c, 'length'), 'dependencies exist'); + assert.ok(canReflect.getKeyDependencies(c, 'length').valueDependencies.has(c._computed.length.compute), 'dependencies returned'); + }); + QUnit.test('assign property', function (assert) { + var list = new DefineList([ + 'A', + 'B' + ]); + list.assign({ + count: 0, + skip: 2, + arr: [ + '1', + '2', + '3' + ] + }); + assert.equal(list.get('count'), 0, 'Count set properly'); + list.assign({ + count: 1000, + arr: ['first'] + }); + assert.deepEqual(list.get('arr'), new DefineList(['first']), 'Array is set properly'); + assert.equal(list.get('count'), 1000, 'Count set properly'); + assert.equal(list.get('skip'), 2, 'Skip is unchanged'); + }); + QUnit.test('update property', function (assert) { + var list = new DefineList([ + 'A', + 'B' + ]); + list.update({ + count: 0, + skip: 2 + }); + assert.equal(list.get('count'), 0, 'Count set properly'); + list.update({ count: 1000 }); + assert.equal(list.get('count'), 1000, 'Count set properly'); + assert.equal(list.get('skip'), undefined, 'Skip is changed'); + }); + QUnit.test('assignDeep property', function (assert) { + var list = new DefineList([ + 'A', + 'B' + ]); + list.assignDeep({ + count: 0, + skip: 2, + foo: { + bar: 'zed', + tar: 'yap' + } + }); + assert.equal(list.get('count'), 0, 'Count set properly'); + list.assignDeep({ + count: 1000, + foo: { bar: 'updated' } + }); + assert.equal(list.get('count'), 1000, 'Count set properly'); + assert.equal(list.get('skip'), 2, 'Skip is unchanged'); + assert.propEqual(list.get('foo'), { + bar: 'updated', + tar: 'yap' + }, 'Foo was updated properly'); + }); + QUnit.test('updateDeep property', function (assert) { + var list = new DefineList([ + 'A', + 'B' + ]); + list.updateDeep({ + count: 0, + skip: 2, + foo: { + bar: 'zed', + tar: 'yap' + } + }); + assert.equal(list.get('count'), 0, 'Count set properly'); + list.updateDeep({ count: 1000 }); + assert.equal(list.get('count'), 1000, 'Count set properly'); + assert.equal(list.get('skip'), undefined, 'Skip is set to undefined'); + assert.propEqual(list.get('foo'), undefined, 'Foo is set to undefined'); + }); + QUnit.test('registered symbols', function (assert) { + var a = new DefineMap({ 'a': 'a' }); + assert.ok(a[canSymbol.for('can.isMapLike')], 'can.isMapLike'); + assert.equal(a[canSymbol.for('can.getKeyValue')]('a'), 'a', 'can.getKeyValue'); + a[canSymbol.for('can.setKeyValue')]('a', 'b'); + assert.equal(a.a, 'b', 'can.setKeyValue'); + function handler(val) { + assert.equal(val, 'c', 'can.onKeyValue'); + } + a[canSymbol.for('can.onKeyValue')]('a', handler); + a.a = 'c'; + a[canSymbol.for('can.offKeyValue')]('a', handler); + a.a = 'd'; + }); + QUnit.test('cannot remove length', function (assert) { + var list = new DefineList(['a']); + list.set('length', undefined); + assert.equal(list.length, 1, 'list length is unchanged'); + }); + QUnit.test('cannot set length to a non-number', function (assert) { + var list = new DefineList(['a']); + list.set('length', null); + assert.equal(list.length, 1, 'list length is unchanged'); + list.set('length', 'foo'); + assert.equal(list.length, 1, 'list length is unchanged'); + list.set('length', {}); + assert.equal(list.length, 1, 'list length is unchanged'); + }); + QUnit.test('_length is not enumerable', function (assert) { + assert.ok(!Object.getOwnPropertyDescriptor(new DefineList(), '_length').enumerable, '_length is not enumerable'); + }); + QUnit.test('update with no indexed items sets length to 0', function (assert) { + var list = new DefineList(['a']); + assert.equal(list.length, 1, 'list length is correct before update'); + list.update({ foo: 'bar' }); + assert.equal(list.length, 0, 'list length is correct after update'); + }); + [ + 'length', + '_length' + ].forEach(function (prop) { + QUnit.test('setting ' + prop + ' does not overwrite definition', function (assert) { + var list = new DefineList(); + list.get(prop); + var proto = list, listDef, listDef2; + while (!listDef && proto) { + listDef = Object.getOwnPropertyDescriptor(proto, prop); + proto = Object.getPrototypeOf(proto); + } + list.set(prop, 1); + proto = list; + while (!listDef2 && proto) { + listDef2 = Object.getOwnPropertyDescriptor(proto, prop); + proto = Object.getPrototypeOf(proto); + } + delete listDef2.value; + delete listDef.value; + assert.deepEqual(listDef2, listDef, 'descriptor hasn\'t changed'); + }); + }); + QUnit.test('iterator can recover from bad _length', function (assert) { + var list = new DefineList(['a']); + list.set('_length', null); + assert.equal(list._length, null, 'Bad value for _length'); + var iterator = list[canSymbol.iterator](); + var iteration = iterator.next(); + assert.ok(iteration.done, 'Didn\'t fail'); + }); + QUnit.test('onPatches', function (assert) { + var list = new DefineList([ + 'a', + 'b' + ]); + var PATCHES = [ + [{ + deleteCount: 2, + index: 0, + type: 'splice' + }], + [{ + index: 0, + insert: [ + 'A', + 'B' + ], + deleteCount: 0, + type: 'splice' + }] + ]; + var calledPatches = []; + var handler = function patchesHandler(patches) { + calledPatches.push(patches); + }; + list[canSymbol.for('can.onPatches')](handler, 'notify'); + list.replace([ + 'A', + 'B' + ]); + list[canSymbol.for('can.offPatches')](handler, 'notify'); + list.replace([ + '1', + '2' + ]); + assert.deepEqual(calledPatches, PATCHES); + }); + canTestHelpers.devOnlyTest('can.getName symbol behavior', function (assert) { + var getName = function (instance) { + return instance[canSymbol.for('can.getName')](); + }; + assert.ok('DefineList[]', getName(new DefineList()), 'should use DefineList constructor name by default'); + var MyList = DefineList.extend('MyList', {}); + assert.ok('MyList[]', getName(new MyList()), 'should use custom list name when provided'); + }); + QUnit.test('length event should include previous value', function (assert) { + var done = assert.async(); + var list = new DefineList([]); + var other = new DefineList(['a']); + var changes = []; + list.on('length', function (_, current, previous) { + changes.push({ + current: current, + previous: previous + }); + }); + list.push('x'); + list.pop(); + list.push('y', 'z'); + list.splice(2, 0, 'x', 'w'); + list.splice(0, 1); + list.sort(); + list.replace(other); + assert.expect(1); + setTimeout(function () { + assert.deepEqual(changes, [ + { + current: 1, + previous: 0 + }, + { + current: 0, + previous: 1 + }, + { + current: 2, + previous: 0 + }, + { + current: 4, + previous: 2 + }, + { + current: 3, + previous: 4 + }, + { + current: 3, + previous: 3 + }, + { + current: 1, + previous: 3 + } + ], 'should include length before mutation'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log all events', function (assert) { + var done = assert.async(); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + list.set('total', 100); + list.log(); + var keys = []; + var log = dev.log; + dev.log = function () { + keys.push(JSON.parse(arguments[2])); + }; + list.push('x'); + list.pop(); + list.set('total', 50); + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(keys, [ + 'add', + 'length', + 'remove', + 'length', + 'total' + ], 'should log \'add\', \'remove\', \'length\' and \'propertyName\' events'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log single events', function (assert) { + var done = assert.async(); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + list.set('total', 100); + list.log('length'); + var keys = []; + var log = dev.log; + dev.log = function () { + keys.push(JSON.parse(arguments[2])); + }; + list.push('x'); + list.pop(); + list.set('total', 50); + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(keys, [ + 'length', + 'length' + ], 'should log \'length\' event'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log multiple events', function (assert) { + var done = assert.async(); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + list.set('total', 100); + list.log('add'); + list.log('total'); + var keys = []; + var log = dev.log; + dev.log = function () { + keys.push(JSON.parse(arguments[2])); + }; + list.push('x'); + list.pop(); + list.set('total', 50); + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(keys, [ + 'add', + 'total' + ], 'should log add and total'); + done(); + }); + }); + QUnit.test('DefineList has defineInstanceKey symbol', function (assert) { + var Type = DefineList.extend({}); + Type[canSymbol.for('can.defineInstanceKey')]('prop', { type: 'number' }); + var t = new Type(); + t.prop = '5'; + assert.equal(t.prop, 5, 'value set'); + }); + QUnit.test('.sort() produces patches (can-stache#498)', function (assert) { + var list = new DefineList([ + 'b', + 'a' + ]); + var PATCHES = [ + [{ + index: 0, + deleteCount: 2, + type: 'splice' + }], + [{ + index: 0, + insert: [ + 'a', + 'b' + ], + deleteCount: 0, + type: 'splice' + }] + ]; + var calledPatches = []; + var handler = function patchesHandler(patches) { + calledPatches.push(patches); + }; + list[canSymbol.for('can.onPatches')](handler, 'notify'); + list.sort(); + assert.deepEqual(calledPatches, PATCHES); + }); + QUnit.test('canReflect.getSchema', function (assert) { + var MyType = DefineMap.extend({ + id: { + identity: true, + type: 'number' + }, + name: 'string' + }); + var MyList = DefineList.extend({ + count: 'number', + '#': MyType + }); + var schema = canReflect.getSchema(MyList); + assert.equal(schema.values, MyType); + }); + QUnit.test('Bound serialized lists update when they change length', function (assert) { + assert.expect(1); + var list = new DefineList(['eggs']); + var obs = new Observation(function () { + return list.serialize(); + }); + function onChange(val) { + assert.deepEqual(val, [ + 'eggs', + 'toast' + ]); + } + canReflect.onValue(obs, onChange); + list.push('toast'); + canReflect.offValue(obs, onChange); + }); + if (typeof Array.prototype.includes === 'function') { + QUnit.test('\'includes\' method basics (#277)', function (assert) { + assert.expect(6); + var emptyList = new DefineList([]); + assert.notOk(emptyList.includes(2)); + var list = new DefineList([ + 1, + 2, + 3 + ]); + assert.ok(list.includes(2)); + assert.notOk(list.includes(4)); + assert.notOk(list.includes(3, 3)); + assert.ok(list.includes(3, -1)); + var nanList = new DefineList([ + 1, + 2, + NaN + ]); + assert.ok(nanList.includes(NaN)); + }); + QUnit.test('\'fromIndex\' is not >= to the array length', function (assert) { + assert.expect(2); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + assert.notOk(list.includes('c', 3)); + assert.notOk(list.includes('c', 100)); + }); + QUnit.test('computed index is less than 0', function (assert) { + assert.expect(4); + var list = new DefineList([ + 'a', + 'b', + 'c' + ]); + assert.ok(list.includes('a', -100)); + assert.ok(list.includes('b', -100)); + assert.ok(list.includes('c', -100)); + assert.notOk(list.includes('a', -2)); + }); + QUnit.test('Bound \'includes\' (#277)', function (assert) { + assert.expect(1); + var list = new DefineList(); + var obs = new Observation(function () { + return list.includes('foo'); + }); + function onChange(val) { + assert.ok(val); + } + canReflect.onValue(obs, onChange); + list.push('foo'); + canReflect.offValue(obs, onChange); + }); + } + QUnit.test('Set __inSetup prop #421', function (assert) { + var list = new DefineList([]); + list.set('__inSetup', 'nope'); + assert.equal(list.__inSetup, 'nope'); + }); +}); +/*can-define@2.8.0#map/map-test*/ +define('can-define@2.8.0#map/map-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-define/map/map', + 'can-define', + 'can-observation', + 'can-assign', + 'can-reflect', + 'can-symbol', + 'can-test-helpers/lib/dev', + 'can-define/list/list', + 'can-log/dev/dev', + 'can-observation-recorder', + 'can-data-types/maybe-string/maybe-string', + 'can-reflect-tests/observables/map-like/instance/on-event-get-set-delete-key' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var DefineMap = require('can-define/map/map'); + var define = require('can-define'); + var Observation = require('can-observation'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var isPlainObject = canReflect.isPlainObject; + var canTestHelpers = require('can-test-helpers/lib/dev'); + var DefineList = require('can-define/list/list'); + var dev = require('can-log/dev/dev'); + var ObservationRecorder = require('can-observation-recorder'); + var MaybeString = require('can-data-types/maybe-string/maybe-string'); + var sealWorks = function () { + try { + var o = {}; + Object.seal(o); + o.prop = true; + return false; + } catch (e) { + return true; + } + }(); + QUnit.module('can-define/map/map'); + QUnit.test('Map is an event emitter', function (assert) { + var Base = DefineMap.extend({}); + assert.ok(Base.on, 'Base has event methods.'); + var Map = Base.extend({}); + assert.ok(Map.on, 'Map has event methods.'); + }); + QUnit.test('creating an instance', function (assert) { + var map = new DefineMap({ prop: 'foo' }); + map.on('prop', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR'); + assert.equal(oldVal, 'foo'); + }); + map.prop = 'BAR'; + }); + QUnit.test('creating an instance with nested prop', function (assert) { + var map = new DefineMap({ name: { first: 'Justin' } }); + map.name.on('first', function (ev, newVal, oldVal) { + assert.equal(newVal, 'David'); + assert.equal(oldVal, 'Justin'); + }); + map.name.first = 'David'; + }); + QUnit.test('extending', function (assert) { + var MyMap = DefineMap.extend({ prop: {} }); + var map = new MyMap(); + map.on('prop', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR'); + assert.equal(oldVal, undefined); + }); + map.prop = 'BAR'; + }); + QUnit.test('loop only through defined serializable props', function (assert) { + var MyMap = DefineMap.extend({ + propA: {}, + propB: { serialize: false }, + propC: { + get: function () { + return this.propA; + } + } + }); + var inst = new MyMap({ + propA: 1, + propB: 2 + }); + assert.deepEqual(Object.keys(inst.get()), ['propA']); + }); + QUnit.test('get and set can setup expandos', function (assert) { + var map = new DefineMap(); + var oi = new Observation(function () { + return map.get('foo'); + }); + canReflect.onValue(oi, function (newVal) { + assert.equal(newVal, 'bar', 'updated to bar'); + canReflect.offValue(oi); + }); + map.set('foo', 'bar'); + }); + QUnit.test('default settings', function (assert) { + var MyMap = DefineMap.extend({ + '*': 'string', + foo: {} + }); + var m = new MyMap(); + m.set('foo', 123); + assert.ok(m.get('foo') === '123'); + }); + QUnit.test('default settings on unsealed', function (assert) { + var MyMap = DefineMap.extend({ seal: false }, { '*': 'string' }); + var m = new MyMap(); + m.set('foo', 123); + assert.ok(m.get('foo') === '123'); + }); + if (!System.isEnv('production')) { + QUnit.test('extends sealed objects (#48)', function (assert) { + var Map1 = DefineMap.extend({ seal: true }, { + name: { + get: function (curVal) { + return 'computed ' + curVal; + } + } + }); + var Map2 = Map1.extend({ seal: false }, {}); + var Map3 = Map2.extend({ seal: true }, {}); + var map1 = new Map1({ name: 'Justin' }); + try { + map1.foo = 'bar'; + if (map1.foo) { + assert.ok(false, 'map1 not sealed'); + } else { + assert.ok(true, 'map1 sealed - silent failure'); + } + } catch (ex) { + assert.ok(true, 'map1 sealed'); + } + assert.equal(map1.name, 'computed Justin', 'map1.name property is computed'); + var map2 = new Map2({ name: 'Brian' }); + try { + map2.foo = 'bar'; + if (map2.foo) { + assert.ok(true, 'map2 not sealed'); + } else { + assert.ok(false, 'map2 sealed'); + } + } catch (ex) { + assert.ok(false, 'map2 sealed'); + } + assert.equal(map2.name, 'computed Brian', 'map2.name property is computed'); + var map3 = new Map3({ name: 'Curtis' }); + try { + map3.foo = 'bar'; + if (map3.foo) { + assert.ok(false, 'map3 not sealed'); + } else { + assert.ok(true, 'map3 sealed'); + } + } catch (ex) { + assert.ok(true, 'map3 sealed'); + } + assert.equal(map3.name, 'computed Curtis', 'map3.name property is computed'); + }); + } + QUnit.test('get with dynamically added properties', function (assert) { + var map = new DefineMap(); + map.set('a', 1); + map.set('b', 2); + assert.deepEqual(map.get(), { + a: 1, + b: 2 + }); + }); + QUnit.test('set multiple props', function (assert) { + var map = new DefineMap(); + map.assign({ + a: 0, + b: 2 + }); + assert.deepEqual(map.get(), { + a: 0, + b: 2 + }, 'added props'); + map.update({ a: 2 }); + assert.deepEqual(map.get(), { a: 2 }, 'removed b'); + map.assign({ foo: { bar: 'VALUE' } }); + assert.deepEqual(map.get(), { + foo: { bar: 'VALUE' }, + a: 2 + }, 'works nested'); + }); + QUnit.test('serialize responds to added props', function (assert) { + var map = new DefineMap(); + var oi = new Observation(function () { + return map.serialize(); + }); + canReflect.onValue(oi, function (newVal) { + assert.deepEqual(newVal, { + a: 1, + b: 2 + }, 'updated right'); + canReflect.offValue(oi); + }); + map.assign({ + a: 1, + b: 2 + }); + }); + QUnit.test('initialize an undefined property', function (assert) { + var MyMap = DefineMap.extend({ seal: false }, {}); + var instance = new MyMap({ foo: 'bar' }); + assert.equal(instance.foo, 'bar'); + }); + QUnit.test('set an already initialized null property', function (assert) { + var map = new DefineMap({ foo: null }); + map.assign({ foo: null }); + assert.equal(map.foo, null); + }); + QUnit.test('creating a new key doesn\'t cause two changes', function (assert) { + assert.expect(1); + var map = new DefineMap(); + var oi = new Observation(function () { + return map.serialize(); + }); + canReflect.onValue(oi, function (newVal) { + assert.deepEqual(newVal, { a: 1 }, 'updated right'); + canReflect.offValue(oi); + }); + map.set('a', 1); + }); + QUnit.test('setting nested object', function (assert) { + var m = new DefineMap({}); + m.assign({ foo: {} }); + m.assign({ foo: {} }); + assert.deepEqual(m.get(), { foo: {} }); + }); + QUnit.test('passing a DefineMap to DefineMap (#33)', function (assert) { + var MyMap = DefineMap.extend({ foo: 'observable' }); + var m = new MyMap({ + foo: {}, + bar: {} + }); + var m2 = new MyMap(m); + assert.deepEqual(m.get(), m2.get()); + assert.ok(m.foo === m2.foo, 'defined props the same'); + assert.ok(m.bar === m2.bar, 'expando props the same'); + }); + QUnit.test('serialize: function works (#38)', function (assert) { + var Something = DefineMap.extend({}); + var MyMap = DefineMap.extend({ + somethingRef: { + type: function (val) { + return new Something({ id: val }); + }, + serialize: function (val) { + return val.id; + } + }, + somethingElseRef: { + type: function (val) { + return new Something({ id: val }); + }, + serialize: false + } + }); + var myMap = new MyMap({ + somethingRef: 2, + somethingElseRef: 3 + }); + assert.ok(myMap.somethingRef instanceof Something); + assert.deepEqual(myMap.serialize(), { somethingRef: 2 }, 'serialize: function and serialize: false works'); + var MyMap2 = DefineMap.extend({ + '*': { + serialize: function (value) { + return '' + value; + } + } + }); + var myMap2 = new MyMap2({ + foo: 1, + bar: 2 + }); + assert.deepEqual(myMap2.serialize(), { + foo: '1', + bar: '2' + }, 'serialize: function on default works'); + }); + QUnit.test('get will not create properties', function (assert) { + var method = function () { + }; + var MyMap = DefineMap.extend({ method: method }); + var m = new MyMap(); + m.get('foo'); + assert.equal(m.get('method'), method); + }); + QUnit.test('Properties are enumerable', function (assert) { + assert.expect(4); + var VM = DefineMap.extend({ foo: 'string' }); + var vm = new VM({ + foo: 'bar', + baz: 'qux' + }); + var i = 0; + canReflect.eachKey(vm, function (value, key) { + if (i === 0) { + assert.equal(key, 'foo'); + assert.equal(value, 'bar'); + } else { + assert.equal(key, 'baz'); + assert.equal(value, 'qux'); + } + i++; + }); + }); + QUnit.test('Getters are not enumerable', function (assert) { + assert.expect(2); + var MyMap = DefineMap.extend({ + foo: 'string', + baz: { + get: function () { + return this.foo; + } + } + }); + var map = new MyMap({ foo: 'bar' }); + canReflect.eachKey(map, function (value, key) { + assert.equal(key, 'foo'); + assert.equal(value, 'bar'); + }); + }); + QUnit.test('extending DefineMap constructor functions (#18)', function (assert) { + var AType = DefineMap.extend('AType', { + aProp: {}, + aMethod: function () { + } + }); + var BType = AType.extend('BType', { + bProp: {}, + bMethod: function () { + } + }); + var CType = BType.extend('CType', { + cProp: {}, + cMethod: function () { + } + }); + var map = new CType(); + map.on('aProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'PROP'); + assert.equal(oldVal, undefined); + }); + map.on('bProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'FOO'); + assert.equal(oldVal, undefined); + }); + map.on('cProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR'); + assert.equal(oldVal, undefined); + }); + map.aProp = 'PROP'; + map.bProp = 'FOO'; + map.cProp = 'BAR'; + assert.ok(map.aMethod); + assert.ok(map.bMethod); + assert.ok(map.cMethod); + }); + QUnit.test('extending DefineMap constructor functions more than once (#18)', function (assert) { + var AType = DefineMap.extend('AType', { + aProp: {}, + aMethod: function () { + } + }); + var BType = AType.extend('BType', { + bProp: {}, + bMethod: function () { + } + }); + var CType = AType.extend('CType', { + cProp: {}, + cMethod: function () { + } + }); + var map1 = new BType(); + var map2 = new CType(); + map1.on('aProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'PROP', 'aProp newVal on map1'); + assert.equal(oldVal, undefined); + }); + map1.on('bProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'FOO', 'bProp newVal on map1'); + assert.equal(oldVal, undefined); + }); + map2.on('aProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'PROP', 'aProp newVal on map2'); + assert.equal(oldVal, undefined); + }); + map2.on('cProp', function (ev, newVal, oldVal) { + assert.equal(newVal, 'BAR', 'cProp newVal on map2'); + assert.equal(oldVal, undefined); + }); + map1.aProp = 'PROP'; + map1.bProp = 'FOO'; + map2.aProp = 'PROP'; + map2.cProp = 'BAR'; + assert.ok(map1.aMethod, 'map1 aMethod'); + assert.ok(map1.bMethod); + assert.ok(map2.aMethod); + assert.ok(map2.cMethod, 'map2 cMethod'); + }); + QUnit.test('extending DefineMap constructor functions - value (#18)', function (assert) { + var AType = DefineMap.extend('AType', { aProp: { default: 1 } }); + var BType = AType.extend('BType', {}); + var CType = BType.extend('CType', {}); + var c = new CType(); + assert.equal(c.aProp, 1, 'got initial value'); + }); + QUnit.test('copying DefineMap excludes constructor', function (assert) { + var AType = DefineMap.extend('AType', { aProp: { default: 1 } }); + var a = new AType(); + var b = assign({}, a); + assert.notEqual(a.constructor, b.constructor, 'Constructor prop not copied'); + assert.equal(a.aProp, b.aProp, 'Other values are unaffected'); + }); + QUnit.test('cloning from non-defined map excludes special keys on setup', function (assert) { + var MyType = DefineMap.extend({}); + var a = new MyType({ 'foo': 'bar' }); + var b = new DefineMap(a); + assert.notEqual(a.constructor, b.constructor, 'Constructor prop not copied'); + assert.notEqual(a._data, b._data, '_data prop not copied'); + assert.equal(a.foo, b.foo, 'Other props copied'); + }); + QUnit.test('copying from .set() excludes special keys', function (assert) { + var MyType = DefineMap.extend({}); + var a = new MyType({ + 'foo': 'bar', + 'existing': 'newVal' + }); + var b = new DefineMap({ 'existing': 'oldVal' }); + b.assign(a); + assert.notEqual(a.constructor, b.constructor, 'Constructor prop not copied'); + assert.notEqual(a._data, b._data, '_data prop not copied'); + assert.equal(a.foo, b.foo, 'NEw props copied'); + }); + QUnit.test('copying with assign() excludes special keys', function (assert) { + var a = { + _data: {}, + 'foo': 'bar', + 'existing': 'neVal' + }; + var b = new DefineMap({ 'existing': 'oldVal' }, false); + canReflect.assignMap(b, a); + assert.notEqual(a._data, b._data, '_data prop not copied'); + assert.equal(a.foo, b.foo, 'New props copied'); + assert.equal(a.existing, b.existing, 'Existing props copied'); + }); + QUnit.test('shorthand getter setter (#56)', function (assert) { + var Person = DefineMap.extend({ + first: '*', + last: '*', + get fullName() { + return this.first + ' ' + this.last; + }, + set fullName(newVal) { + var parts = newVal.split(' '); + this.first = parts[0]; + this.last = parts[1]; + } + }); + var p = new Person({ + first: 'Mohamed', + last: 'Cherif' + }); + p.on('fullName', function (ev, newVal, oldVal) { + assert.equal(oldVal, 'Mohamed Cherif'); + assert.equal(newVal, 'Justin Meyer'); + }); + assert.equal(p.fullName, 'Mohamed Cherif', 'fullName initialized right'); + p.fullName = 'Justin Meyer'; + }); + QUnit.test('compute props can be set to null or undefined (#2372)', function (assert) { + var VM = DefineMap.extend({ computeProp: { type: 'compute' } }); + var vmNull = new VM({ computeProp: null }); + assert.equal(vmNull.get('computeProp'), null, 'computeProp is null, no error thrown'); + var vmUndef = new VM({ computeProp: undefined }); + assert.equal(vmUndef.get('computeProp'), undefined, 'computeProp is undefined, no error thrown'); + }); + QUnit.test('Inheriting DefineMap .set doesn\'t work if prop is on base map (#74)', function (assert) { + var Base = DefineMap.extend({ baseProp: 'string' }); + var Inheriting = Base.extend(); + var inherting = new Inheriting(); + inherting.set('baseProp', 'value'); + assert.equal(inherting.baseProp, 'value', 'set prop'); + }); + if (sealWorks && System.env.indexOf('production') < 0) { + QUnit.test('setting not defined property', function (assert) { + var MyMap = DefineMap.extend({ prop: {} }); + var mymap = new MyMap(); + try { + mymap.notdefined = 'value'; + assert.ok(false, 'no error'); + } catch (e) { + assert.ok(true, 'error thrown'); + } + }); + } + QUnit.test('.extend errors when re-defining a property (#117)', function (assert) { + var A = DefineMap.extend('A', { + foo: { + type: 'string', + default: 'blah' + } + }); + A.extend('B', { + foo: { + type: 'string', + default: 'flub' + } + }); + var C = DefineMap.extend('C', { + foo: { + get: function () { + return 'blah'; + } + } + }); + C.extend('D', { + foo: { + get: function () { + return 'flub'; + } + } + }); + assert.ok(true, 'extended without errors'); + }); + QUnit.test('.value functions should not be observable', function (assert) { + var outer = new DefineMap({ bam: 'baz' }); + var ItemsVM = DefineMap.extend({ + item: { + default: function () { + (function () { + }(this.zed, outer.bam)); + return new DefineMap({ foo: 'bar' }); + } + }, + zed: 'string' + }); + var items = new ItemsVM(); + var count = 0; + var itemsList = new Observation(function () { + count++; + return items.item; + }); + canReflect.onValue(itemsList, function () { + }); + items.item.foo = 'changed'; + items.zed = 'changed'; + assert.equal(count, 1); + }); + QUnit.test('.value values are overwritten by props in DefineMap construction', function (assert) { + var Foo = DefineMap.extend({ bar: { default: 'baz' } }); + var foo = new Foo({ bar: 'quux' }); + assert.equal(foo.bar, 'quux', 'Value set properly'); + }); + QUnit.test('can-reflect reflections work with DefineMap', function (assert) { + var b = new DefineMap({ 'foo': 'bar' }); + var c = new (DefineMap.extend({ + 'baz': { + get: function () { + return b.foo; + } + } + }))({ + 'foo': 'bar', + thud: 'baz' + }); + assert.equal(canReflect.getKeyValue(b, 'foo'), 'bar', 'unbound value'); + var handler = function (newValue) { + assert.equal(newValue, 'quux', 'observed new value'); + canReflect.offKeyValue(c, 'baz', handler); + }; + assert.ok(!canReflect.isValueLike(c), 'isValueLike is false'); + assert.ok(canReflect.isObservableLike(c), 'isObservableLike is true'); + assert.ok(canReflect.isMapLike(c), 'isMapLike is true'); + assert.ok(!canReflect.isListLike(c), 'isListLike is false'); + assert.ok(!canReflect.keyHasDependencies(b, 'foo'), 'keyHasDependencies -- false'); + canReflect.onKeyValue(c, 'baz', handler); + canReflect.onKeyValue(c, 'thud', handler); + assert.ok(canReflect.keyHasDependencies(c, 'baz'), 'keyHasDependencies -- true'); + b.foo = 'quux'; + c.thud = 'quux'; + assert.equal(canReflect.getKeyValue(c, 'baz'), 'quux', 'bound value'); + b.foo = 'thud'; + c.baz = 'jeek'; + }); + QUnit.test('can-reflect setKeyValue', function (assert) { + var a = new DefineMap({ 'a': 'b' }); + canReflect.setKeyValue(a, 'a', 'c'); + assert.equal(a.a, 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect deleteKeyValue', function (assert) { + var a = new DefineMap({ 'a': 'b' }); + canReflect.deleteKeyValue(a, 'a'); + assert.equal(a.a, undefined, 'value is now undefined'); + assert.ok(!('a' in a.get()), 'value not included in serial'); + }); + QUnit.test('can-reflect getKeyDependencies', function (assert) { + var a = new DefineMap({ 'a': 'a' }); + var b = new (DefineMap.extend({ + 'a': { + get: function () { + return a.a; + } + } + }))(); + assert.ok(canReflect.getKeyDependencies(b, 'a'), 'dependencies exist'); + assert.ok(!canReflect.getKeyDependencies(b, 'b'), 'no dependencies exist for unknown value'); + assert.ok(canReflect.getKeyDependencies(b, 'a').valueDependencies.has(b._computed.a.compute), 'dependencies returned'); + }); + QUnit.test('can-reflect assign', function (assert) { + var aData = { 'a': 'b' }; + var bData = { 'b': 'c' }; + var a = new DefineMap(aData); + var b = new DefineMap(bData); + canReflect.assign(a, b); + assert.deepEqual(a.get(), assign(aData, bData), 'when called with an object, should merge into existing object'); + }); + QUnit.test('Does not attempt to redefine _data if already defined', function (assert) { + var Bar = DefineMap.extend({ seal: false }, { baz: { default: 'thud' } }); + var baz = new Bar(); + define(baz, { + quux: { default: 'jeek' }, + plonk: { + get: function () { + return 'waldo'; + } + } + }, baz._define); + assert.equal(baz.quux, 'jeek', 'New definitions successful'); + assert.equal(baz.plonk, 'waldo', 'New computed definitions successful'); + assert.equal(baz.baz, 'thud', 'Old definitions still available'); + }); + if (!System.isEnv('production')) { + QUnit.test('redefines still not allowed on sealed objects', function (assert) { + assert.expect(6); + var Bar = DefineMap.extend({ seal: true }, { baz: { default: 'thud' } }); + var baz = new Bar(); + try { + define(baz, { quux: { default: 'jeek' } }, baz._define); + } catch (e) { + assert.ok(/is not extensible/i.test(e.message), 'Sealed object throws on data property defines'); + assert.ok(!Object.getOwnPropertyDescriptor(baz, 'quux'), 'nothing set on object'); + assert.ok(!Object.getOwnPropertyDescriptor(baz._data, 'quux'), 'nothing set on _data'); + } + try { + define(baz, { + plonk: { + get: function () { + return 'waldo'; + } + } + }, baz._define); + } catch (e) { + assert.ok(/is not extensible/i.test(e.message), 'Sealed object throws on computed property defines'); + assert.ok(!Object.getOwnPropertyDescriptor(baz, 'plonk'), 'nothing set on object'); + assert.ok(!Object.getOwnPropertyDescriptor(baz._computed, 'plonk'), 'nothing set on _computed'); + } + }); + } + QUnit.test('Call .get() when a nested object has its own get method', function (assert) { + var Bar = DefineMap.extend({ request: '*' }); + var request = { + prop: 22, + get: function () { + if (arguments.length === 0) { + throw new Error('This function can\'t be called with 0 arguments'); + } + } + }; + var obj = new Bar({ request: request }); + var data = obj.get(); + assert.equal(data.request.prop, 22, 'obj did get()'); + }); + QUnit.test('DefineMap short-hand Type (#221)', function (assert) { + var Child = DefineMap.extend('child', { other: DefineMap }); + var c = new Child(); + c.other = { prop: 'hello' }; + assert.ok(c.other instanceof DefineMap, 'is a DefineMap'); + }); + QUnit.test('non-Object constructor', function (assert) { + var Constructor = DefineMap.extend(); + assert.ok(!isPlainObject(new DefineMap()), 'instance of DefineMap is not a plain object'); + assert.ok(!isPlainObject(new Constructor()), 'instance of extended DefineMap is not a plain object'); + }); + QUnit.test('Observation bound to getter using lastSetVal updates correctly (canjs#3541)', function (assert) { + var MyMap = DefineMap.extend({ + foo: { + get: function (lastSetVal) { + if (lastSetVal) { + return lastSetVal; + } + } + } + }); + var map = new MyMap(); + var oi = new Observation(function () { + return map.get('foo'); + }); + canReflect.onValue(oi, function (newVal) { + assert.equal(newVal, 'bar', 'updated to bar'); + }); + map.set('foo', 'bar'); + }); + QUnit.test('Observation bound to async getter updates correctly (canjs#3541)', function (assert) { + var MyMap = DefineMap.extend({ + foo: { + get: function (lastSetVal, resolve) { + if (lastSetVal) { + return resolve(lastSetVal); + } + } + } + }); + var map = new MyMap(); + var oi = new Observation(function () { + return map.get('foo'); + }); + canReflect.onValue(oi, function (newVal) { + assert.equal(newVal, 'bar', 'updated to bar'); + }); + map.set('foo', 'bar'); + }); + canTestHelpers.devOnlyTest('log all property changes', function (assert) { + var done = assert.async(); + var Person = DefineMap.extend({ + first: 'string', + last: 'string', + children: { Type: DefineList }, + fullName: { + get: function () { + return this.first + ' ' + this.last; + } + } + }); + var changed = []; + var log = dev.log; + dev.log = function () { + changed.push(JSON.parse(arguments[2])); + }; + var p = new Person(); + p.log(); + p.on('fullName', function () { + }); + p.first = 'Manuel'; + p.last = 'Mujica'; + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(changed, [ + 'first', + 'fullName', + 'last', + 'fullName' + ], 'should log all property changes'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log single property changes', function (assert) { + var done = assert.async(); + var Person = DefineMap.extend({ + first: 'string', + last: 'string', + age: 'number' + }); + var changed = []; + var log = dev.log; + dev.log = function () { + changed.push(JSON.parse(arguments[2])); + }; + var p = new Person(); + p.log('first'); + p.first = 'John'; + p.last = 'Doe'; + p.age = 99; + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(changed, ['first'], 'should log \'first\' changes'); + done(); + }); + }); + canTestHelpers.devOnlyTest('log multiple property changes', function (assert) { + var done = assert.async(); + var Person = DefineMap.extend({ + first: 'string', + last: 'string', + age: 'number', + company: 'string' + }); + var changed = []; + var log = dev.log; + dev.log = function () { + changed.push(JSON.parse(arguments[2])); + }; + var p = new Person(); + p.log('first'); + p.log('age'); + p.first = 'John'; + p.last = 'Doe'; + p.company = 'Bitovi'; + p.age = 99; + assert.expect(1); + setTimeout(function () { + dev.log = log; + assert.deepEqual(changed, [ + 'first', + 'age' + ], 'should log first and age'); + done(); + }); + }); + canTestHelpers.devOnlyTest('Setting a value with an object type generates a warning (#148)', function (assert) { + assert.expect(1); + var message = 'can-define: The default value for DefineMap{}.options is set to an object. This will be shared by all instances of the DefineMap. Use a function that returns the object instead.'; + var finishErrorCheck = canTestHelpers.willWarn(message); + DefineMap.extend({ options: { default: {} } }); + DefineMap.extend({ options: { default: [] } }); + DefineMap.extend({ + options: { + default: function () { + } + } + }); + DefineMap.extend({ options: { default: 2 } }); + assert.equal(finishErrorCheck(), 2); + }); + canTestHelpers.devOnlyTest('Setting a default value to a constructor type generates a warning', function (assert) { + assert.expect(1); + var message = 'can-define: The "default" for DefineMap{}.options is set to a constructor. Did you mean "Default" instead?'; + var finishErrorCheck = canTestHelpers.willWarn(message); + DefineMap.extend({ options: { default: DefineMap } }); + assert.equal(finishErrorCheck(), 1); + }); + canTestHelpers.devOnlyTest('can.getName symbol behavior', function (assert) { + var getName = function (instance) { + return instance[canSymbol.for('can.getName')](); + }; + assert.ok('DefineMap{}', getName(new DefineMap()), 'should use DefineMap constructor name by default'); + var MyMap = DefineMap.extend('MyMap', {}); + assert.ok('MyMap{}', getName(new MyMap()), 'should use custom map name when provided'); + }); + canTestHelpers.devOnlyTest('Error on not using a constructor or string on short-hand definitions (#278)', function (assert) { + assert.expect(5); + var message = /does not match a supported propDefinition. See: https:\/\/canjs.com\/doc\/can-define.types.propDefinition.html/i; + var finishErrorCheck = canTestHelpers.willError(message, function (actual, match) { + var rightProp = /prop0[15]/; + assert.ok(rightProp.test(actual.split(' ')[0])); + assert.ok(match); + }); + DefineMap.extend('ShortName', { + prop01: 0, + prop02: function () { + }, + prop03: 'string', + prop04: DefineMap, + prop05: 'a string that is not a type', + prop06: [], + get prop07() { + }, + set prop07(newVal) { + }, + prop08: 'boolean' + }); + assert.equal(finishErrorCheck(), 2); + }); + QUnit.test('Improper shorthand properties are not set', function (assert) { + var VM = DefineMap.extend({ + prop01: 0, + prop02: function () { + }, + prop03: 'some random string' + }); + assert.equal(VM.prototype._define.methods.prop01, undefined); + assert.equal(typeof VM.prototype._define.methods.prop02, 'function'); + assert.equal(VM.prototype._define.methods.prop03, undefined); + }); + QUnit.test('onKeyValue sets up computed values', function (assert) { + var fullNameCalls = []; + var VM = DefineMap.extend({ + first: 'string', + last: 'string', + get fullName() { + fullNameCalls.push(this.first + ' ' + this.last); + return this.first + ' ' + this.last; + } + }); + var vm = new VM({ + first: 'J', + last: 'M' + }); + canReflect.onKeyValue(vm, 'fullName', function () { + }); + assert.deepEqual(fullNameCalls, ['J M']); + }); + QUnit.test('async getters derived from other properties should have correct keyDependencies', function (assert) { + var VM = DefineMap.extend({ + get source() { + return 'source value'; + }, + derived: { + get: function (last, resolve) { + return resolve(this.source); + } + } + }); + var vm = new VM(); + vm.on('derived', function () { + }); + assert.ok(vm._computed.derived.compute.observation.newDependencies.keyDependencies.get(vm).has('source'), 'getter should depend on vm.source'); + }); + var sealDoesErrorWithPropertyName = function () { + 'use strict'; + var o = Object.seal({}); + try { + o.foo = 'bar'; + } catch (error) { + return error.message.indexOf('foo') !== -1; + } + return false; + }(); + canTestHelpers.devOnlyTest('setting a property gives a nice error', function (assert) { + var VM = DefineMap.extend({}); + var vm = new VM(); + try { + vm.set('fooxyz', 'bar'); + } catch (error) { + if (sealDoesErrorWithPropertyName) { + assert.ok(error.message.indexOf('fooxyz') !== -1, 'Set property error with property name should be thrown'); + } else { + assert.ok(true, 'Set property error should be thrown'); + } + } + }); + canTestHelpers.devOnlyTest('can.hasKey and can.hasOwnKey (#303) (#412)', function (assert) { + var hasKeySymbol = canSymbol.for('can.hasKey'), hasOwnKeySymbol = canSymbol.for('can.hasOwnKey'); + var Parent = DefineMap.extend({ + parentProp: 'any', + get parentDerivedProp() { + if (this.parentProp) { + return 'parentDerived'; + } + } + }); + var VM = Parent.extend({ + prop: 'any', + get derivedProp() { + if (this.prop) { + return 'derived'; + } + } + }); + var vm = new VM(); + assert.equal(vm[hasKeySymbol]('prop'), true, 'vm.hasKey(\'prop\') true'); + assert.equal(vm[hasKeySymbol]('derivedProp'), true, 'vm.hasKey(\'derivedProp\') true'); + assert.equal(vm[hasKeySymbol]('parentProp'), true, 'vm.hasKey(\'parentProp\') true'); + assert.equal(vm[hasKeySymbol]('parentDerivedProp'), true, 'vm.hasKey(\'parentDerivedProp\') true'); + assert.equal(vm[hasKeySymbol]('anotherProp'), false, 'vm.hasKey(\'anotherProp\') false'); + assert.equal(vm[hasOwnKeySymbol]('prop'), true, 'vm.hasOwnKey(\'prop\') true'); + assert.equal(vm[hasOwnKeySymbol]('derivedProp'), true, 'vm.hasOwnKey(\'derivedProp\') true'); + assert.equal(vm[hasOwnKeySymbol]('parentProp'), false, 'vm.hasOwnKey(\'parentProp\') false'); + assert.equal(vm[hasOwnKeySymbol]('parentDerivedProp'), false, 'vm.hasOwnKey(\'parentDerivedProp\') false'); + assert.equal(vm[hasOwnKeySymbol]('anotherProp'), false, 'vm.hasOwnKey(\'anotherProp\') false'); + var map = new DefineMap({ expandoKey: undefined }); + assert.equal(map[hasKeySymbol]('expandoKey'), true, 'map.hasKey(\'expandoKey\') (#412)'); + }); + canTestHelpers.devOnlyTest('getOwnKeys, getOwnEnumerableKeys (#326)', function (assert) { + var getOwnEnumerableKeysSymbol = canSymbol.for('can.getOwnEnumerableKeys'), getOwnKeysSymbol = canSymbol.for('can.getOwnKeys'); + var Parent = DefineMap.extend({ + parentProp: 'any', + get parentDerivedProp() { + if (this.parentProp) { + return 'parentDerived'; + } + }, + parentValueProp: { + value: function (prop) { + if (this.parentProp) { + prop.resolve(this.parentProp); + } + prop.listenTo('parentProp', prop.resolve); + } + } + }); + var VM = Parent.extend({ + prop: 'any', + get derivedProp() { + if (this.prop) { + return 'derived'; + } + }, + valueProp: { + value: function (prop) { + if (this.prop) { + prop.resolve(this.prop); + } + prop.listenTo('prop', prop.resolve); + } + } + }); + var vm = new VM(); + assert.deepEqual(vm[getOwnEnumerableKeysSymbol](), [ + 'prop', + 'valueProp', + 'parentProp', + 'parentValueProp' + ], 'vm.getOwnEnumerableKeys()'); + assert.deepEqual(vm[getOwnKeysSymbol](), [ + 'prop', + 'valueProp', + 'parentProp', + 'parentValueProp', + 'derivedProp', + 'parentDerivedProp' + ], 'vm.getOwnKeys()'); + }); + QUnit.test('value as a string breaks', function (assert) { + var MyMap = DefineMap.extend({ prop: { value: 'a string' } }); + var my = new MyMap(); + assert.equal(my.prop, 'a string', 'works'); + }); + QUnit.test('canReflect.getSchema', function (assert) { + var StringIgnoreCase = canReflect.assignSymbols({}, { + 'can.new': function (value) { + return value.toLowerCase(); + } + }); + var MyType = DefineMap.extend({ + id: { + identity: true, + type: 'number' + }, + name: 'string', + foo: { serialize: false }, + lowerCase: StringIgnoreCase, + text: MaybeString, + maybeString_type: { type: MaybeString }, + maybeString_Type: { Type: MaybeString } + }); + var schema = canReflect.getSchema(MyType); + assert.deepEqual(schema.identity, ['id'], 'right identity'); + assert.deepEqual(Object.keys(schema.keys), [ + 'id', + 'name', + 'lowerCase', + 'text', + 'maybeString_type', + 'maybeString_Type' + ], 'right key names'); + assert.equal(canReflect.convert('1', schema.keys.id), 1, 'converted to number'); + assert.equal(canReflect.convert(3, schema.keys.id), '3', 'converted to number'); + assert.equal(schema.keys.name, MaybeString, ' \'string\' -> MaybeString'); + assert.equal(schema.keys.lowerCase, StringIgnoreCase, 'StringIgnoreCase'); + assert.equal(schema.keys.text, MaybeString, 'MaybeString'); + assert.equal(schema.keys.maybeString_type, MaybeString, '{type: MaybeString}'); + assert.equal(schema.keys.maybeString_Type, MaybeString, '{Type: MaybeString}'); + }); + QUnit.test('use can.new and can.serialize for conversion', function (assert) { + var Status = canReflect.assignSymbols({}, { + 'can.new': function (val) { + return val.toLowerCase(); + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + 'new', + 'assigned', + 'complete' + ] + }; + }, + 'can.serialize': function () { + return this.toUpperCase(); + } + }); + var Todo = DefineMap.extend('Todo', { status: Status }); + var todo = new Todo({ status: 'NEW' }); + assert.equal(todo.status, 'new', 'converted during set'); + assert.deepEqual(todo.serialize(), { status: 'NEW' }, 'serialized to upper case'); + var Todo2 = DefineMap.extend('Todo', { due: 'date' }); + var date = new Date(2018, 3, 30); + var todo2 = new Todo2({ due: date.toString() }); + assert.ok(todo2.due instanceof Date, 'converted to a date instance'); + var res = todo2.serialize(); + assert.deepEqual(res, { due: date }, 'serialized to a date?'); + }); + QUnit.test('make sure stringOrObservable works', function (assert) { + var Type = DefineMap.extend({ val: 'stringOrObservable' }); + var type = new Type({ val: 'foo' }); + assert.equal(type.val, 'foo', 'works'); + }); + QUnit.test('primitive types work with val: Type', function (assert) { + var UpperCase = {}; + UpperCase[canSymbol.for('can.new')] = function (val) { + return val.toUpperCase(); + }; + var Type = DefineMap.extend({ val: UpperCase }); + var type = new Type({ val: 'works' }); + assert.equal(type.val, 'WORKS', 'it worked'); + }); + QUnit.test('primitive types work with val: {Type: Type}', function (assert) { + var UpperCase = {}; + UpperCase[canSymbol.for('can.new')] = function (val) { + return val.toUpperCase(); + }; + var Type = DefineMap.extend({ val: { Type: UpperCase } }); + var type = new Type({ val: 'works' }); + assert.equal(type.val, 'WORKS', 'it worked'); + }); + QUnit.test('primitive types work with val: {type: Type}', function (assert) { + var UpperCase = {}; + UpperCase[canSymbol.for('can.new')] = function (val) { + return val.toUpperCase(); + }; + var Type = DefineMap.extend({ val: { type: UpperCase } }); + var type = new Type({ val: 'works' }); + assert.equal(type.val, 'WORKS', 'it worked'); + }); + QUnit.test('ownKeys works on basic DefineMaps', function (assert) { + var map = new DefineMap({ + first: 'Jane', + last: 'Doe' + }); + var keys = canReflect.getOwnKeys(map); + assert.equal(keys.length, 2, 'There are 2 keys'); + }); + QUnit.test('deleteKey works (#351)', function (assert) { + var map = new DefineMap({ foo: 'bar' }); + assert.deepEqual(canReflect.getOwnKeys(map), ['foo']); + map.set('zed', 'ted'); + assert.deepEqual(canReflect.getOwnKeys(map), [ + 'foo', + 'zed' + ]); + map.deleteKey('zed'); + assert.deepEqual(canReflect.getOwnKeys(map), ['foo']); + map.deleteKey('foo'); + assert.deepEqual(canReflect.getOwnKeys(map), []); + map.set('foo', 'bar'); + map = new DefineMap({ foo: 'bar' }, true); + map.deleteKey('foo'); + assert.equal(map.foo, undefined, 'prop set to undefined'); + }); + QUnit.test('makes sure observation add is called (#393)', function (assert) { + var map = new DefineMap({ foo: 'bar' }); + canReflect.deleteKeyValue(map, 'foo'); + ObservationRecorder.start(); + (function () { + return map.foo; + }()); + var result = ObservationRecorder.stop(); + assert.deepEqual(canReflect.toArray(result.keyDependencies.get(map)), ['foo'], 'toArray'); + }); + QUnit.test('type called with `this` as the map (#349)', function (assert) { + var Type = DefineMap.extend({ + foo: { + type: function () { + assert.equal(Type, this.constructor, 'got the right this'); + return 5; + }, + default: 4 + } + }); + var map = new Type(); + assert.equal(map.foo, 5); + }); + QUnit.test('expandos use default type (#383)', function (assert) { + var AllNumbers = DefineMap.extend({ '*': { type: 'number' } }); + var someNumbers = new AllNumbers({ version: '24' }); + assert.ok(someNumbers.version === 24, 'is 24'); + }); + QUnit.test('do not enumerate anything other than key properties (#369)', function (assert) { + var ancestor = { prop: true }; + var F = function () { + }; + F.prototype = ancestor; + var descendant = new F(); + Object.defineProperty(descendant, 'prop', { + writable: true, + configurable: true, + enumerable: false, + value: true + }); + var test = {}; + for (var k in descendant) { + test[k] = descendant[k]; + } + if (test.prop) { + return assert.ok(test.prop, 'Browser doesn\'t correctly skip shadowed enumerable properties'); + } + var Type = DefineMap.extend({ + aProp: 'string', + aMethod: function () { + } + }); + var instance = new Type({ + aProp: 'VALUE', + anExpando: 'VALUE' + }); + var props = {}; + for (var prop in instance) { + props[prop] = true; + } + assert.deepEqual(props, { + aProp: true, + anExpando: true, + aMethod: true + }); + }); + QUnit.test('Properties added via defineInstanceKey are observable', function (assert) { + var Type = DefineMap.extend({}); + var map = new Type(); + var obs = new Observation(function () { + return canReflect.serialize(map); + }); + var count = 0; + canReflect.onValue(obs, function (val) { + count++; + if (count === 2) { + assert.deepEqual(val, { foo: 'bar' }, 'changed value'); + } + }); + canReflect.defineInstanceKey(Type, 'foo', { type: 'string' }); + map.foo = 'bar'; + }); + QUnit.test('Serialized computes do not prevent getters from working', function (assert) { + var Type = DefineMap.extend('MyType', { + page: 'string', + myPage: { + get: function (last, resolve) { + return this.page; + } + } + }); + var first = new Type({ page: 'one' }); + var firstObservation = new Observation(function () { + return canReflect.serialize(first); + }); + var boundTo = Function.prototype; + canReflect.onValue(firstObservation, boundTo); + var second = new Type({ page: 'two' }); + assert.equal(second.myPage, 'two', 'Runs the getter correctly'); + }); + QUnit.test('setup should be called (#395)', function (assert) { + var calls = []; + var Base = DefineMap.extend('Base', { + setup: function (attrs) { + calls.push(this); + return DefineMap.prototype.setup.apply(this, arguments); + } + }); + var Super = Base.extend('Super', {}); + var base = new Base(); + var supa = new Super(); + assert.deepEqual(calls, [ + base, + supa + ], 'setup called'); + }); + QUnit.test('Set new prop to undefined #408', function (assert) { + var obj = new DefineMap({}); + var PATCHES = [ + [{ + type: 'add', + key: 'foo', + value: undefined + }], + [{ + type: 'set', + key: 'foo', + value: 'bar' + }] + ]; + var calledPatches = []; + var handler = function (patches) { + calledPatches.push(patches); + }; + obj[canSymbol.for('can.onPatches')](handler, 'notify'); + obj.set('foo', undefined); + obj.set('foo', 'bar'); + assert.deepEqual(calledPatches, PATCHES); + }); + QUnit.test('Set __inSetup prop #421', function (assert) { + var map = new DefineMap({}); + map.set('__inSetup', 'nope'); + assert.equal(map.__inSetup, 'nope'); + }); + QUnit.test('\'*\' wildcard type definitions that use constructors works for expandos #425', function (assert) { + var MyType = function MyType() { + }; + MyType.prototype = {}; + var OtherType = DefineMap.extend({ seal: false }, { '*': MyType }); + var map = new OtherType(); + map.set('foo', {}); + var foo = map.get('foo'); + assert.ok(foo instanceof MyType); + }); + QUnit.test('\'*\' wildcard type definitions that use DefineMap constructors works for expandos #425', function (assert) { + var MyType = DefineMap.extend({}); + var OtherType = DefineMap.extend({ seal: false }, { '*': MyType }); + var map = new OtherType(); + map.set('foo', {}); + var foo = map.get('foo'); + assert.ok(foo instanceof MyType); + }); + require('can-reflect-tests/observables/map-like/instance/on-event-get-set-delete-key')('DefineMap', function () { + return new DefineMap(); + }); +}); +/*can-define@2.8.0#test/test-list-and-map*/ +define('can-define@2.8.0#test/test-list-and-map', [ + 'require', + 'exports', + 'module', + 'can-define/map/map', + 'can-define/list/list', + 'can-reflect', + 'can-observation', + 'can-define', + 'steal-qunit' +], function (require, exports, module) { + var DefineMap = require('can-define/map/map'); + var DefineList = require('can-define/list/list'); + var canReflect = require('can-reflect'); + var isPlainObject = canReflect.isPlainObject; + var Observation = require('can-observation'); + var define = require('can-define'); + var QUnit = require('steal-qunit'); + QUnit.module('can-define: map and list combined'); + QUnit.test('basics', function (assert) { + var items = new DefineMap({ + people: [ + { name: 'Justin' }, + { name: 'Brian' } + ], + count: 1000 + }); + assert.ok(items.people instanceof DefineList, 'people is list'); + assert.ok(items.people.item(0) instanceof DefineMap, '1st object is Map'); + assert.ok(items.people.item(1) instanceof DefineMap, '2nd object is Map'); + assert.equal(items.people.item(1).name, 'Brian', '2nd object\'s name is right'); + assert.equal(items.count, 1000, 'count is number'); + }); + QUnit.test('basic type', function (assert) { + assert.expect(6); + var Typer = function (arrayWithAddedItem, listWithAddedItem) { + this.arrayWithAddedItem = arrayWithAddedItem; + this.listWithAddedItem = listWithAddedItem; + }; + define(Typer.prototype, { + arrayWithAddedItem: { + type: function (value) { + if (value && value.push) { + value.push('item'); + } + return value; + } + }, + listWithAddedItem: { + type: function (value) { + if (value && value.push) { + value.push('item'); + } + return value; + }, + Type: DefineList + } + }); + var t = new Typer(); + assert.deepEqual(Object.keys(t), [], 'no keys'); + var array = []; + t.arrayWithAddedItem = array; + assert.deepEqual(array, ['item'], 'updated array'); + assert.equal(t.arrayWithAddedItem, array, 'leave value as array'); + t.listWithAddedItem = []; + assert.ok(t.listWithAddedItem instanceof DefineList, 'convert to CanList'); + assert.equal(t.listWithAddedItem[0], 'item', 'has item in it'); + var observation = new Observation(function () { + return t.listWithAddedItem.attr('length'); + }); + canReflect.onValue(observation, function (newVal) { + assert.equal(newVal, 2, 'got a length change'); + }); + t.listWithAddedItem.push('another item'); + }); + QUnit.test('serialize works', function (assert) { + var Person = DefineMap.extend({ + first: 'string', + last: 'string' + }); + var People = DefineList.extend({ '*': Person }); + var people = new People([{ + first: 'j', + last: 'm' + }]); + assert.deepEqual(people.serialize(), [{ + first: 'j', + last: 'm' + }]); + }); + QUnit.test('Extended Map with empty def converts to default Observables', function (assert) { + var School = DefineMap.extend({ + students: {}, + teacher: {} + }); + var school = new School(); + school.students = [{ name: 'J' }]; + school.teacher = { name: 'M' }; + assert.ok(school.students instanceof DefineList, 'converted to DefineList'); + assert.ok(school.teacher instanceof DefineMap, 'converted to DefineMap'); + }); + QUnit.test('default \'observable\' type prevents Type from working (#29)', function (assert) { + var M = DefineMap.extend('M', { id: 'number' }); + var L = DefineList.extend('L', { '*': M }); + var MyMap = DefineMap.extend({ l: L }); + var m = new MyMap({ l: [{ id: 5 }] }); + assert.ok(m.l[0] instanceof M, 'is instance'); + assert.equal(m.l[0].id, 5, 'correct props'); + }); + QUnit.test('inline DefineList Type', function (assert) { + var M = DefineMap.extend('M', { id: 'number' }); + var MyMap = DefineMap.extend({ l: { Type: [M] } }); + var m = new MyMap({ l: [{ id: 5 }] }); + assert.ok(m.l[0] instanceof M, 'is instance'); + assert.equal(m.l[0].id, 5, 'correct props'); + }); + QUnit.test('recursively `get`s (#31)', function (assert) { + var M = DefineMap.extend('M', { id: 'number' }); + var MyMap = DefineMap.extend({ l: { Type: [M] } }); + var m = new MyMap({ l: [{ id: 5 }] }); + var res = m.get(); + assert.ok(Array.isArray(res.l), 'is a plain array'); + assert.ok(isPlainObject(res.l[0]), 'plain object'); + }); + QUnit.test('DefineList trigger deprecation warning when set with Map.set (#93)', function (assert) { + assert.expect(0); + var map = new DefineMap({ things: [{ foo: 'bar' }] }); + map.things.attr = function () { + assert.ok(false, 'attr should not be called'); + }; + map.assign({ things: [{ baz: 'luhrmann' }] }); + }); + QUnit.test('Value generator can read other properties', function (assert) { + var Map = define.Constructor({ + letters: { default: 'ABC' }, + numbers: { + default: [ + 1, + 2, + 3 + ] + }, + definedLetters: { default: 'DEF' }, + definedNumbers: { + default: [ + 4, + 5, + 6 + ] + }, + generatedLetters: { + default: function () { + return 'GHI'; + } + }, + generatedNumbers: { + default: function () { + return new DefineList([ + 7, + 8, + 9 + ]); + } + }, + firstLetter: { + default: function () { + return this.letters.substr(0, 1); + } + }, + firstNumber: { + default: function () { + return this.numbers[0]; + } + }, + middleLetter: { + default: function () { + return this.definedLetters.substr(1, 1); + } + }, + middleNumber: { + default: function () { + return this.definedNumbers[1]; + } + }, + lastLetter: { + default: function () { + return this.generatedLetters.substr(2, 1); + } + }, + lastNumber: { + default: function () { + return this.generatedNumbers[2]; + } + } + }); + var map = new Map(); + var prefix = 'Was able to read dependent value from '; + assert.equal(map.firstLetter, 'A', prefix + 'traditional can.Map style property definition'); + assert.equal(map.firstNumber, 1, prefix + 'traditional can.Map style property definition'); + assert.equal(map.middleLetter, 'E', prefix + 'define plugin style default property definition'); + assert.equal(map.middleNumber, 5, prefix + 'define plugin style default property definition'); + assert.equal(map.lastLetter, 'I', prefix + 'define plugin style generated default property definition'); + assert.equal(map.lastNumber, 9, prefix + 'define plugin style generated default property definition'); + }); + QUnit.test('value and get (#1521)', function (assert) { + var MyMap = define.Constructor({ + data: { + default: function () { + return new DefineList(['test']); + } + }, + size: { + default: 1, + get: function (val) { + var list = this.data; + var length = list.attr('length'); + return val + length; + } + } + }); + var map = new MyMap({}); + assert.equal(map.size, 2); + }); + QUnit.test('Assign value on map', function (assert) { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'CanJS', + foo: { + bar: 'bar', + zoo: 'say' + } + }); + obj.assign({ + list: ['another'], + foo: { bar: 'zed' } + }); + assert.equal(obj.list.length, 1, 'list length should be 1'); + assert.propEqual(obj.foo, { bar: 'zed' }, 'foo.bar is set correctly'); + assert.equal(obj.name, 'CanJS', 'name is unchanged'); + }); + QUnit.test('Update value on a map', function (assert) { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'CanJS', + foo: { bar: 'bar' } + }); + obj.update({ + list: ['another'], + foo: { bar: 'zed' } + }); + assert.equal(obj.list.length, 1, 'list length should be 1'); + assert.equal(obj.foo.bar, 'zed', 'foo.bar is set correctly'); + assert.equal(obj.name, undefined, 'name is removed'); + }); + QUnit.test('Deep assign a map', function (assert) { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'Test Name' + }); + assert.equal(obj.list.length, 3, 'list length should be 3'); + obj.assignDeep({ list: ['something'] }); + assert.equal(obj.name, 'Test Name', 'Name property is still intact'); + assert.equal(obj.list[0], 'something', 'the first element in the list should be updated'); + }); + QUnit.test('Deep updating a map', function (assert) { + var MyConstruct = DefineMap.extend({ + list: DefineList, + name: 'string' + }); + var obj = new MyConstruct({ + list: [ + 'data', + 'data', + 'data' + ], + name: 'Test Name' + }); + assert.equal(obj.list.length, 3, 'list length should be 3'); + obj.updateDeep({ list: ['something'] }); + assert.equal(obj.name, undefined, 'Name property has been reset'); + assert.equal(obj.list[0], 'something', 'the first element of the list should be updated'); + }); + QUnit.test('assignDeep', function (assert) { + var justin = new DefineMap({ + name: 'Justin', + age: 35 + }), payal = new DefineMap({ + name: 'Payal', + age: 35 + }); + var people = new DefineList([ + justin, + payal + ]); + people.assignDeep([{ age: 36 }]); + assert.deepEqual(people.serialize(), [ + { + name: 'Justin', + age: 36 + }, + { + name: 'Payal', + age: 35 + } + ], 'assigned right'); + }); + QUnit.test('DefineMap fires \'set\' event when a new property is added (#400)', function (assert) { + var counter = 0; + var vm = new DefineMap({}); + canReflect.onPatches(vm, function (patch) { + if (counter === 0) { + assert.equal(patch[0].type, 'add', 'dispatched add correctly'); + } else { + assert.equal(patch[0].type, 'set', 'dispatched set correctly'); + } + counter++; + }); + vm.set('name', 'Matt'); + vm.set('name', 'Justin'); + }); +}); +/*can-define@2.8.0#test/test-value-resolve*/ +define('can-define@2.8.0#test/test-value-resolve', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-define/list/list', + 'can-define/map/map', + 'can-reflect', + 'can-queues', + 'can-observation-recorder' +], function (require, exports, module) { + 'use strict'; + var QUnit = require('steal-qunit'); + require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var canReflect = require('can-reflect'); + var queues = require('can-queues'); + var ObservationRecorder = require('can-observation-recorder'); + QUnit.module('can-define value with resolve'); + QUnit.test('counter', function (assert) { + var Person = DefineMap.extend('Person', { + name: 'string', + nameChangeCount: { + value: function (prop) { + var count = 0; + prop.resolve(count); + prop.listenTo('name', function () { + prop.resolve(++count); + }); + } + } + }); + var me = new Person(); + assert.equal(me.nameChangeCount, 0, 'unbound value'); + me.name = 'first'; + assert.equal(me.nameChangeCount, 0, 'unbound value'); + me.on('nameChangeCount', function (ev, newVal, oldVal) { + assert.equal(newVal, 1, 'updated count'); + assert.equal(oldVal, 0, 'updated count from old value'); + }); + me.name = 'second'; + assert.equal(me.nameChangeCount, 1, 'bound value'); + }); + QUnit.test('fullName getter the hard way', function (assert) { + assert.expect(3); + var Person = DefineMap.extend('Person', { + first: 'string', + last: 'string', + fullName: { + value: function (prop) { + var first = this.first, last = this.last; + prop.resolve(first + ' ' + last); + prop.listenTo('first', function (ev, newFirst) { + first = newFirst; + prop.resolve(first + ' ' + last); + }); + prop.listenTo('last', function (ev, newLast) { + last = newLast; + prop.resolve(first + ' ' + last); + }); + } + } + }); + var me = new Person({ + first: 'Justin', + last: 'Meyer' + }); + assert.equal(me.fullName, 'Justin Meyer', 'unbound value'); + var handler = function (ev, newVal, oldVal) { + assert.equal(newVal, 'Ramiya Meyer', 'event newVal'); + assert.equal(oldVal, 'Justin Meyer', 'event oldVal'); + }; + me.on('fullName', handler); + me.first = 'Ramiya'; + me.off('fullName', handler); + me.last = 'Shah'; + }); + QUnit.test('list length', function (assert) { + var VM = DefineMap.extend('VM', { + tasks: [], + tasksLength: { + value: function (prop) { + var tasks; + function checkAndResolve() { + if (tasks) { + prop.resolve(tasks.length); + } else { + prop.resolve(0); + } + } + function updateTask(ev, newTask, oldTask) { + if (oldTask) { + prop.stopListening(oldTask); + } + tasks = newTask; + if (newTask) { + prop.listenTo(newTask, 'length', function (ev, newVal) { + prop.resolve(newVal); + }); + } + checkAndResolve(); + } + prop.listenTo('tasks', updateTask); + updateTask(null, this.tasks, null); + } + } + }); + var vm = new VM({ tasks: null }); + assert.equal(vm.tasksLength, 0, 'empty tasks, unbound'); + vm.tasks = [ + 'chore 1', + 'chore 2' + ]; + assert.equal(vm.tasksLength, 2, 'tasks, unbound'); + var lengths = []; + vm.on('tasksLength', function (ev, newLength) { + lengths.push(newLength); + }); + assert.equal(vm.tasksLength, 2, '2 tasks, bound'); + vm.tasks.push('chore 3'); + var originalTasks = vm.tasks; + assert.equal(vm.tasksLength, 3, '3 tasks, bound, after push to source'); + vm.tasks = ['one chore']; + assert.equal(vm.tasksLength, 1, '1 tasks, bound, after replace array'); + assert.notOk(canReflect.isBound(originalTasks), 'not bound on original'); + assert.deepEqual(lengths, [ + 3, + 1 + ], 'length changes are right'); + }); + QUnit.test('batches produce one result', function (assert) { + assert.expect(2); + var Person = DefineMap.extend('Person', { + first: 'string', + last: 'string', + fullName: { + value: function (prop) { + var first = this.first, last = this.last; + prop.resolve(first + ' ' + last); + prop.listenTo('first', function (ev, newFirst) { + first = newFirst; + prop.resolve(first + ' ' + last); + }); + prop.listenTo('last', function (ev, newLast) { + last = newLast; + prop.resolve(first + ' ' + last); + }); + } + } + }); + var me = new Person({ + first: 'Justin', + last: 'Meyer' + }); + var handler = function (ev, newVal, oldVal) { + assert.equal(newVal, 'Ramiya Shah', 'event newVal'); + assert.equal(oldVal, 'Justin Meyer', 'event oldVal'); + }; + me.on('fullName', handler); + queues.batch.start(); + me.first = 'Ramiya'; + me.last = 'Shah'; + queues.batch.stop(); + }); + QUnit.test('location vm', function (assert) { + var Locator = DefineMap.extend('Locator', { + state: 'string', + setCity: function (city) { + this.dispatch('citySet', city); + }, + city: { + value: function (prop) { + prop.listenTo('citySet', function (ev, city) { + prop.resolve(city); + }); + prop.listenTo('state', function () { + prop.resolve(null); + }); + } + } + }); + var locator = new Locator({ state: 'IL' }); + locator.on('city', function () { + }); + locator.setCity('Chicago'); + locator.state = 'CA'; + assert.equal(locator.city, null, 'changing the state sets the city'); + }); + QUnit.test('location vm with setter', function (assert) { + var Locator = DefineMap.extend('Locator', { + state: 'string', + city: { + value: function (prop) { + prop.listenTo(prop.lastSet, prop.resolve); + prop.listenTo('state', function () { + prop.resolve(null); + }); + prop.resolve(prop.lastSet.get()); + } + } + }); + var locator = new Locator({ + state: 'IL', + city: 'Chicago' + }); + assert.equal(locator.city, 'Chicago', 'init to Chicago'); + locator.on('city', function () { + }); + locator.state = 'CA'; + assert.equal(locator.city, null, 'changing the state sets the city'); + locator.city = 'San Jose'; + assert.equal(locator.city, 'San Jose', 'changing the state sets the city'); + }); + QUnit.test('events should not be fired when resolve is not called', function (assert) { + var Numbers = DefineMap.extend('Numbers', { + oddNumber: { + value: function (prop) { + prop.resolve(5); + prop.listenTo(prop.lastSet, function (newVal) { + if (newVal % 2) { + prop.resolve(newVal); + } + }); + } + } + }); + var nums = new Numbers({}); + assert.equal(nums.oddNumber, 5, 'initial value is 5'); + nums.on('oddNumber', function (ev, newVal) { + assert.equal(newVal % 2, 1, 'event dispatched for ' + newVal); + }); + nums.oddNumber = 7; + nums.oddNumber = 8; + }); + QUnit.test('reading properties does not leak out', function (assert) { + var Type = DefineMap.extend({ + prop: { + value: function (prop) { + prop.resolve(this.value); + } + }, + value: { default: 'hi' } + }); + var t = new Type(); + ObservationRecorder.start(); + t.on('prop', function () { + }); + var records = ObservationRecorder.stop(); + assert.equal(records.keyDependencies.size, 0, 'there are no key dependencies'); + }); +}); +/*can-define@2.8.0#test/test*/ +define('can-define@2.8.0#test/test', [ + 'require', + 'exports', + 'module', + './test-define-only', + '../list/list-test', + '../map/map-test', + './test-list-and-map', + './test-value-resolve' +], function (require, exports, module) { + require('./test-define-only'); + require('../list/list-test'); + require('../map/map-test'); + require('./test-list-and-map'); + require('./test-value-resolve'); +}); +/*can-fixture@3.1.7#data-from-url*/ +define('can-fixture@3.1.7#data-from-url', function (require, exports, module) { + var replacer = /\{([^\}]+)\}/g; + module.exports = function dataFromUrl(fixtureUrl, url) { + if (!fixtureUrl) { + return {}; + } + var order = [], fixtureUrlAdjusted = fixtureUrl.replace('.', '\\.').replace('?', '\\?'), res = new RegExp(fixtureUrlAdjusted.replace(replacer, function (whole, part) { + order.push(part); + return '([^/]+)'; + }) + '$').exec(url), data = {}; + if (!res) { + return null; + } + res.shift(); + order.forEach(function (name) { + data[name] = res.shift(); + }); + return data; + }; +}); +/*can-fixture@3.1.7#matches*/ +define('can-fixture@3.1.7#matches', [ + 'require', + 'exports', + 'module', + 'can-query-logic/src/set', + 'can-reflect', + './data-from-url', + 'can-query-logic' +], function (require, exports, module) { + var set = require('can-query-logic/src/set'); + var canReflect = require('can-reflect'); + var dataFromUrl = require('./data-from-url'); + var QueryLogic = require('can-query-logic'); + function deepEqual(a, b) { + if (a === b) { + return true; + } else if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) { + return false; + } else { + return a.every(function (aVal, i) { + return deepEqual(aVal, b[i]); + }); + } + } else if (a && b && canReflect.isPlainObject(a) && canReflect.isPlainObject(b)) { + var aKeys = Object.keys(a), bKeys = Object.keys(b); + if (aKeys.length === bKeys.length) { + for (var prop in a) { + if (!b.hasOwnProperty(prop)) { + return false; + } + if (!deepEqual(a[prop], b[prop])) { + return false; + } + } + return true; + } else { + return false; + } + } else { + return false; + } + } + function deepMatches(a, b) { + if (a === b) { + return true; + } else if (Array.isArray(a) && Array.isArray(b)) { + return a.every(function (aVal, i) { + return deepMatches(aVal, b[i]); + }); + } else if (a && b && canReflect.isPlainObject(a) && canReflect.isPlainObject(b)) { + for (var prop in a) { + if (!b.hasOwnProperty(prop)) { + return false; + } + if (!deepMatches(a[prop], b[prop])) { + return false; + } + } + return true; + } else { + return false; + } + } + function removeFixtureAndXHR(query) { + if (query.fixture || query.xhr || query.data) { + var clone = canReflect.serialize(query); + delete clone.fixture; + delete clone.xhr; + delete clone.data; + return clone; + } else { + return query; + } + } + function identityIntersection(v1, v2) { + return v1.value === v2.value ? v1 : set.EMPTY; + } + function identityDifference(v1, v2) { + return v1.value === v2.value ? set.EMPTY : v1; + } + function identityUnion(v1, v2) { + return v1.value === v2.value ? v1 : set.UNDEFINABLE; + } + var identityComparitor = { + intersection: identityIntersection, + difference: identityDifference, + union: identityUnion + }; + function makeComparatorType(compare) { + var Type = function () { + }; + var SetType = function (value) { + this.value = value; + }; + SetType.prototype.isMember = function (value, root, keys) { + return compare(this.value, value, root, keys); + }; + canReflect.assignSymbols(Type, { 'can.SetType': SetType }); + set.defineComparison(SetType, SetType, identityComparitor); + set.defineComparison(set.UNIVERSAL, SetType, { + difference: function () { + return set.UNDEFINABLE; + } + }); + return Type; + } + function quickEqual(queryA, queryB) { + var dataA = queryA.data, dataB = queryB.data; + if (dataA && dataB) { + if (!deepMatches(dataA, dataB)) { + return false; + } + } + var q1 = new QueryLogic.KeysAnd(removeFixtureAndXHR(queryA)), q2 = new QueryLogic.KeysAnd(removeFixtureAndXHR(queryB)); + return set.isEqual(q1, q2); + } + function quickSubset(queryA, queryB) { + return set.isSubset(new QueryLogic.KeysAnd(queryA), new QueryLogic.KeysAnd(queryB)); + } + var types = {}; + canReflect.eachKey({ + IsEmptyOrNull: function (a, b) { + if (a == null && canReflect.size(b) === 0) { + return true; + } else if (b == null && canReflect.size(a) === 0) { + return true; + } else { + return quickEqual(a, b); + } + }, + isEmptyOrSubset: function (a, b) { + if (a == null && canReflect.size(b) === 0) { + return true; + } else if (b == null && canReflect.size(a) === 0) { + return true; + } else { + return quickSubset(a, b); + } + }, + TemplateUrl: function (a, b) { + return !!dataFromUrl(a, b); + }, + StringIgnoreCase: function (a, b) { + return b && a ? a.toLowerCase() === b.toLowerCase() : b === a; + }, + Ignore: function () { + return true; + } + }, function (compare, name) { + types[name] = makeComparatorType(compare); + }); + var schema = { + identity: ['id'], + keys: { + url: types.TemplateUrl, + fixture: types.Ignore, + xhr: types.Ignore, + type: types.StringIgnoreCase, + method: types.StringIgnoreCase, + helpers: types.Ignore, + headers: types.IsEmptyOrNull, + data: types.IsEmptyOrSubset + } + }; + var query = new QueryLogic(schema); + module.exports = { + fixture: quickEqual, + request: function (requestData, fixtureData) { + return query.isMember({ filter: fixtureData }, requestData); + }, + matches: function (settings, fixture, exact) { + if (exact) { + return this.fixture(settings, fixture); + } else { + return this.request(settings, fixture); + } + }, + makeComparatorType: makeComparatorType + }; +}); +/*can-memory-store@1.0.3#make-simple-store*/ +define('can-memory-store@1.0.3#make-simple-store', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + function getItems(data) { + if (Array.isArray(data)) { + return data; + } else { + return data.data; + } + } + function indexOf(records, identity, queryLogic) { + var schema = canReflect.getSchema(queryLogic); + for (var i = 0; i < records.length; i++) { + if (identity === canReflect.getIdentity(records[i], schema)) { + return i; + } + } + return -1; + } + function makeSimpleStore(baseConnection) { + baseConnection.constructor = makeSimpleStore; + var behavior = Object.create(baseConnection); + return canReflect.assignMap(behavior, { + getRecordFromParams: function (record) { + var id = canReflect.getIdentity(record, this.queryLogic.schema); + return this.getRecord(id); + }, + log: function () { + this._log = true; + }, + getSets: function () { + return this.getQueries(); + }, + getQueries: function () { + return Promise.resolve(this.getQueriesSync()); + }, + getQueriesSync: function () { + return this.getQueryDataSync().map(function (queryData) { + return queryData.query; + }); + }, + getListData: function (query) { + query = query || {}; + var listData = this.getListDataSync(query); + if (listData) { + return Promise.resolve(listData); + } + return Promise.reject({ + title: 'no data', + status: '404', + detail: 'No data available for this query.\nAvailable queries: ' + JSON.stringify(this.getQueriesSync()) + }); + }, + getPaginatedListDataSync: function (superSetQueryData) { + var records = this.getAllRecords(); + var queryWithoutPagination = this.queryLogic.removePagination(superSetQueryData.query); + var matchingSuperRecordsNoPagination = this.queryLogic.filterMembersAndGetCount(queryWithoutPagination, {}, records); + var startIndex = indexOf(matchingSuperRecordsNoPagination.data, superSetQueryData.startIdentity, this.queryLogic); + var matchingSuperRecords = matchingSuperRecordsNoPagination.data.slice(startIndex, startIndex + this.queryLogic.count(superSetQueryData.query)); + return { + count: matchingSuperRecordsNoPagination.data.length, + data: matchingSuperRecords + }; + }, + getListDataSync: function (query) { + var queryData = this.getQueryDataSync(), superSetQueryData, isPaginated = this.queryLogic.isPaginated(query); + for (var i = 0; i < queryData.length; i++) { + var checkSet = queryData[i].query; + if (this.queryLogic.isSubset(query, checkSet)) { + superSetQueryData = queryData[i]; + } + } + var records = this.getAllRecords(); + if (isPaginated && this.queryLogic.isPaginated(superSetQueryData.query)) { + var result = this.getPaginatedListDataSync(superSetQueryData); + return this.queryLogic.filterMembersAndGetCount(query, superSetQueryData.query, result.data); + } + var matching = this.queryLogic.filterMembersAndGetCount(query, {}, records); + if (matching && matching.count) { + return matching; + } + if (superSetQueryData) { + return { + count: 0, + data: [] + }; + } + }, + updateListData: function (data, query) { + var queryData = this.getQueryDataSync(); + query = query || {}; + var clonedData = canReflect.serialize(data); + var records = getItems(clonedData); + this.updateRecordsSync(records); + var isPaginated = this.queryLogic.isPaginated(query); + var identity = records.length ? canReflect.getIdentity(records[0], this.queryLogic.schema) : undefined; + if (isPaginated) { + for (var i = 0; i < queryData.length; i++) { + var checkSet = queryData[i].query; + var union = this.queryLogic.union(checkSet, query); + if (this.queryLogic.isDefinedAndHasMembers(union)) { + var siblingRecords = this.getPaginatedListDataSync(queryData[i]); + var res = this.queryLogic.unionMembers(checkSet, query, siblingRecords.data, records); + identity = canReflect.getIdentity(res[0], this.queryLogic.schema); + queryData[i] = { + query: union, + startIdentity: identity + }; + this.updateQueryDataSync(queryData); + return Promise.resolve(); + } + } + queryData.push({ + query: query, + startIdentity: identity + }); + this.updateQueryDataSync(queryData); + return Promise.resolve(); + } + var allRecords = this.getAllRecords(); + var curretMatching = this.queryLogic.filterMembers(query, allRecords); + if (curretMatching.length) { + var toBeDeleted = new Map(); + curretMatching.forEach(function (record) { + toBeDeleted.set(canReflect.getIdentity(record, this.queryLogic.schema), record); + }, this); + records.forEach(function (record) { + toBeDeleted.delete(canReflect.getIdentity(record, this.queryLogic.schema)); + }, this); + this.destroyRecords(canReflect.toArray(toBeDeleted)); + } + var allQueries = this.getQueryDataSync(); + var notSubsets = allQueries.filter(function (existingQueryData) { + return !this.queryLogic.isSubset(existingQueryData.query, query); + }, this), superSets = notSubsets.filter(function (existingQueryData) { + return this.queryLogic.isSubset(query, existingQueryData.query); + }, this); + if (superSets.length) { + this.updateQueryDataSync(notSubsets); + } else { + this.updateQueryDataSync(notSubsets.concat([{ + query: query, + startIdentity: identity + }])); + } + return Promise.resolve(); + }, + getData: function (params) { + var id = canReflect.getIdentity(params, canReflect.getSchema(this.queryLogic)); + var res = this.getRecord(id); + if (res) { + return Promise.resolve(res); + } else { + return Promise.reject({ + title: 'no data', + status: '404', + detail: 'No record with matching identity (' + id + ').' + }); + } + }, + createData: function (record) { + this.updateRecordsSync([record]); + return Promise.resolve(canReflect.assignMap({}, this.getRecordFromParams(record))); + }, + updateData: function (record) { + if (this.errorOnMissingRecord && !this.getRecordFromParams(record)) { + var id = canReflect.getIdentity(record, this.queryLogic.schema); + return Promise.reject({ + title: 'no data', + status: '404', + detail: 'No record with matching identity (' + id + ').' + }); + } + this.updateRecordsSync([record]); + return Promise.resolve(canReflect.assignMap({}, this.getRecordFromParams(record))); + }, + destroyData: function (record) { + var id = canReflect.getIdentity(record, this.queryLogic.schema), savedRecord = this.getRecordFromParams(record); + if (this.errorOnMissingRecord && !savedRecord) { + return Promise.reject({ + title: 'no data', + status: '404', + detail: 'No record with matching identity (' + id + ').' + }); + } + this.destroyRecords([record]); + return Promise.resolve(canReflect.assignMap({}, savedRecord || record)); + } + }); + } + module.exports = makeSimpleStore; +}); +/*can-memory-store@1.0.3#can-memory-store*/ +define('can-memory-store@1.0.3#can-memory-store', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-namespace', + './make-simple-store' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + var namespace = require('can-namespace'); + var makeSimpleStore = require('./make-simple-store'); + module.exports = namespace.memoryStore = function memoryStore(baseConnection) { + baseConnection.constructor = memoryStore; + var behavior = Object.create(makeSimpleStore(baseConnection)); + canReflect.assignMap(behavior, { + clear: function () { + this._instances = {}; + this._queryData = []; + }, + _queryData: [], + updateQueryDataSync: function (queries) { + this._queryData = queries; + }, + getQueryDataSync: function () { + return this._queryData; + }, + _instances: {}, + getRecord: function (id) { + return this._instances[id]; + }, + getAllRecords: function () { + var records = []; + for (var id in this._instances) { + records.push(this._instances[id]); + } + return records; + }, + destroyRecords: function (records) { + canReflect.eachIndex(records, function (record) { + var id = canReflect.getIdentity(record, this.queryLogic.schema); + delete this._instances[id]; + }, this); + }, + updateRecordsSync: function (records) { + records.forEach(function (record) { + var id = canReflect.getIdentity(record, this.queryLogic.schema); + this._instances[id] = record; + }, this); + } + }); + return behavior; + }; +}); +/*can-fixture@3.1.7#store*/ +define('can-fixture@3.1.7#store', [ + 'require', + 'exports', + 'module', + 'can-query-logic', + 'can-reflect', + 'can-memory-store' +], function (require, exports, module) { + var QueryLogic = require('can-query-logic'); + var canReflect = require('can-reflect'); + var memoryStore = require('can-memory-store'); + var connectToConnection = function (method, convert) { + return function (req, res) { + this.connection[method](convert.call(this, req.data)).then(function (data) { + res(data); + }, function (err) { + res(parseInt(err.status, 10), err); + }); + }; + }; + var makeMakeItems = function (baseItems, idProp) { + return function () { + var items = [], maxId = 0, idType = 'number'; + baseItems.forEach(function (item) { + items.push(canReflect.serialize(item)); + var type = typeof item[idProp]; + if (type === 'number') { + maxId = Math.max(item[idProp], maxId); + } else { + idType = type; + } + }); + return { + maxId: maxId, + items: items, + idType: idType + }; + }; + }; + var stringToAny = function (str) { + switch (str) { + case 'NaN': + case 'Infinity': + return +str; + case 'null': + return null; + case 'undefined': + return undefined; + case 'true': + case 'false': + return str === 'true'; + default: + var val = +str; + if (!isNaN(val)) { + return val; + } else { + return str; + } + } + }; + var Store = function (connection, makeItems, idProp) { + var schema = connection.queryLogic.schema; + var identityKey = schema.identity[0], keys = schema.keys; + if (!keys || !keys[identityKey]) { + console.warn('No type specified for identity key. Going to convert strings to reasonable type.'); + } + this.connection = connection; + this.makeItems = makeItems; + this.idProp = idProp; + this.reset(); + for (var method in Store.prototype) { + this[method] = this[method].bind(this); + } + }; + var doNotConvert = function (v) { + return v; + }; + function typeConvert(data) { + var schema = this.connection.queryLogic.schema; + var idType = this.idType; + var identityKey = schema.identity[0], keys = schema.keys; + if (!keys || !keys[identityKey]) { + keys = {}; + keys[identityKey] = function (value) { + if (idType === 'string') { + return '' + value; + } else { + return typeof value === 'string' ? stringToAny(value) : value; + } + }; + } + var copy = {}; + canReflect.eachKey(data, function (value, key) { + if (keys[key]) { + copy[key] = canReflect.serialize(canReflect.convert(value, keys[key])); + } else { + copy[key] = value; + } + }); + return copy; + } + canReflect.assignMap(Store.prototype, { + getListData: connectToConnection('getListData', doNotConvert), + getData: connectToConnection('getData', typeConvert), + createData: function (req, res) { + var idProp = this.idProp; + req.data[idProp] = ++this.maxId; + this.connection.createData(typeConvert.call(this, req.data)).then(function (data) { + res(data); + }, function (err) { + res(403, err); + }); + }, + createInstance: function (record) { + var idProp = this.idProp; + if (!(idProp in record)) { + record[idProp] = ++this.maxId; + } + return this.connection.createData(record); + }, + updateData: connectToConnection('updateData', typeConvert), + updateInstance: function (record) { + return this.connection.updateData(record); + }, + destroyInstance: function (record) { + return this.connection.destroyData(record); + }, + destroyData: connectToConnection('destroyData', typeConvert), + reset: function (newItems) { + if (newItems) { + this.makeItems = makeMakeItems(newItems, this.idProp); + } + var itemData = this.makeItems(); + this.maxId = itemData.maxId; + this.idType = itemData.idType; + this.connection.updateListData(itemData.items, {}); + }, + get: function (params) { + var id = this.connection.queryLogic.memberIdentity(params); + return this.connection.getRecord(id); + }, + getList: function (set) { + return this.connection.getListDataSync(set); + } + }); + function looksLikeAQueryLogic(obj) { + return obj && 'identityKeys' in obj; + } + Store.make = function (count, make, queryLogic) { + var makeItems, idProp; + if (typeof count === 'number') { + if (!queryLogic) { + queryLogic = new QueryLogic({}); + } else if (!looksLikeAQueryLogic(queryLogic)) { + queryLogic = new QueryLogic(queryLogic); + } + idProp = queryLogic.identityKeys()[0] || 'id'; + makeItems = function () { + var items = []; + var maxId = 0; + for (var i = 0; i < count; i++) { + var item = make(i, items); + if (!item[idProp]) { + item[idProp] = i; + } + maxId = Math.max(item[idProp], maxId); + items.push(item); + } + return { + maxId: maxId, + items: items + }; + }; + } else if (Array.isArray(count)) { + queryLogic = make; + if (!queryLogic) { + queryLogic = new QueryLogic({}); + } else if (!looksLikeAQueryLogic(queryLogic)) { + queryLogic = new QueryLogic(queryLogic); + } + idProp = queryLogic.identityKeys()[0] || 'id'; + makeItems = makeMakeItems(count, idProp); + } + var connection = memoryStore({ + queryLogic: queryLogic, + errorOnMissingRecord: true + }); + return new Store(connection, makeItems, idProp); + }; + module.exports = Store; +}); +/*can-fixture@3.1.7#core*/ +define('can-fixture@3.1.7#core', [ + 'require', + 'exports', + 'module', + 'can-key/sub/sub', + 'can-reflect', + './matches', + 'can-log', + 'can-log/dev/dev', + './data-from-url', + './store' +], function (require, exports, module) { + 'use strict'; + var sub = require('can-key/sub/sub'); + var canReflect = require('can-reflect'); + var matches = require('./matches'); + var canLog = require('can-log'); + var canDev = require('can-log/dev/dev'); + var dataFromUrl = require('./data-from-url'); + require('./store'); + var fixtures = []; + exports.fixtures = fixtures; + function isStoreLike(fixture) { + return fixture && (fixture.getData || fixture.getListData); + } + var methodMapping = { + item: { + 'GET': 'getData', + 'PUT': 'updateData', + 'DELETE': 'destroyData' + }, + list: { + 'GET': 'getListData', + 'POST': 'createData' + } + }; + function getMethodAndPath(route) { + var matches = route.match(/(GET|POST|PUT|DELETE|PATCH) (.+)/i); + if (!matches) { + return [ + undefined, + route + ]; + } + var method = matches[1]; + var path = matches[2]; + return [ + method, + path + ]; + } + function inferIdProp(url) { + var wrappedInBraces = /\{(.*)\}/; + var matches = url.match(wrappedInBraces); + var isUniqueMatch = matches && matches.length === 2; + if (isUniqueMatch) { + return matches[1]; + } + } + function getItemAndListUrls(url, idProp) { + idProp = idProp || inferIdProp(url); + if (!idProp) { + return [ + undefined, + url + ]; + } + var itemRegex = new RegExp('\\/\\{' + idProp + '\\}.*'); + var rootIsItemUrl = itemRegex.test(url); + var listUrl = rootIsItemUrl ? url.replace(itemRegex, '') : url; + var itemUrl = rootIsItemUrl ? url : url.trim() + '/{' + idProp + '}'; + return [ + itemUrl, + listUrl + ]; + } + function addStoreFixture(root, store) { + var settings = {}; + var typeAndUrl = getMethodAndPath(root); + var type = typeAndUrl[0]; + var url = typeAndUrl[1]; + var itemAndListUrls = getItemAndListUrls(url, store.idProp); + var itemUrl = itemAndListUrls[0]; + var listUrl = itemAndListUrls[1]; + if (type) { + var warning = ['fixture("' + root + '", fixture) must use a store method, not a store directly.']; + if (itemUrl) { + var itemAction = methodMapping.item[type]; + if (itemAction) { + settings[type + ' ' + itemUrl] = store[itemAction]; + var itemWarning = 'Replace with fixture("' + type + ' ' + itemUrl + '", fixture.' + itemAction + ') for items.'; + warning.push(itemWarning); + } + } + var listAction = methodMapping.list[type]; + if (listAction) { + settings[type + ' ' + listUrl] = store[listAction]; + var listWarning = 'Replace with fixture("' + type + ' ' + listUrl + '", fixture.' + listAction + ') for lists.'; + warning.push(listWarning); + } + var message = warning.join(' '); + canDev.warn(message); + } else { + var itemMapping = methodMapping.item; + for (var itemMethod in itemMapping) { + var storeItemMethod = itemMapping[itemMethod]; + settings[itemMethod + ' ' + itemUrl] = store[storeItemMethod]; + } + var listMapping = methodMapping.list; + for (var listMethod in listMapping) { + var storeListMethod = listMapping[listMethod]; + settings[listMethod + ' ' + listUrl] = store[storeListMethod]; + } + } + return settings; + } + function getSettingsFromString(route) { + var typeAndUrl = getMethodAndPath(route); + var type = typeAndUrl[0]; + var url = typeAndUrl[1]; + if (type) { + return { + type: type, + url: url + }; + } + return { url: url }; + } + function upsertFixture(fixtureList, settings, fixture) { + var index = exports.index(settings, true); + var oldFixture; + if (index > -1) { + oldFixture = fixtures.splice(index, 1); + } + if (fixture == null) { + return oldFixture; + } + if (typeof fixture === 'object') { + var data = fixture; + fixture = function () { + return data; + }; + } + settings.fixture = fixture; + fixtures.unshift(settings); + return oldFixture; + } + exports.add = function (settings, fixture) { + if (fixture === undefined) { + var oldFixtures = []; + if (Array.isArray(settings)) { + canReflect.eachIndex(settings, function (ajaxSettings) { + var fixture = ajaxSettings.fixture; + ajaxSettings = canReflect.assignMap({}, ajaxSettings); + delete ajaxSettings.fixture; + return exports.add(ajaxSettings, fixture); + }); + } else { + canReflect.eachKey(settings, function (fixture, url) { + oldFixtures = oldFixtures.concat(exports.add(url, fixture)); + }); + return oldFixtures; + } + } + if (isStoreLike(fixture)) { + settings = addStoreFixture(settings, fixture); + return exports.add(settings); + } + if (typeof settings === 'string') { + settings = getSettingsFromString(settings); + } + return upsertFixture(fixtures, settings, fixture); + }; + var $fixture = exports.add; + $fixture.on = true; + $fixture.delay = 10; + function FixtureResponse(fixture, response) { + this.statusCode = response[0]; + this.responseBody = response[1]; + this.headers = response[2]; + this.statusText = response[3]; + this.fixture = fixture; + } + exports.callDynamicFixture = function (xhrSettings, fixtureSettings, cb) { + xhrSettings.data = fixtureSettings.data; + var response = function () { + var res = exports.extractResponse.apply(xhrSettings, arguments); + return cb.apply(this, res); + }; + var callFixture = function () { + var result = fixtureSettings.fixture(xhrSettings, response, xhrSettings.headers, fixtureSettings); + if (canReflect.isPromise(result)) { + result.then(function (result) { + if (result !== undefined) { + response(200, result); + } + }); + } else { + if (result !== undefined) { + response(200, result); + } + } + }; + if (!xhrSettings.async) { + callFixture(); + return null; + } else { + return setTimeout(callFixture, $fixture.delay); + } + }; + exports.index = function (settings, exact) { + for (var i = 0; i < fixtures.length; i++) { + if (matches.matches(settings, fixtures[i], exact)) { + return i; + } + } + return -1; + }; + exports.get = function (xhrSettings) { + if (!$fixture.on) { + return; + } + var index = exports.index(xhrSettings, true); + if (index === -1) { + index = exports.index(xhrSettings, false); + } + var fixtureSettings = index >= 0 ? canReflect.assignMap({}, fixtures[index]) : undefined; + if (fixtureSettings) { + var url = fixtureSettings.fixture, data = dataFromUrl(fixtureSettings.url, xhrSettings.url); + if (typeof fixtureSettings.fixture === 'string') { + if (data) { + url = sub(url, data); + } + fixtureSettings.url = url; + fixtureSettings.data = null; + fixtureSettings.type = 'GET'; + if (!fixtureSettings.error) { + fixtureSettings.error = function (xhr, error, message) { + throw 'fixtures.js Error ' + error + ' ' + message; + }; + } + } else if (canReflect.isPlainObject(xhrSettings.data) || xhrSettings.data == null) { + var xhrData = canReflect.assignMap({}, xhrSettings.data || {}); + fixtureSettings.data = canReflect.assignMap(xhrData, data); + } else { + fixtureSettings.data = xhrSettings.data; + } + } + return fixtureSettings; + }; + exports.matches = matches; + exports.extractResponse = function (status, response, headers, statusText) { + if (typeof status !== 'number') { + headers = response; + response = status; + status = 200; + } + if (typeof headers === 'string') { + statusText = headers; + headers = {}; + } + return [ + status, + response, + headers, + statusText + ]; + }; +}); +/*can-fixture@3.1.7#xhr*/ +define('can-fixture@3.1.7#xhr', [ + 'require', + 'exports', + 'module', + './core', + 'can-deparam', + 'can-reflect', + 'can-log' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var fixtureCore = require('./core'); + var deparam = require('can-deparam'); + var canReflect = require('can-reflect'); + var canLog = require('can-log'); + var XHR = XMLHttpRequest, GLOBAL = typeof global !== 'undefined' ? global : window; + var props = [ + 'type', + 'url', + 'async', + 'response', + 'responseText', + 'responseType', + 'responseXML', + 'responseURL', + 'status', + 'statusText', + 'readyState' + ]; + var events = [ + 'abort', + 'error', + 'load', + 'loadend', + 'loadstart', + 'progress', + 'readystatechange' + ]; + (function () { + var x = new XHR(); + for (var prop in x) { + if (prop.indexOf('on') === 0) { + if (events.indexOf(prop.substr(2)) === -1) { + events.push(prop.substr(2)); + } + } else if (props.indexOf(prop) === -1 && typeof x[prop] !== 'function') { + props.push(prop); + } + } + }()); + function callEvents(xhr, ev) { + var evs = xhr.__events[ev] || [], fn; + for (var i = 0, len = evs.length; i < len; i++) { + fn = evs[i]; + fn.call(xhr); + } + } + function defineNonEnumerable(obj, prop, value) { + Object.defineProperty(obj, prop, { + enumerable: false, + configurable: true, + writable: true, + value: value + }); + } + GLOBAL.XMLHttpRequest = function () { + var mockXHR = this; + var realXHR = new XHR(); + defineNonEnumerable(this, '_xhr', realXHR); + defineNonEnumerable(this, '_requestHeaders', {}); + defineNonEnumerable(this, '__events', {}); + events.forEach(function (eventName) { + realXHR['on' + eventName] = function () { + callEvents(mockXHR, eventName); + if (mockXHR['on' + eventName]) { + return mockXHR['on' + eventName].apply(mockXHR, arguments); + } + }; + }); + this.onload = null; + }; + GLOBAL.XMLHttpRequest._XHR = XHR; + canReflect.assignMap(XMLHttpRequest.prototype, { + setRequestHeader: function (name, value) { + this._requestHeaders[name] = value; + }, + open: function (type, url, async) { + this.type = type; + this.url = url; + this.async = async === false ? false : true; + }, + getAllResponseHeaders: function () { + return this._xhr.getAllResponseHeaders.apply(this._xhr, arguments); + }, + addEventListener: function (ev, fn) { + var evs = this.__events[ev] = this.__events[ev] || []; + evs.push(fn); + }, + removeEventListener: function (ev, fn) { + var evs = this.__events[ev] = this.__events[ev] || []; + var idx = evs.indexOf(fn); + if (idx >= 0) { + evs.splice(idx, 1); + } + }, + setDisableHeaderCheck: function (val) { + this._disableHeaderCheck = !!val; + }, + getResponseHeader: function (key) { + return this._xhr.getResponseHeader(key); + }, + abort: function () { + var xhr = this._xhr; + if (this.timeoutId !== undefined) { + clearTimeout(this.timeoutId); + xhr.open(this.type, this.url, this.async === false ? false : true); + xhr.send(); + } + return xhr.abort(); + }, + send: function (data) { + var type = this.type.toLowerCase() || 'get'; + var xhrSettings = { + url: this.url, + data: data, + headers: this._requestHeaders, + type: type, + method: type, + async: this.async, + xhr: this + }; + if (!xhrSettings.data && xhrSettings.type === 'get' || xhrSettings.type === 'delete') { + xhrSettings.data = deparam(xhrSettings.url.split('?')[1]); + xhrSettings.url = xhrSettings.url.split('?')[0]; + } + if (typeof xhrSettings.data === 'string') { + try { + xhrSettings.data = JSON.parse(xhrSettings.data); + } catch (e) { + xhrSettings.data = deparam(xhrSettings.data); + } + } + var fixtureSettings = fixtureCore.get(xhrSettings); + var mockXHR = this; + if (fixtureSettings && typeof fixtureSettings.fixture === 'function') { + this.timeoutId = fixtureCore.callDynamicFixture(xhrSettings, fixtureSettings, function (status, body, headers, statusText) { + body = typeof body === 'string' ? body : JSON.stringify(body); + mockXHR._xhr = { + open: function () { + }, + send: function () { + }, + abort: function () { + }, + getResponseHeader: function () { + } + }; + canReflect.assignMap(mockXHR, { + readyState: 4, + status: status + }); + var success = status >= 200 && status < 300 || status === 304; + if (success) { + canReflect.assignMap(mockXHR, { + statusText: statusText || 'OK', + responseText: body + }); + } else { + canReflect.assignMap(mockXHR, { + statusText: statusText || 'error', + responseText: body + }); + } + mockXHR.getAllResponseHeaders = function () { + var ret = []; + canReflect.eachKey(headers || {}, function (value, name) { + Array.prototype.push.apply(ret, [ + name, + ': ', + value, + '\r\n' + ]); + }); + return ret.join(''); + }; + if (mockXHR.onreadystatechange) { + mockXHR.onreadystatechange({ target: mockXHR }); + } + callEvents(mockXHR, 'progress'); + if (mockXHR.onprogress) { + mockXHR.onprogress(); + } + callEvents(mockXHR, 'load'); + if (mockXHR.onload) { + mockXHR.onload(); + } + callEvents(mockXHR, 'loadend'); + if (mockXHR.onloadend) { + mockXHR.onloadend(); + } + }); + return; + } + var makeRequest = function () { + mockXHR._xhr.open(mockXHR._xhr.type, mockXHR._xhr.url, mockXHR._xhr.async); + if (mockXHR._requestHeaders) { + Object.keys(mockXHR._requestHeaders).forEach(function (key) { + mockXHR._xhr.setRequestHeader(key, mockXHR._requestHeaders[key]); + }); + } + return mockXHR._xhr.send(data); + }; + if (fixtureSettings && typeof fixtureSettings.fixture === 'number') { + canLog.log('can-fixture: ' + xhrSettings.url + ' => delay ' + fixtureSettings.fixture + 'ms'); + this.timeoutId = setTimeout(makeRequest, fixtureSettings.fixture); + return; + } + if (fixtureSettings) { + canLog.log('can-fixture: ' + xhrSettings.url + ' => ' + fixtureSettings.url); + canReflect.assignMap(mockXHR, fixtureSettings); + } + return makeRequest(); + } + }); + props.forEach(function (prop) { + Object.defineProperty(XMLHttpRequest.prototype, prop, { + get: function () { + return this._xhr[prop]; + }, + set: function (newVal) { + try { + this._xhr[prop] = newVal; + } catch (e) { + } + } + }); + }); + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-fixture@3.1.7#fixture*/ +define('can-fixture@3.1.7#fixture', [ + 'require', + 'exports', + 'module', + './core', + './store', + './xhr', + 'can-reflect', + 'can-log/dev/dev', + 'can-namespace' +], function (require, exports, module) { + (function (global, require, exports, module) { + 'use strict'; + var core = require('./core'); + var fixture = core.add; + var Store = require('./store'); + require('./xhr'); + var canReflect = require('can-reflect'); + var canDev = require('can-log/dev/dev'); + var ns = require('can-namespace'); + var noop = function () { + }; + canReflect.assignMap(fixture, { + rand: function randomize(arr, min, max) { + if (typeof arr === 'number') { + if (typeof min === 'number') { + return arr + Math.floor(Math.random() * (min - arr + 1)); + } else { + return Math.floor(Math.random() * (arr + 1)); + } + } + var choices = arr.slice(0); + if (min === undefined) { + min = 1; + max = choices.length; + } else if (max === undefined) { + max = min; + } + var result = []; + var selectedCount = min + Math.round(randomize(max - min)); + for (var i = 0; i < selectedCount; i++) { + var selectedIndex = randomize(choices.length - 1), selected = choices.splice(selectedIndex, 1)[0]; + result.push(selected); + } + return result; + }, + xhr: function (xhr) { + return canReflect.assignMap({}, { + abort: noop, + getAllResponseHeaders: function () { + return ''; + }, + getResponseHeader: function () { + return ''; + }, + open: noop, + overrideMimeType: noop, + readyState: 4, + responseText: '', + responseXML: null, + send: noop, + setRequestHeader: noop, + status: 200, + statusText: 'OK' + }, xhr); + }, + store: Store.make, + fixtures: core.fixtures + }); + if (typeof window !== 'undefined' && typeof require.resolve !== 'function') { + window.fixture = function () { + canDev.warn('You are using the global fixture. Make sure you import can-fixture.'); + return fixture.apply(this, arguments); + }; + } + module.exports = ns.fixture = fixture; + }(function () { + return this; + }(), require, exports, module)); +}); +/*can-connect@4.0.2#behavior*/ +define('can-connect@4.0.2#behavior', function (require, exports, module) { + 'use strict'; + var behaviorsMap = {}; + function behavior(name, behavior) { + if (typeof name !== 'string') { + behavior = name; + name = undefined; + } + var behaviorMixin = function (base) { + var Behavior = function () { + }; + Object.defineProperty(Behavior, 'name', { + value: name, + configurable: true + }); + Behavior.prototype = base; + var newBehavior = new Behavior(); + var res = typeof behavior === 'function' ? behavior.apply(newBehavior, arguments) : behavior; + for (var prop in res) { + if (res.hasOwnProperty(prop)) { + Object.defineProperty(newBehavior, prop, Object.getOwnPropertyDescriptor(res, prop)); + } else { + newBehavior[prop] = res[prop]; + } + } + newBehavior.__behaviorName = name; + return newBehavior; + }; + if (name) { + behaviorMixin.behaviorName = name; + behaviorsMap[name] = behaviorMixin; + } + behaviorMixin.isBehavior = true; + return behaviorMixin; + } + behavior.map = behaviorsMap; + module.exports = behavior; +}); +/*can-connect@4.0.2#connect*/ +define('can-connect@4.0.2#connect', [ + 'require', + 'exports', + 'module', + './behavior' +], function (require, exports, module) { + var behavior = require('./behavior'); + var connect = function (behaviors, options) { + behaviors = behaviors.map(function (behavior, index) { + var sortedIndex = -1; + if (typeof behavior === 'string') { + sortedIndex = connect.order.indexOf(behavior); + behavior = behavior.map[behavior]; + } else if (behavior.isBehavior) { + sortedIndex = connect.order.indexOf(behavior.behaviorName); + } else { + behavior = connect.behavior(behavior); + } + return { + originalIndex: index, + sortedIndex: sortedIndex, + behavior: behavior + }; + }); + behaviors.sort(function (b1, b2) { + if (~b1.sortedIndex && ~b2.sortedIndex) { + return b1.sortedIndex - b2.sortedIndex; + } + return b1.originalIndex - b2.originalIndex; + }); + behaviors = behaviors.map(function (b) { + return b.behavior; + }); + var behavior = connect.base(connect.behavior('options', function () { + return options; + })()); + behaviors.forEach(function (behave) { + behavior = behave(behavior); + }); + if (behavior.init) { + behavior.init(); + } + return behavior; + }; + connect.order = [ + 'data/localstorage-cache', + 'data/url', + 'data/parse', + 'cache-requests', + 'data/combine-requests', + 'constructor', + 'constructor/store', + 'can/map', + 'can/ref', + 'fall-through-cache', + 'data/worker', + 'real-time', + 'data/callbacks-cache', + 'data/callbacks', + 'constructor/callbacks-once' + ]; + connect.behavior = behavior; + module.exports = connect; +}); +/*can-connect@4.0.2#base/base*/ +define('can-connect@4.0.2#base/base', [ + 'require', + 'exports', + 'module', + '../behavior', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var behavior = require('../behavior'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + module.exports = behavior('base', function (baseConnection) { + var setQueryLogic; + return { + id: function (instance) { + if (this.queryLogic) { + return canReflect.getIdentity(instance, this.queryLogic.schema); + } else if (this.idProp) { + return instance[this.idProp]; + } else { + throw new Error('can-connect/base/base - Please add a queryLogic option.'); + } + }, + listQuery: function (list) { + return list[this.listQueryProp]; + }, + listQueryProp: canSymbol.for('can.listQuery'), + init: function () { + }, + get queryLogic() { + if (setQueryLogic) { + return setQueryLogic; + } else if (baseConnection.queryLogic) { + return baseConnection.queryLogic; + } else if (baseConnection.algebra) { + return baseConnection.algebra; + } + }, + set queryLogic(newVal) { + setQueryLogic = newVal; + } + }; + }); +}); +/*can-connect@4.0.2#can-connect*/ +define('can-connect@4.0.2#can-connect', [ + 'require', + 'exports', + 'module', + './connect', + './base/base', + 'can-namespace' +], function (require, exports, module) { + 'use strict'; + var connect = require('./connect'); + var base = require('./base/base'); + var ns = require('can-namespace'); + connect.base = base; + module.exports = ns.connect = connect; +}); +/*can-connect@4.0.2#helpers/weak-reference-map*/ +define('can-connect@4.0.2#helpers/weak-reference-map', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var assign = require('can-reflect').assignMap; + var WeakReferenceMap = function () { + this.set = {}; + }; + assign(WeakReferenceMap.prototype, { + has: function (key) { + return !!this.set[key]; + }, + addReference: function (key, item, referenceCount) { + if (typeof key === 'undefined') { + throw new Error('can-connect: You must provide a key to store a value in a WeakReferenceMap'); + } + var data = this.set[key]; + if (!data) { + data = this.set[key] = { + item: item, + referenceCount: 0, + key: key + }; + } + data.referenceCount += referenceCount || 1; + }, + referenceCount: function (key) { + var data = this.set[key]; + if (data) { + return data.referenceCount; + } + }, + deleteReference: function (key) { + var data = this.set[key]; + if (data) { + data.referenceCount--; + if (data.referenceCount === 0) { + delete this.set[key]; + } + } + }, + get: function (key) { + var data = this.set[key]; + if (data) { + return data.item; + } + }, + forEach: function (cb) { + for (var id in this.set) { + cb(this.set[id].item, id); + } + } + }); + module.exports = WeakReferenceMap; +}); +/*can-diff@1.5.0#update-deep-except-identity/update-deep-except-identity*/ +define('can-diff@1.5.0#update-deep-except-identity/update-deep-except-identity', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + module.exports = function updateExceptIdentity(obj, data, schema) { + if (!schema) { + schema = canReflect.getSchema(obj); + } + if (!schema) { + throw new Error('can-diff/update-except-id is unable to update without a schema.'); + } + schema.identity.forEach(function (key) { + var id = canReflect.getKeyValue(obj, key); + if (id !== undefined) { + canReflect.setKeyValue(data, key, id); + } + }); + canReflect.updateDeep(obj, data); + }; +}); +/*can-connect@4.0.2#helpers/id-merge*/ +define('can-connect@4.0.2#helpers/id-merge', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-diff/list/list' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var diffList = require('can-diff/list/list'); + module.exports = function (list, update, id, make) { + var patches = diffList(list, update, function (a, b) { + return id(a) === id(b); + }); + patches.forEach(function (patch) { + canReflect.splice(list, patch.index, patch.deleteCount, patch.insert.map(make)); + }); + }; +}); +/*can-connect@4.0.2#constructor/constructor*/ +define('can-connect@4.0.2#constructor/constructor', [ + 'require', + 'exports', + 'module', + 'can-reflect', + '../helpers/weak-reference-map', + 'can-diff/update-deep-except-identity/update-deep-except-identity', + '../helpers/id-merge', + '../behavior' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var makeArray = canReflect.toArray; + var assign = canReflect.assignMap; + var WeakReferenceMap = require('../helpers/weak-reference-map'); + var updateDeepExceptIdentity = require('can-diff/update-deep-except-identity/update-deep-except-identity'); + var idMerge = require('../helpers/id-merge'); + var behavior = require('../behavior'); + module.exports = behavior('constructor', function (baseConnection) { + var behavior = { + cidStore: new WeakReferenceMap(), + _cid: 0, + get: function (params) { + var self = this; + return this.getData(params).then(function (data) { + return self.hydrateInstance(data); + }); + }, + getList: function (set) { + set = set || {}; + var self = this; + return this.getListData(set).then(function (data) { + return self.hydrateList(data, set); + }); + }, + hydrateList: function (listData, set) { + if (Array.isArray(listData)) { + listData = { data: listData }; + } + var arr = []; + for (var i = 0; i < listData.data.length; i++) { + arr.push(this.hydrateInstance(listData.data[i])); + } + listData.data = arr; + if (this.list) { + return this.list(listData, set); + } else { + var list = listData.data.slice(0); + list[this.listQueryProp || '__listQuery'] = set; + copyMetadata(listData, list); + return list; + } + }, + hydrateInstance: function (props) { + if (this.instance) { + return this.instance(props); + } else { + return assign({}, props); + } + }, + save: function (instance) { + var serialized = this.serializeInstance(instance); + var id = this.id(instance); + var self = this; + if (id === undefined) { + var cid = this._cid++; + this.cidStore.addReference(cid, instance); + return this.createData(serialized, cid).then(function (data) { + if (data !== undefined) { + self.createdInstance(instance, data); + } + self.cidStore.deleteReference(cid, instance); + return instance; + }); + } else { + return this.updateData(serialized).then(function (data) { + if (data !== undefined) { + self.updatedInstance(instance, data); + } + return instance; + }); + } + }, + destroy: function (instance) { + var serialized = this.serializeInstance(instance), self = this, id = this.id(instance); + if (id !== undefined) { + return this.destroyData(serialized).then(function (data) { + if (data !== undefined) { + self.destroyedInstance(instance, data); + } + return instance; + }); + } else { + this.destroyedInstance(instance, {}); + return Promise.resolve(instance); + } + }, + createdInstance: function (instance, props) { + assign(instance, props); + }, + updatedInstance: function (instance, data) { + updateDeepExceptIdentity(instance, data, this.queryLogic.schema); + }, + updatedList: function (list, listData, set) { + var instanceList = []; + for (var i = 0; i < listData.data.length; i++) { + instanceList.push(this.hydrateInstance(listData.data[i])); + } + idMerge(list, instanceList, this.id.bind(this), this.hydrateInstance.bind(this)); + copyMetadata(listData, list); + }, + destroyedInstance: function (instance, data) { + updateDeepExceptIdentity(instance, data, this.queryLogic.schema); + }, + serializeInstance: function (instance) { + return assign({}, instance); + }, + serializeList: function (list) { + var self = this; + return makeArray(list).map(function (instance) { + return self.serializeInstance(instance); + }); + }, + isNew: function (instance) { + var id = this.id(instance); + return !(id || id === 0); + } + }; + return behavior; + }); + function copyMetadata(listData, list) { + for (var prop in listData) { + if (prop !== 'data') { + if (typeof list.set === 'function') { + list.set(prop, listData[prop]); + } else if (typeof list.attr === 'function') { + list.attr(prop, listData[prop]); + } else { + list[prop] = listData[prop]; + } + } + } + } +}); +/*can-diff@1.5.0#assign-deep-except-identity/assign-deep-except-identity*/ +define('can-diff@1.5.0#assign-deep-except-identity/assign-deep-except-identity', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + module.exports = function assignExceptIdentity(obj, data, schema) { + if (!schema) { + schema = canReflect.getSchema(obj); + } + if (!schema) { + throw new Error('can-diff/update-except-id is unable to update without a schema.'); + } + schema.identity.forEach(function (key) { + var id = canReflect.getKeyValue(obj, key); + if (id !== undefined) { + canReflect.setKeyValue(data, key, id); + } + }); + canReflect.assignDeep(obj, data); + }; +}); +/*can-diff@1.5.0#merge-deep/merge-deep*/ +define('can-diff@1.5.0#merge-deep/merge-deep', [ + 'require', + 'exports', + 'module', + 'can-reflect', + '../list/list' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var diffList = require('../list/list'); + function smartMerge(instance, props) { + props = canReflect.serialize(props); + if (canReflect.isMoreListLikeThanMapLike(instance)) { + mergeList(instance, props); + } else { + mergeMap(instance, props); + } + return instance; + } + function mergeMap(instance, data) { + canReflect.eachKey(instance, function (value, prop) { + if (!canReflect.hasKey(data, prop)) { + canReflect.deleteKeyValue(instance, prop); + return; + } + var newValue = canReflect.getKeyValue(data, prop); + canReflect.deleteKeyValue(data, prop); + if (canReflect.isPrimitive(value)) { + canReflect.setKeyValue(instance, prop, newValue); + return; + } + var newValueIsList = Array.isArray(newValue), currentValueIsList = canReflect.isMoreListLikeThanMapLike(value); + if (currentValueIsList && newValueIsList) { + mergeList(value, newValue); + } else if (!newValueIsList && !currentValueIsList && canReflect.isMapLike(value) && canReflect.isPlainObject(newValue)) { + var schema = canReflect.getSchema(value); + if (schema && schema.identity && schema.identity.length) { + var id = canReflect.getIdentity(value, schema); + if (id != null && id === canReflect.getIdentity(newValue, schema)) { + mergeMap(value, newValue); + return; + } + } + canReflect.setKeyValue(instance, prop, canReflect.new(value.constructor, newValue)); + } else { + canReflect.setKeyValue(instance, prop, newValue); + } + }); + canReflect.eachKey(data, function (value, prop) { + canReflect.setKeyValue(instance, prop, value); + }); + } + function mergeList(list, data) { + var ItemType, itemSchema; + var listSchema = canReflect.getSchema(list); + if (listSchema) { + ItemType = listSchema.values; + } + if (ItemType) { + itemSchema = canReflect.getSchema(ItemType); + } + if (!itemSchema && canReflect.size(list) > 0) { + itemSchema = canReflect.getSchema(canReflect.getKeyValue(list, 0)); + } + var identity; + if (itemSchema && itemSchema.identity && itemSchema.identity.length) { + identity = function (a, b) { + var aId = canReflect.getIdentity(a, itemSchema), bId = canReflect.getIdentity(b, itemSchema); + var eq = aId === bId; + if (eq) { + mergeMap(a, b); + } + return eq; + }; + } else { + identity = function (a, b) { + var eq = a === b; + if (eq) { + if (!canReflect.isPrimitive(a)) { + mergeMap(a, b); + } + } + return eq; + }; + } + var patches = diffList(list, data, identity); + var hydrate = ItemType ? canReflect.new.bind(canReflect, ItemType) : function (v) { + return v; + }; + if (!patches.length) { + return list; + } + patches.forEach(function (patch) { + applyPatch(list, patch, hydrate); + }); + } + function applyPatch(list, patch, makeInstance) { + var insert = makeInstance && patch.insert.map(function (val) { + return makeInstance(val); + }) || patch.insert; + var args = [ + patch.index, + patch.deleteCount + ].concat(insert); + list.splice.apply(list, args); + return list; + } + smartMerge.applyPatch = applyPatch; + module.exports = smartMerge; +}); +/*can-connect@4.0.2#helpers/validate*/ +define('can-connect@4.0.2#helpers/validate', [ + 'require', + 'exports', + 'module', + 'can-validate-interface' +], function (require, exports, module) { + 'use strict'; + var makeInterfaceValidator = require('can-validate-interface'); + module.exports = function (extendingBehavior, interfaces) { + var validatedBehaviour = validateArgumentInterface(extendingBehavior, 0, interfaces, function (errors, baseBehavior) { + throw new BehaviorInterfaceError(baseBehavior, extendingBehavior, errors); + }); + Object.keys(extendingBehavior).forEach(function (k) { + validatedBehaviour[k] = extendingBehavior[k]; + }); + validatedBehaviour.__interfaces = interfaces; + return validatedBehaviour; + }; + function validateArgumentInterface(func, argIndex, interfaces, errorHandler) { + return function () { + var errors = makeInterfaceValidator(interfaces)(arguments[argIndex]); + if (errors && errorHandler) { + errorHandler(errors, arguments[argIndex]); + } + return func.apply(this, arguments); + }; + } + function BehaviorInterfaceError(baseBehavior, extendingBehavior, missingProps) { + var extendingName = extendingBehavior.behaviorName || 'anonymous behavior', baseName = baseBehavior.__behaviorName || 'anonymous behavior', message = 'can-connect: Extending behavior "' + extendingName + '" found base behavior "' + baseName + '" was missing required properties: ' + JSON.stringify(missingProps.related), instance = new Error(message); + if (Object.setPrototypeOf) { + Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); + } + return instance; + } + BehaviorInterfaceError.prototype = Object.create(Error.prototype, { constructor: { value: Error } }); + if (Object.setPrototypeOf) { + Object.setPrototypeOf(BehaviorInterfaceError, Error); + } else { + BehaviorInterfaceError.__proto__ = Error; + } +}); +/*can-connect@4.0.2#can/map/map*/ +define('can-connect@4.0.2#can/map/map', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-queues', + 'can-event-queue/map/map', + 'can-symbol', + 'can-query-logic', + 'can-log/dev/dev', + '../../behavior', + 'can-diff/update-deep-except-identity/update-deep-except-identity', + 'can-diff/assign-deep-except-identity/assign-deep-except-identity', + 'can-diff/merge-deep/merge-deep', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var each = canReflect.each; + var isPlainObject = canReflect.isPlainObject; + var queues = require('can-queues'); + var eventQueue = require('can-event-queue/map/map'); + var canSymbol = require('can-symbol'); + var QueryLogic = require('can-query-logic'); + var dev = require('can-log/dev/dev'); + var behavior = require('../../behavior'); + var updateDeepExceptIdentity = require('can-diff/update-deep-except-identity/update-deep-except-identity'); + var assignDeepExceptIdentity = require('can-diff/assign-deep-except-identity/assign-deep-except-identity'); + var smartMerge = require('can-diff/merge-deep/merge-deep'); + var canSymbol = require('can-symbol'); + var getNameSymbol = canSymbol.for('can.getName'); + function smartMergeExceptIdentity(dest, source, schema) { + if (!schema) { + schema = canReflect.getSchema(dest); + } + if (!schema) { + throw new Error('can-connect/can/map/ is unable to update without a schema.'); + } + schema.identity.forEach(function (key) { + var id = canReflect.getKeyValue(dest, key); + if (id !== undefined) { + canReflect.setKeyValue(source, key, id); + } + }); + smartMerge(dest, source); + } + var canMapBehavior = behavior('can/map', function (baseConnection) { + var behavior = { + init: function () { + if (!this.Map) { + if (this.ObjectType) { + this.Map = this.ObjectType; + } else { + throw new Error('can-connect/can/map/map must be configured with a Map or ObjectType type'); + } + } + if (!this[getNameSymbol]) { + this[getNameSymbol] = function () { + if (this.name) { + return 'Connection{' + this.name + '}'; + } else if (this.Map) { + return 'Connection{' + canReflect.getName(this.Map) + '}'; + } else if (typeof this.url === 'string') { + return 'Connection{' + this.url + '}'; + } else { + return 'Connection{}'; + } + }; + } + this.List = this.List || this.ArrayType || this.Map.List; + var hasList = Boolean(this.List); + if (!hasList) { + Object.defineProperty(this, 'List', { + get: function () { + throw new Error('can-connect/can/map/map - ' + canReflect.getName(this) + ' should be configured with an ArrayType or List type.'); + } + }); + } + overwrite(this, this.Map, mapOverwrites); + if (hasList) { + overwrite(this, this.List, listOverwrites); + } + if (!this.queryLogic) { + this.queryLogic = new QueryLogic(this.Map); + } + var connection = this; + if (this.Map[canSymbol.for('can.onInstanceBoundChange')]) { + var canConnectMap_onMapBoundChange = function (instance, isBound) { + var method = isBound ? 'addInstanceReference' : 'deleteInstanceReference'; + if (connection[method]) { + connection[method](instance); + } + }; + this.Map[canSymbol.for('can.onInstanceBoundChange')](canConnectMap_onMapBoundChange); + } else { + console.warn('can-connect/can/map is unable to listen to onInstanceBoundChange on the Map type'); + } + if (hasList) { + if (this.List[canSymbol.for('can.onInstanceBoundChange')]) { + var canConnectMap_onListBoundChange = function (list, isBound) { + var method = isBound ? 'addListReference' : 'deleteListReference'; + if (connection[method]) { + connection[method](list); + } + }; + this.List[canSymbol.for('can.onInstanceBoundChange')](canConnectMap_onListBoundChange); + } else { + console.warn('can-connect/can/map is unable to listen to onInstanceBoundChange on the List type'); + } + } + if (this.Map[canSymbol.for('can.onInstancePatches')]) { + this.Map[canSymbol.for('can.onInstancePatches')](function canConnectMap_onInstancePatches(instance, patches) { + patches.forEach(function (patch) { + if ((patch.type === 'add' || patch.type === 'set') && patch.key === connection.idProp && instance[canSymbol.for('can.isBound')]()) { + connection.addInstanceReference(instance); + } + }); + }); + } else { + console.warn('can-connect/can/map is unable to listen to onInstancePatches on the Map type'); + } + baseConnection.init.apply(this, arguments); + }, + serializeInstance: function (instance) { + return canReflect.serialize(instance); + }, + serializeList: function (list) { + return canReflect.serialize(list); + }, + instance: function (props) { + var _Map = this.Map; + return new _Map(props); + }, + list: function (listData, set) { + var _List = this.List || this.Map && this.Map.List; + var list = canReflect.new(_List, listData.data); + canReflect.eachKey(listData, function (val, prop) { + if (prop !== 'data') { + canReflect.setKeyValue(list, prop, val); + } + }); + list[this.listQueryProp] = set; + return list; + }, + updatedList: function (list, listData, set) { + queues.batch.start(); + var enqueueOptions = {}; + queues.mutateQueue.enqueue(baseConnection.updatedList, this, arguments, enqueueOptions); + queues.batch.stop(); + }, + save: function (instance) { + canReflect.setKeyValue(instance, '_saving', true); + var done = function () { + canReflect.setKeyValue(instance, '_saving', false); + }; + var base = baseConnection.save.apply(this, arguments); + base.then(done, done); + return base; + }, + destroy: function (instance) { + canReflect.setKeyValue(instance, '_destroying', true); + var done = function () { + canReflect.setKeyValue(instance, '_destroying', false); + }; + var base = baseConnection.destroy.apply(this, arguments); + base.then(done, done); + return base; + } + }; + each([ + 'created', + 'updated', + 'destroyed' + ], function (funcName) { + behavior[funcName + 'Instance'] = function (instance, props) { + if (props && typeof props === 'object') { + if (funcName === 'destroyed' && canReflect.size(props) === 0) { + } else { + if (this.constructor.removeAttr) { + updateDeepExceptIdentity(instance, props, this.queryLogic.schema); + } else if (this.updateInstanceWithAssignDeep) { + assignDeepExceptIdentity(instance, props, this.queryLogic.schema); + } else { + smartMergeExceptIdentity(instance, props, this.queryLogic.schema); + } + } + } + if (funcName === 'created' && this.moveCreatedInstanceToInstanceStore) { + this.moveCreatedInstanceToInstanceStore(instance); + } + canMapBehavior.callbackInstanceEvents(funcName, instance); + }; + }); + return behavior; + }); + canMapBehavior.callbackInstanceEvents = function (funcName, instance) { + var constructor = instance.constructor; + queues.batch.start(); + eventQueue.dispatch.call(instance, { + type: funcName, + target: instance + }); + eventQueue.dispatch.call(constructor, funcName, [instance]); + queues.batch.stop(); + }; + var mapOverwrites = { + static: { + getList: function (base, connection) { + return function (set) { + return connection.getList(set); + }; + }, + findAll: function (base, connection) { + return function (set) { + return connection.getList(set); + }; + }, + get: function (base, connection) { + return function (params) { + return connection.get(params); + }; + }, + findOne: function (base, connection) { + return function (params) { + return connection.get(params); + }; + } + }, + prototype: { + isNew: function (base, connection) { + return function () { + return connection.isNew(this); + }; + }, + isSaving: function (base, connection) { + return function () { + return !!canReflect.getKeyValue(this, '_saving'); + }; + }, + isDestroying: function (base, connection) { + return function () { + return !!canReflect.getKeyValue(this, '_destroying'); + }; + }, + save: function (base, connection) { + return function (success, error) { + var promise = connection.save(this); + promise.then(success, error); + return promise; + }; + }, + destroy: function (base, connection) { + return function (success, error) { + var promise = connection.destroy(this); + promise.then(success, error); + return promise; + }; + } + }, + properties: { + _saving: { + enumerable: false, + value: false, + configurable: true, + writable: true + }, + _destroying: { + enumerable: false, + value: false, + configurable: true, + writable: true + } + } + }; + var listOverwrites = { + static: { + _bubbleRule: function (base, connection) { + return function (eventName, list) { + var bubbleRules = base(eventName, list); + bubbleRules.push('destroyed'); + return bubbleRules; + }; + } + }, + prototype: { + setup: function (base, connection) { + return function (params) { + if (isPlainObject(params) && !Array.isArray(params)) { + this[connection.listQueryProp] = params; + base.apply(this); + this.replace(canReflect.isPromise(params) ? params : connection.getList(params)); + } else { + base.apply(this, arguments); + } + }; + } + }, + properties: {} + }; + var overwrite = function (connection, Constructor, overwrites) { + var prop; + for (prop in overwrites.properties) { + canReflect.defineInstanceKey(Constructor, prop, overwrites.properties[prop]); + } + for (prop in overwrites.prototype) { + Constructor.prototype[prop] = overwrites.prototype[prop](Constructor.prototype[prop], connection); + } + if (overwrites.static) { + for (prop in overwrites.static) { + Constructor[prop] = overwrites.static[prop](Constructor[prop], connection); + } + } + }; + module.exports = canMapBehavior; +}); +/*can-connect@4.0.2#helpers/weak-reference-set*/ +define('can-connect@4.0.2#helpers/weak-reference-set', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + var assign = require('can-reflect').assignMap; + var WeakReferenceSet = function () { + this.set = []; + }; + assign(WeakReferenceSet.prototype, { + has: function (item) { + return this._getIndex(item) !== -1; + }, + addReference: function (item, referenceCount) { + var index = this._getIndex(item); + var data = this.set[index]; + if (!data) { + data = { + item: item, + referenceCount: 0 + }; + this.set.push(data); + } + data.referenceCount += referenceCount || 1; + }, + deleteReference: function (item) { + var index = this._getIndex(item); + var data = this.set[index]; + if (data) { + data.referenceCount--; + if (data.referenceCount === 0) { + this.set.splice(index, 1); + } + } + }, + delete: function (item) { + var index = this._getIndex(item); + if (index !== -1) { + this.set.splice(index, 1); + } + }, + get: function (item) { + var data = this.set[this._getIndex(item)]; + if (data) { + return data.item; + } + }, + referenceCount: function (item) { + var data = this.set[this._getIndex(item)]; + if (data) { + return data.referenceCount; + } + }, + _getIndex: function (item) { + var index; + this.set.every(function (data, i) { + if (data.item === item) { + index = i; + return false; + } + return true; + }); + return index !== undefined ? index : -1; + }, + forEach: function (cb) { + return this.set.forEach(cb); + } + }); + module.exports = WeakReferenceSet; +}); +/*can-connect@4.0.2#helpers/sorted-set-json*/ +define('can-connect@4.0.2#helpers/sorted-set-json', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + module.exports = function (set) { + if (set == null) { + return set; + } else { + return JSON.stringify(canReflect.cloneKeySort(set)); + } + }; +}); +/*can-connect@4.0.2#constructor/store/store*/ +define('can-connect@4.0.2#constructor/store/store', [ + 'require', + 'exports', + 'module', + '../../can-connect', + '../../helpers/weak-reference-map', + '../../helpers/weak-reference-set', + '../../helpers/sorted-set-json', + 'can-event-queue/map/map' +], function (require, exports, module) { + 'use strict'; + var connect = require('../../can-connect'); + var WeakReferenceMap = require('../../helpers/weak-reference-map'); + var WeakReferenceSet = require('../../helpers/weak-reference-set'); + var sortedSetJSON = require('../../helpers/sorted-set-json'); + var eventQueue = require('can-event-queue/map/map'); + var pendingRequests = 0; + var noRequestsTimer = null; + var requests = { + increment: function (connection) { + pendingRequests++; + clearTimeout(noRequestsTimer); + }, + decrement: function (connection) { + pendingRequests--; + if (pendingRequests === 0) { + noRequestsTimer = setTimeout(function () { + requests.dispatch('end'); + }, module.exports.requestCleanupDelay); + } + if (pendingRequests < 0) { + pendingRequests = 0; + } + }, + count: function () { + return pendingRequests; + } + }; + eventQueue(requests); + var constructorStore = connect.behavior('constructor/store', function (baseConnection) { + var behavior = { + instanceStore: new WeakReferenceMap(), + newInstanceStore: new WeakReferenceSet(), + listStore: new WeakReferenceMap(), + init: function () { + if (baseConnection.init) { + baseConnection.init.apply(this, arguments); + } + if (!this.hasOwnProperty('_requestInstances')) { + this._requestInstances = {}; + } + if (!this.hasOwnProperty('_requestLists')) { + this._requestLists = {}; + } + requests.on('end', function onRequestsEnd_deleteStoreReferences() { + var id; + for (id in this._requestInstances) { + this.instanceStore.deleteReference(id); + } + this._requestInstances = {}; + for (id in this._requestLists) { + this.listStore.deleteReference(id); + this._requestLists[id].forEach(this.deleteInstanceReference.bind(this)); + } + this._requestLists = {}; + }.bind(this)); + }, + _finishedRequest: function () { + requests.decrement(this); + }, + addInstanceReference: function (instance, id) { + var ID = id || this.id(instance); + if (ID === undefined) { + this.newInstanceStore.addReference(instance); + } else { + this.instanceStore.addReference(ID, instance); + } + }, + createdInstance: function (instance, props) { + baseConnection.createdInstance.apply(this, arguments); + this.moveCreatedInstanceToInstanceStore(instance); + }, + moveCreatedInstanceToInstanceStore: function (instance) { + var ID = this.id(instance); + if (this.newInstanceStore.has(instance) && ID !== undefined) { + var referenceCount = this.newInstanceStore.referenceCount(instance); + this.newInstanceStore.delete(instance); + this.instanceStore.addReference(ID, instance, referenceCount); + } + }, + addInstanceMetaData: function (instance, name, value) { + var data = this.instanceStore.set[this.id(instance)]; + if (data) { + data[name] = value; + } + }, + getInstanceMetaData: function (instance, name) { + var data = this.instanceStore.set[this.id(instance)]; + if (data) { + return data[name]; + } + }, + deleteInstanceMetaData: function (instance, name) { + var data = this.instanceStore.set[this.id(instance)]; + delete data[name]; + }, + deleteInstanceReference: function (instance) { + var ID = this.id(instance); + if (ID === undefined) { + this.newInstanceStore.deleteReference(instance); + } else { + this.instanceStore.deleteReference(this.id(instance), instance); + } + }, + addListReference: function (list, set) { + var id = sortedSetJSON(set || this.listQuery(list)); + if (id) { + this.listStore.addReference(id, list); + list.forEach(function (instance) { + this.addInstanceReference(instance); + }.bind(this)); + } + }, + deleteListReference: function (list, set) { + var id = sortedSetJSON(set || this.listQuery(list)); + if (id) { + this.listStore.deleteReference(id, list); + list.forEach(this.deleteInstanceReference.bind(this)); + } + }, + hydratedInstance: function (instance) { + if (requests.count() > 0) { + var id = this.id(instance); + if (!this._requestInstances[id]) { + this.addInstanceReference(instance); + this._requestInstances[id] = instance; + } + } + }, + hydrateInstance: function (props) { + var id = this.id(props); + if ((id || id === 0) && this.instanceStore.has(id)) { + var storeInstance = this.instanceStore.get(id); + this.updatedInstance(storeInstance, props); + return storeInstance; + } + var instance = baseConnection.hydrateInstance.call(this, props); + this.hydratedInstance(instance); + return instance; + }, + hydratedList: function (list, set) { + if (requests.count() > 0) { + var id = sortedSetJSON(set || this.listQuery(list)); + if (id) { + if (!this._requestLists[id]) { + this.addListReference(list, set); + this._requestLists[id] = list; + } + } + } + }, + hydrateList: function (listData, set) { + set = set || this.listQuery(listData); + var id = sortedSetJSON(set); + if (id && this.listStore.has(id)) { + var storeList = this.listStore.get(id); + this.updatedList(storeList, listData, set); + return storeList; + } + var list = baseConnection.hydrateList.call(this, listData, set); + this.hydratedList(list, set); + return list; + }, + getList: function (listQuery) { + var self = this; + requests.increment(this); + var promise = baseConnection.getList.call(this, listQuery); + promise.then(function (instances) { + self._finishedRequest(); + }, function () { + self._finishedRequest(); + }); + return promise; + }, + get: function (params) { + var self = this; + requests.increment(this); + var promise = baseConnection.get.call(this, params); + promise.then(function (instance) { + self._finishedRequest(); + }, function () { + self._finishedRequest(); + }); + return promise; + }, + save: function (instance) { + var self = this; + requests.increment(this); + var updating = !this.isNew(instance); + if (updating) { + this.addInstanceReference(instance); + } + var promise = baseConnection.save.call(this, instance); + promise.then(function (instances) { + if (updating) { + self.deleteInstanceReference(instance); + } + self._finishedRequest(); + }, function () { + self._finishedRequest(); + }); + return promise; + }, + destroy: function (instance) { + var self = this; + this.addInstanceReference(instance); + requests.increment(this); + var promise = baseConnection.destroy.call(this, instance); + promise.then(function (instance) { + self._finishedRequest(); + self.deleteInstanceReference(instance); + }, function () { + self._finishedRequest(); + }); + return promise; + }, + updatedList: function (list, listData, set) { + var oldList = list.slice(0); + if (!listData.data && typeof listData.length === 'number') { + listData = { data: listData }; + } + if (baseConnection.updatedList) { + baseConnection.updatedList.call(this, list, listData, set); + list.forEach(function (instance) { + this.addInstanceReference(instance); + }.bind(this)); + } else if (listData.data) { + listData.data.forEach(function (instance) { + this.addInstanceReference(instance); + }.bind(this)); + } + oldList.forEach(this.deleteInstanceReference.bind(this)); + } + }; + return behavior; + }); + constructorStore.requests = requests; + constructorStore.requestCleanupDelay = 10; + module.exports = constructorStore; +}); +/*can-connect@4.0.2#data/callbacks/callbacks*/ +define('can-connect@4.0.2#data/callbacks/callbacks', [ + 'require', + 'exports', + 'module', + '../../can-connect', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var connect = require('../../can-connect'); + var each = require('can-reflect').each; + var pairs = { + getListData: 'gotListData', + createData: 'createdData', + updateData: 'updatedData', + destroyData: 'destroyedData' + }; + var dataCallbackBehavior = connect.behavior('data/callbacks', function (baseConnection) { + var behavior = {}; + each(pairs, function (callbackName, name) { + behavior[name] = function (params, cid) { + var self = this; + return baseConnection[name].call(this, params).then(function (data) { + if (self[callbackName]) { + return self[callbackName].call(self, data, params, cid); + } else { + return data; + } + }); + }; + }); + return behavior; + }); + module.exports = dataCallbackBehavior; +}); +/*can-connect@4.0.2#data/parse/parse*/ +define('can-connect@4.0.2#data/parse/parse', [ + 'require', + 'exports', + 'module', + 'can-reflect', + 'can-key/get/get', + '../../behavior' +], function (require, exports, module) { + 'use strict'; + var each = require('can-reflect').each; + var getObject = require('can-key/get/get'); + var behavior = require('../../behavior'); + module.exports = behavior('data/parse', function (baseConnection) { + var behavior = { + parseListData: function (responseData) { + if (baseConnection.parseListData) { + responseData = baseConnection.parseListData.apply(this, arguments); + } + var result; + if (Array.isArray(responseData)) { + result = { data: responseData }; + } else { + var prop = this.parseListProp || 'data'; + responseData.data = getObject(responseData, prop); + result = responseData; + if (prop !== 'data') { + delete responseData[prop]; + } + if (!Array.isArray(result.data)) { + throw new Error('Could not get any raw data while converting using .parseListData'); + } + } + var arr = []; + for (var i = 0; i < result.data.length; i++) { + arr.push(this.parseInstanceData(result.data[i])); + } + result.data = arr; + return result; + }, + parseInstanceData: function (props) { + if (baseConnection.parseInstanceData) { + props = baseConnection.parseInstanceData.apply(this, arguments) || props; + } + return this.parseInstanceProp ? getObject(props, this.parseInstanceProp) || props : props; + } + }; + each(pairs, function (parseFunction, name) { + behavior[name] = function (params) { + var self = this; + return baseConnection[name].call(this, params).then(function () { + return self[parseFunction].apply(self, arguments); + }); + }; + }); + return behavior; + }); + var pairs = { + getListData: 'parseListData', + getData: 'parseInstanceData', + createData: 'parseInstanceData', + updateData: 'parseInstanceData', + destroyData: 'parseInstanceData' + }; +}); +/*can-make-rest@0.1.4#can-make-rest*/ +define('can-make-rest@0.1.4#can-make-rest', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + var methodMapping = { + item: { + 'GET': 'getData', + 'PUT': 'updateData', + 'DELETE': 'destroyData' + }, + list: { + 'GET': 'getListData', + 'POST': 'createData' + } + }; + function inferIdProp(url) { + var wrappedInBraces = /\{(.*)\}/; + var matches = url.match(wrappedInBraces); + var isUniqueMatch = matches && matches.length === 2; + if (isUniqueMatch) { + return matches[1]; + } + } + function getItemAndListUrls(url, idProp) { + idProp = idProp || inferIdProp(url) || 'id'; + var itemRegex = new RegExp('\\/\\{' + idProp + '\\}.*'); + var rootIsItemUrl = itemRegex.test(url); + var listUrl = rootIsItemUrl ? url.replace(itemRegex, '') : url; + var itemUrl = rootIsItemUrl ? url : url.trim() + '/{' + idProp + '}'; + return { + item: itemUrl, + list: listUrl + }; + } + module.exports = function (url, idProp) { + var data = {}; + canReflect.eachKey(getItemAndListUrls(url, idProp), function (url, type) { + canReflect.eachKey(methodMapping[type], function (interfaceMethod, method) { + data[interfaceMethod] = { + method: method, + url: url + }; + }); + }); + return data; + }; +}); +/*can-connect@4.0.2#helpers/make-promise*/ +define('can-connect@4.0.2#helpers/make-promise', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + var canReflect = require('can-reflect'); + module.exports = function (obj) { + if (obj && typeof obj.then === 'function' && !canReflect.isPromise(obj)) { + return new Promise(function (resolve, reject) { + obj.then(resolve, reject); + }); + } else { + return obj; + } + }; +}); +/*can-connect@4.0.2#data/url/url*/ +define('can-connect@4.0.2#data/url/url', [ + 'require', + 'exports', + 'module', + 'can-ajax', + 'can-key/replace-with/replace-with', + 'can-reflect', + 'can-log/dev/dev', + '../../behavior', + 'can-make-rest', + '../../helpers/make-promise' +], function (require, exports, module) { + 'use strict'; + var ajax = require('can-ajax'); + var replaceWith = require('can-key/replace-with/replace-with'); + var canReflect = require('can-reflect'); + var dev = require('can-log/dev/dev'); + var behavior = require('../../behavior'); + var makeRest = require('can-make-rest'); + var defaultRest = makeRest('/resource/{id}'); + var makePromise = require('../../helpers/make-promise'); + var urlBehavior = behavior('data/url', function (baseConnection) { + var behavior = {}; + canReflect.eachKey(defaultRest, function (defaultData, dataInterfaceName) { + behavior[dataInterfaceName] = function (params) { + var meta = methodMetaData[dataInterfaceName]; + var defaultBeforeSend; + if (typeof this.url === 'object') { + defaultBeforeSend = this.url.beforeSend; + if (typeof this.url[dataInterfaceName] === 'function') { + return makePromise(this.url[dataInterfaceName](params)); + } else if (this.url[dataInterfaceName]) { + var promise = makeAjax(this.url[dataInterfaceName], params, defaultData.method, this.ajax || ajax, findContentType(this.url, defaultData.method), meta, defaultBeforeSend); + return makePromise(promise); + } + } + var resource = typeof this.url === 'string' ? this.url : this.url.resource; + if (resource) { + var idProps = canReflect.getSchema(this.queryLogic).identity; + var resourceWithoutTrailingSlashes = resource.replace(/\/+$/, ''); + var result = makeRest(resourceWithoutTrailingSlashes, idProps[0])[dataInterfaceName]; + return makePromise(makeAjax(result.url, params, result.method, this.ajax || ajax, findContentType(this.url, result.method), meta, defaultBeforeSend)); + } + return baseConnection[name].call(this, params); + }; + }); + return behavior; + }); + var methodMetaData = { + getListData: {}, + getData: {}, + createData: {}, + updateData: {}, + destroyData: { includeData: false } + }; + var findContentType = function (url, method) { + if (typeof url === 'object' && url.contentType) { + var acceptableType = url.contentType === 'application/x-www-form-urlencoded' || url.contentType === 'application/json'; + if (acceptableType) { + return url.contentType; + } else { + } + } + return method === 'GET' ? 'application/x-www-form-urlencoded' : 'application/json'; + }; + function urlParamEncoder(key, value) { + return encodeURIComponent(value); + } + var makeAjax = function (ajaxOb, data, type, ajax, contentType, reqOptions, defaultBeforeSend) { + var params = {}; + if (typeof ajaxOb === 'string') { + var parts = ajaxOb.split(/\s+/); + params.url = parts.pop(); + if (parts.length) { + params.type = parts.pop(); + } + } else { + canReflect.assignMap(params, ajaxOb); + } + params.data = typeof data === 'object' && !Array.isArray(data) ? canReflect.assignMap(params.data || {}, data) : data; + params.url = replaceWith(params.url, params.data, urlParamEncoder, true); + params.contentType = contentType; + if (reqOptions.includeData === false) { + delete params.data; + } + return ajax(canReflect.assignMap({ + type: type || 'post', + dataType: 'json', + beforeSend: defaultBeforeSend + }, params)); + }; + module.exports = urlBehavior; +}); +/*can-diff@1.5.0#index-by-identity/index-by-identity*/ +define('can-diff@1.5.0#index-by-identity/index-by-identity', [ + 'require', + 'exports', + 'module', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canReflect = require('can-reflect'); + module.exports = function (items, item, schema) { + var length = canReflect.size(items); + if (!schema && length > 0) { + schema = canReflect.getSchema(items[0]); + } + if (!schema) { + schema = canReflect.getSchema(item); + } + if (!schema) { + throw new Error('No schema to use to get identity.'); + } + var id = canReflect.getIdentity(item, schema); + for (var i = 0; i < length; i++) { + var connId = canReflect.getIdentity(items[i], schema); + if (id === connId) { + return i; + } + } + return -1; + }; +}); +/*can-connect@4.0.2#real-time/real-time*/ +define('can-connect@4.0.2#real-time/real-time', [ + 'require', + 'exports', + 'module', + '../can-connect', + 'can-diff/index-by-identity/index-by-identity', + 'can-log/dev/dev', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var connect = require('../can-connect'); + var indexByIdentity = require('can-diff/index-by-identity/index-by-identity'); + var canDev = require('can-log/dev/dev'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var spliceSymbol = canSymbol.for('can.splice'); + function updateList(list, getRecord, currentIndex, newIndex) { + if (currentIndex === -1) { + if (newIndex !== -1) { + canReflect.splice(list, newIndex, 0, [getRecord()]); + } + } else { + if (newIndex === -1) { + canReflect.splice(list, currentIndex, 1, []); + } else if (newIndex !== currentIndex) { + if (currentIndex < newIndex) { + canReflect.splice(list, newIndex, 0, [getRecord()]); + canReflect.splice(list, currentIndex, 1, []); + } else { + canReflect.splice(list, currentIndex, 1, []); + canReflect.splice(list, newIndex, 0, [getRecord()]); + } + } else { + } + } + } + function updateListWithItem(list, recordData, currentIndex, newIndex, connection, set) { + if (currentIndex !== -1 && (newIndex === currentIndex + 1 || newIndex === currentIndex)) { + return; + } + if (list[spliceSymbol] !== undefined) { + updateList(list, function () { + return connection.hydrateInstance(recordData); + }, currentIndex, newIndex); + } else { + var copy = connection.serializeList(list); + updateList(copy, function () { + return recordData; + }, currentIndex, newIndex); + connection.updatedList(list, { data: copy }, set); + } + } + module.exports = connect.behavior('real-time', function (baseConnection) { + var createPromise = Promise.resolve(); + var behavior; + behavior = { + createData: function () { + var promise = baseConnection.createData.apply(this, arguments); + var cleanPromise = promise.catch(function () { + return ''; + }); + createPromise = Promise.all([ + createPromise, + cleanPromise + ]); + return promise; + }, + createInstance: function (props) { + var self = this; + return new Promise(function (resolve, reject) { + createPromise.then(function () { + setTimeout(function () { + var id = self.id(props); + var instance = self.instanceStore.get(id); + var serialized; + if (instance) { + resolve(self.updateInstance(props)); + } else { + instance = self.hydrateInstance(props); + serialized = self.serializeInstance(instance); + self.addInstanceReference(instance); + Promise.resolve(self.createdData(props, serialized)).then(function () { + self.deleteInstanceReference(instance); + resolve(instance); + }); + } + }, 1); + }); + }); + }, + createdData: function (props, params, cid) { + var instance; + if (cid !== undefined) { + instance = this.cidStore.get(cid); + } else { + instance = this.instanceStore.get(this.id(props)); + } + this.addInstanceReference(instance, this.id(props)); + this.createdInstance(instance, props); + create.call(this, this.serializeInstance(instance)); + this.deleteInstanceReference(instance); + return undefined; + }, + updatedData: function (props, params) { + var instance = this.instanceStore.get(this.id(params)); + this.updatedInstance(instance, props); + update.call(this, this.serializeInstance(instance)); + return undefined; + }, + updateInstance: function (props) { + var id = this.id(props); + var instance = this.instanceStore.get(id); + if (!instance) { + instance = this.hydrateInstance(props); + } + this.addInstanceReference(instance); + var serialized = this.serializeInstance(instance), self = this; + return Promise.resolve(this.updatedData(props, serialized)).then(function () { + self.deleteInstanceReference(instance); + return instance; + }); + }, + destroyedData: function (props, params) { + var id = this.id(params || props); + var instance = this.instanceStore.get(id); + if (!instance) { + instance = this.hydrateInstance(props); + } + var serialized = this.serializeInstance(instance); + this.destroyedInstance(instance, props); + destroy.call(this, serialized); + return undefined; + }, + destroyInstance: function (props) { + var id = this.id(props); + var instance = this.instanceStore.get(id); + if (!instance) { + instance = this.hydrateInstance(props); + } + this.addInstanceReference(instance); + var serialized = this.serializeInstance(instance), self = this; + return Promise.resolve(this.destroyedData(props, serialized)).then(function () { + self.deleteInstanceReference(instance); + return instance; + }); + } + }; + return behavior; + }); + var create = function (props) { + var self = this; + this.listStore.forEach(function (list, id) { + var set = JSON.parse(id); + var index = indexByIdentity(list, props, self.queryLogic.schema); + if (self.queryLogic.isMember(set, props)) { + var newIndex = self.queryLogic.index(set, list, props); + updateListWithItem(list, props, index, newIndex, self, set); + } + }); + }; + var update = function (props) { + var self = this; + this.listStore.forEach(function (list, id) { + var set = JSON.parse(id); + var currentIndex = indexByIdentity(list, props, self.queryLogic.schema); + if (self.queryLogic.isMember(set, props)) { + var newIndex = self.queryLogic.index(set, list, props); + updateListWithItem(list, props, currentIndex, newIndex, self, set); + } else if (currentIndex !== -1) { + updateListWithItem(list, props, currentIndex, -1, self, set); + } + }); + }; + var destroy = function (props) { + var self = this; + this.listStore.forEach(function (list, id) { + var set = JSON.parse(id); + var currentIndex = indexByIdentity(list, props, self.queryLogic.schema); + if (currentIndex !== -1) { + updateListWithItem(list, props, currentIndex, -1, self, set); + } + }); + }; +}); +/*can-connect@4.0.2#constructor/callbacks-once/callbacks-once*/ +define('can-connect@4.0.2#constructor/callbacks-once/callbacks-once', [ + 'require', + 'exports', + 'module', + '../../can-connect', + '../../helpers/sorted-set-json' +], function (require, exports, module) { + 'use strict'; + var connect = require('../../can-connect'); + var sortedSetJSON = require('../../helpers/sorted-set-json'); + var forEach = [].forEach; + var callbacks = [ + 'createdInstance', + 'updatedInstance', + 'destroyedInstance' + ]; + var callbacksOnceBehavior = connect.behavior('constructor/callbacks-once', function (baseConnection) { + var behavior = {}; + forEach.call(callbacks, function (name) { + behavior[name] = function (instance, data) { + var lastSerialized = this.getInstanceMetaData(instance, 'last-data-' + name); + var serialize = sortedSetJSON(data); + if (lastSerialized !== serialize) { + var result = baseConnection[name].apply(this, arguments); + this.addInstanceMetaData(instance, 'last-data-' + name, serialize); + return result; + } + }; + }); + return behavior; + }); + module.exports = callbacksOnceBehavior; +}); +/*can-define-realtime-rest-model@2.0.0#can-define-realtime-rest-model*/ +define('can-define-realtime-rest-model@2.0.0#can-define-realtime-rest-model', [ + 'require', + 'exports', + 'module', + 'can-connect', + 'can-connect/constructor/constructor', + 'can-connect/can/map/map', + 'can-connect/constructor/store/store', + 'can-connect/data/callbacks/callbacks', + 'can-connect/data/parse/parse', + 'can-connect/data/url/url', + 'can-define/list/list', + 'can-define/map/map', + 'can-connect/real-time/real-time', + 'can-connect/constructor/callbacks-once/callbacks-once', + 'can-namespace' +], function (require, exports, module) { + var connect = require('can-connect'); + var constructor = require('can-connect/constructor/constructor'); + var canMap = require('can-connect/can/map/map'); + var constructorStore = require('can-connect/constructor/store/store'); + var dataCallbacks = require('can-connect/data/callbacks/callbacks'); + var dataParse = require('can-connect/data/parse/parse'); + var dataUrl = require('can-connect/data/url/url'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var realTime = require('can-connect/real-time/real-time'); + var callbacksOnce = require('can-connect/constructor/callbacks-once/callbacks-once'); + var namespace = require('can-namespace'); + function defineRealtimeRestModel(optionsOrUrl) { + var options = typeof optionsOrUrl === 'string' ? { url: optionsOrUrl } : optionsOrUrl; + if (typeof options.Map === 'undefined') { + options.Map = DefineMap.extend({ seal: false }, {}); + } + if (typeof options.List === 'undefined') { + options.List = options.Map.List || DefineList.extend({ '#': options.Map }); + } + var behaviors = [ + constructor, + canMap, + constructorStore, + dataCallbacks, + dataParse, + dataUrl, + realTime, + callbacksOnce + ]; + return connect(behaviors, options); + } + module.exports = namespace.defineRealtimeRestModel = defineRealtimeRestModel; +}); +/*can-define-realtime-rest-model@2.0.0#can-define-realtime-rest-model-test*/ +define('can-define-realtime-rest-model@2.0.0#can-define-realtime-rest-model-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-fixture', + 'can-define/map/map', + 'can-define/list/list', + './can-define-realtime-rest-model', + 'can-query-logic', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var fixture = require('can-fixture'); + var DefineMap = require('can-define/map/map'); + var DefineList = require('can-define/list/list'); + var defineRealtimeRestModel = require('./can-define-realtime-rest-model'); + var QueryLogic = require('can-query-logic'); + var canReflect = require('can-reflect'); + QUnit.module('can-define-realtime-rest-model'); + QUnit.test('basics', function (assert) { + var Status = canReflect.assignSymbols({}, { + 'can.new': function (val) { + return val.toLowerCase(); + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + 'new', + 'assigned', + 'complete' + ] + }; + } + }); + var Todo = DefineMap.extend('Todo', { + _id: { + identity: true, + type: 'number' + }, + name: 'string', + complete: 'boolean', + dueDate: 'date', + points: 'number', + status: Status + }); + var TodoList = DefineList.extend({ '#': Todo }); + var connection = defineRealtimeRestModel({ + Map: Todo, + List: TodoList, + url: '/api/todos/{_id}' + }); + var todoStore = fixture.store([], new QueryLogic(Todo)); + fixture('/api/todos/{_id}', todoStore); + var done = assert.async(); + var createdTodo, allList, pushCreatedTodo, listHandler = function () { + }; + Todo.getList({}).then(function (list) { + assert.equal(list.length, 0, 'no items'); + allList = list; + allList.on('length', listHandler); + createdTodo = new Todo({ + name: 'lawn', + status: 'NEW', + dueDate: new Date(2017, 3, 30).toString() + }); + return createdTodo.save(); + }).then(function (todo) { + assert.equal(createdTodo, todo, 'same todo after create'); + assert.equal(todo.status, 'new', 'converted through status'); + assert.equal(allList.length, 1, 'one item added'); + return todoStore.createInstance({ + name: 'push instance', + complete: true, + dueDate: new Date(2018, 3, 30).toString(), + points: 10, + status: 'new' + }).then(function (instance) { + return connection.createInstance(instance); + }).then(function (created) { + pushCreatedTodo = created; + assert.ok(created._id, 'has an id'); + assert.equal(allList.length, 2, 'one item added'); + }); + }).then(function () { + return new Todo({ + name: 'third todo', + status: 'NEW', + dueDate: new Date(2000, 3, 30).toString() + }).save().then(function () { + createdTodo.assign({ points: 20 }); + return createdTodo.save().then(function () { + return Todo.getList({ + sort: '-points', + filter: { dueDate: { $gt: new Date(2001, 3, 30).toString() } } + }).then(function (list) { + assert.deepEqual(list.serialize(), [ + { + _id: 1, + name: 'lawn', + status: 'new', + dueDate: new Date(2017, 3, 30), + points: 20 + }, + { + _id: 2, + name: 'push instance', + complete: true, + dueDate: new Date(2018, 3, 30), + points: 10, + status: 'new' + } + ], 'get list works'); + }); + }); + }); + }).then(function () { + done(); + }, function (err) { + assert.ok(false, err); + done(); + }); + }); + QUnit.test('string signature', function (assert) { + var connection = defineRealtimeRestModel('/api/todos/{_id}'); + assert.ok(new connection.Map() instanceof DefineMap, 'Map defined'); + assert.ok(new connection.List() instanceof DefineList, 'List defined'); + }); +}); +/*can-define-rest-model@2.0.0#can-define-rest-model*/ +define('can-define-rest-model@2.0.0#can-define-rest-model', [ + 'require', + 'exports', + 'module', + 'can-connect/constructor/constructor', + 'can-connect/can/map/map', + 'can-connect/data/parse/parse', + 'can-connect/data/url/url', + 'can-define/list/list', + 'can-define/map/map', + 'can-namespace', + 'can-connect/base/base' +], function (require, exports, module) { + var constructor = require('can-connect/constructor/constructor'); + var canMap = require('can-connect/can/map/map'); + var dataParse = require('can-connect/data/parse/parse'); + var dataUrl = require('can-connect/data/url/url'); + var DefineList = require('can-define/list/list'); + var DefineMap = require('can-define/map/map'); + var namespace = require('can-namespace'); + var base = require('can-connect/base/base'); + function defineRestModel(optionsOrUrl) { + var options = typeof optionsOrUrl === 'string' ? { url: optionsOrUrl } : optionsOrUrl; + if (typeof options.Map === 'undefined') { + options.Map = DefineMap.extend({ seal: false }, {}); + } + if (typeof options.List === 'undefined') { + options.List = options.Map.List || DefineList.extend({ '#': options.Map }); + } + var connection = [ + base, + dataUrl, + dataParse, + constructor, + canMap + ].reduce(function (prev, behavior) { + return behavior(prev); + }, options); + connection.init(); + return connection; + } + module.exports = namespace.defineRestModel = defineRestModel; +}); +/*can-define-rest-model@2.0.0#can-define-rest-model-test*/ +define('can-define-rest-model@2.0.0#can-define-rest-model-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-fixture', + 'can-define/map/map', + 'can-define/list/list', + './can-define-rest-model', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var fixture = require('can-fixture'); + var DefineMap = require('can-define/map/map'); + var DefineList = require('can-define/list/list'); + var defineRestModel = require('./can-define-rest-model'); + var canReflect = require('can-reflect'); + QUnit.module('can-define-realtime-rest-model'); + QUnit.test('CRUD basics', function (assert) { + assert.expect(10); + var Status = canReflect.assignSymbols({}, { + 'can.new': function (val) { + return val.toLowerCase(); + }, + 'can.getSchema': function () { + return { + type: 'Or', + values: [ + 'new', + 'assigned', + 'complete' + ] + }; + } + }); + var Todo = DefineMap.extend('Todo', { + _id: { + identity: true, + type: 'number' + }, + name: 'string', + complete: 'boolean', + dueDate: 'date', + points: 'number', + status: Status + }); + var TodoList = DefineList.extend({ '#': Todo }); + defineRestModel({ + Map: Todo, + List: TodoList, + url: '/api/todos/{_id}' + }); + fixture('GET /api/todos', function () { + var count = 0; + return function (req) { + if (count++ === 0) { + assert.deepEqual(req.data, { + foo: 'bar', + filter: 'zed' + }); + return { + data: [{ + _id: 1, + name: 'zed' + }] + }; + } else { + } + }; + }()); + fixture('POST /api/todos', function () { + return { + _id: 1, + name: 'lawn care', + status: 'new', + dueDate: new Date(2017, 3, 30).toString() + }; + }); + fixture('GET /api/todos/{_id}', function () { + return { + _id: 2, + name: 'lawn care', + status: 'new', + dueDate: new Date(2017, 3, 30).toString() + }; + }); + fixture('PUT /api/todos/{_id}', function (req) { + assert.equal(req.data._id, '2'); + return { + _id: 2, + name: 'do lawn care', + status: 'assigned', + dueDate: new Date(2017, 3, 30).toString() + }; + }); + fixture('DELETE /api/todos/{_id}', function (req) { + assert.equal(req.data._id, '2', 'deleted'); + return {}; + }); + var done = assert.async(); + var createdTodo, listHandler = function () { + }; + Todo.getList({ + foo: 'bar', + filter: 'zed' + }).then(function (list) { + assert.deepEqual(list.serialize(), [{ + _id: 1, + name: 'zed' + }], 'got items'); + list.on('length', listHandler); + createdTodo = new Todo({ + name: 'lawn', + status: 'NEW', + dueDate: new Date(2017, 3, 30).toString() + }); + return createdTodo.save(); + }).then(function (todo) { + assert.equal(createdTodo, todo, 'same todo after create'); + assert.equal(todo.status, 'new', 'converted through status'); + assert.equal(todo.name, 'lawn care', 'converted through response'); + return todo._id; + }).then(function () { + return Todo.get({ _id: 2 }).then(function (todo) { + assert.deepEqual(todo.serialize(), { + _id: 2, + name: 'lawn care', + status: 'new', + dueDate: new Date(2017, 3, 30) + }, 'due date is right'); + return todo; + }); + }).then(function (todo) { + assert.notOk(todo.isNew(), 'is saved'); + todo.status = 'ASSIGNED'; + return todo.save().then(function (saved) { + assert.deepEqual(saved.serialize(), { + _id: 2, + name: 'do lawn care', + status: 'assigned', + dueDate: new Date(2017, 3, 30) + }, 'updated'); + return saved; + }); + }).then(function (todo) { + return todo.destroy(); + }).then(function () { + done(); + }, function (err) { + assert.ok(false, err); + done(); + }); + }); + QUnit.test('string signature', function (assert) { + var connection = defineRestModel('/api/todos/{_id}'); + assert.ok(new connection.Map() instanceof DefineMap, 'Map defined'); + assert.ok(new connection.List() instanceof DefineList, 'List defined'); + }); +}); +/*can-define-rest-model@2.0.0#test*/ +define('can-define-rest-model@2.0.0#test', ['can-define-rest-model@2.0.0#can-define-rest-model-test'], function () { + 'use strict'; +}); +/*can-compute@4.1.1#proto-compute_test*/ +define('can-compute@4.1.1#proto-compute_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-compute/proto-compute', + 'can-queues', + 'can-symbol', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var Compute = require('can-compute/proto-compute'); + var queues = require('can-queues'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + QUnit.module('can/Compute'); + QUnit.test('single value compute', function (assert) { + assert.expect(2); + var num = new Compute(1); + num.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 2, 'newVal'); + assert.equal(oldVal, 1, 'oldVal'); + }); + num.set(2); + }); + QUnit.test('inner computes values are not bound to', function (assert) { + var num = new Compute(1); + var outer = new Compute(function () { + var inner = new Compute(function () { + return num.get() + 1; + }); + return 2 * inner.get(); + }); + var handler = function () { + }; + outer.bind('change', handler); + var done = assert.async(); + setTimeout(function () { + var handlers = num[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get([]).length, 1, 'compute only bound to once'); + done(); + }, 50); + }); + QUnit.test('compute.truthy', function (assert) { + var result = 0; + var num = new Compute(3); + var truthy = Compute.truthy(num); + var tester = new Compute(function () { + if (truthy.get()) { + return ++result; + } else { + return ++result; + } + }); + tester.bind('change', function (ev, newVal, oldVal) { + if (num.get() === 0) { + assert.equal(newVal, 2, '2 is the new val'); + } else if (num.get() === -1) { + assert.equal(newVal, 3, '3 is the new val'); + } else { + assert.ok(false, 'change should not be called'); + } + }); + assert.equal(tester.get(), 1, 'on bind, we call tester once'); + num.set(2); + num.set(1); + num.set(0); + num.set(-1); + }); + QUnit.test('a binding compute does not double read', function (assert) { + var sourceAge = 30, timesComputeIsCalled = 0; + var age = new Compute(function (newVal) { + timesComputeIsCalled++; + if (timesComputeIsCalled === 1) { + assert.ok(true, 'reading age to get value'); + } else if (timesComputeIsCalled === 2) { + assert.equal(newVal, 31, 'the second time should be an update'); + } else if (timesComputeIsCalled === 3) { + assert.ok(true, 'called after set to get the value'); + } else { + assert.ok(false, 'You\'ve called the callback ' + timesComputeIsCalled + ' times'); + } + if (arguments.length) { + sourceAge = newVal; + } else { + return sourceAge; + } + }); + var info = new Compute(function () { + return 'I am ' + age.get(); + }); + var k = function () { + }; + info.bind('change', k); + assert.equal(info.get(), 'I am 30'); + age.set(31); + assert.equal(info.get(), 'I am 31'); + }); + QUnit.test('cloning a setter compute (#547)', function (assert) { + var name = new Compute('', function (newVal) { + return this.txt + newVal; + }); + var cloned = name.clone({ txt: '.' }); + cloned.set('-'); + assert.equal(cloned.get(), '.-'); + }); + QUnit.test('compute updated method uses get and old value (#732)', function (assert) { + assert.expect(9); + var input = { value: 1 }; + var value = new Compute('', { + get: function () { + return input.value; + }, + set: function (newVal) { + input.value = newVal; + }, + on: function (update) { + input.onchange = update; + }, + off: function () { + delete input.onchange; + } + }); + assert.equal(value.get(), 1, 'original value'); + assert.ok(!input.onchange, 'nothing bound'); + value.set(2); + assert.equal(value.get(), 2, 'updated value'); + assert.equal(input.value, 2, 'updated input.value'); + value.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 3, 'newVal'); + assert.equal(oldVal, 2, 'oldVal'); + value.unbind('change', this.Constructor); + }); + assert.ok(input.onchange, 'binding to onchange'); + input.value = 3; + input.onchange({}); + assert.ok(!input.onchange, 'removed binding'); + assert.equal(value.get(), 3); + }); + QUnit.test('a compute updated by source changes within a batch is part of that batch', function (assert) { + var computeA = new Compute('a'); + var computeB = new Compute('b'); + var combined1 = new Compute(function () { + return computeA.get() + ' ' + computeB.get(); + }); + var combined2 = new Compute(function () { + return computeA.get() + ' ' + computeB.get(); + }); + var combo = new Compute(function () { + return combined1.get() + ' ' + combined2.get(); + }); + var callbacks = 0; + combo.bind('change', function () { + if (callbacks === 0) { + assert.ok(true, 'called change once'); + } else { + assert.ok(false, 'called change multiple times'); + } + callbacks++; + }); + queues.batch.start(); + computeA.set('A'); + computeB.set('B'); + queues.batch.stop(); + }); + QUnit.test('Compute.async can be like a normal getter', function (assert) { + var first = new Compute('Justin'), last = new Compute('Meyer'), fullName = Compute.async('', function () { + return first.get() + ' ' + last.get(); + }); + assert.equal(fullName.get(), 'Justin Meyer'); + }); + QUnit.test('Compute.async operate on single value', function (assert) { + var a = new Compute(1); + var b = new Compute(2); + var obj = Compute.async({}, function (curVal) { + if (a.get()) { + curVal.a = a.get(); + } else { + delete curVal.a; + } + if (b.get()) { + curVal.b = b.get(); + } else { + delete curVal.b; + } + return curVal; + }); + obj.bind('change', function () { + }); + assert.deepEqual(obj.get(), { + a: 1, + b: 2 + }, 'object has all properties'); + a.set(0); + assert.deepEqual(obj.get(), { b: 2 }, 'removed a'); + b.set(0); + assert.deepEqual(obj.get(), {}, 'removed b'); + }); + QUnit.test('Compute.async async changing value', function (assert) { + var a = new Compute(1); + var b = new Compute(2); + var async = Compute.async(undefined, function (curVal, setVal) { + if (a.get()) { + setTimeout(function () { + setVal('a'); + }, 10); + } else if (b.get()) { + setTimeout(function () { + setVal('b'); + }, 10); + } else { + return null; + } + }); + var done = assert.async(); + var changeArgs = [ + { + newVal: 'a', + oldVal: undefined, + run: function () { + a.set(0); + } + }, + { + newVal: 'b', + oldVal: 'a', + run: function () { + b.set(0); + } + }, + { + newVal: null, + oldVal: 'b', + run: function () { + done(); + } + } + ], changeNum = 0; + async.bind('change', function (ev, newVal, oldVal) { + var data = changeArgs[changeNum++]; + assert.equal(newVal, data.newVal, 'newVal is correct'); + assert.equal(oldVal, data.oldVal, 'oldVal is correct'); + setTimeout(data.run, 10); + }); + }); + QUnit.test('Compute.async read without binding', function (assert) { + var source = new Compute(1); + var async = Compute.async([], function (curVal, setVal) { + curVal.push(source.get()); + return curVal; + }); + assert.ok(async.get(), 'calling async worked'); + }); + QUnit.test('Compute.async set uses last set or initial value', function (assert) { + var add = new Compute(1); + var fnCount = 0; + var async = Compute.async(10, function (curVal) { + switch (fnCount++) { + case 0: + assert.equal(curVal, 10); + break; + case 1: + assert.equal(curVal, 20); + break; + case 2: + assert.equal(curVal, 30, 'on bind'); + break; + case 3: + assert.equal(curVal, 30, 'on bind'); + break; + } + return curVal + add.get(); + }); + assert.equal(async.get(), 11, 'initial value'); + async.set(20); + async.bind('change', function () { + }); + async.set(20); + async.set(30); + }); + QUnit.test('Change propagation in a batch with late bindings (#2412)', function (assert) { + var rootA = new Compute('a'); + var rootB = new Compute('b'); + var childA = new Compute(function () { + return 'childA' + rootA.get(); + }); + var grandChild = new Compute(function () { + var b = rootB.get(); + if (b === 'b') { + return 'grandChild->b'; + } + var a = childA.get(); + return 'grandChild->' + a; + }); + childA.bind('change', function (ev, newVal, oldVal) { + }); + grandChild.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 'grandChild->childAA'); + }); + queues.batch.start(); + rootA.set('A'); + rootB.set('B'); + queues.batch.stop(); + }); + if (Compute.prototype.trace) { + QUnit.test('trace', function (assert) { + var rootA = new Compute('a'); + var rootB = new Compute('b'); + var childA = new Compute(function () { + return 'childA' + rootA.get(); + }); + var fn = function () { + var b = rootB.get(); + if (b === 'b') { + return 'grandChild->b'; + } + var a = childA.get(); + return 'grandChild->' + a; + }; + var grandChild = new Compute(fn); + childA.bind('change', function (ev, newVal, oldVal) { + }); + grandChild.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 'grandChild->childAA'); + }); + var out = grandChild.trace(); + assert.equal(out.definition, fn, 'got the right function'); + assert.equal(out.computeValue, 'grandChild->b'); + grandChild.log(); + queues.batch.start(); + rootA.set('A'); + rootB.set('B'); + queues.batch.stop(); + grandChild.log(); + }); + } + QUnit.test('works with can-reflect', function (assert) { + assert.expect(5); + var c = new Compute(0); + assert.equal(canReflect.getValue(c), 0, 'unbound value'); + assert.ok(canReflect.isValueLike(c), 'isValueLike is true'); + assert.ok(!canReflect.valueHasDependencies(c), 'valueHasDependencies -- false'); + var d = new Compute(function () { + return c.get(); + }); + d.on('change', function () { + }); + assert.ok(canReflect.valueHasDependencies(d), 'valueHasDependencies -- true'); + c.set(1); + assert.equal(canReflect.getValue(d), 1, 'bound value'); + c.set(2); + }); + QUnit.test('can-reflect setValue', function (assert) { + var a = new Compute('a'); + canReflect.setValue(a, 'A'); + assert.equal(a.get(), 'A', 'compute'); + }); + QUnit.test('registered symbols', function (assert) { + var a = new Compute('a'); + assert.ok(a[canSymbol.for('can.isValueLike')], 'can.isValueLike'); + assert.equal(a[canSymbol.for('can.getValue')](), 'a', 'can.getValue'); + a[canSymbol.for('can.setValue')]('b'); + assert.equal(a.get(), 'b', 'can.setValue'); + function handler(val) { + assert.equal(val, 'c', 'can.onValue'); + } + a[canSymbol.for('can.onValue')](handler); + a.set('c'); + a[canSymbol.for('can.offValue')](handler); + a.set('d'); + }); + QUnit.test('canReflect.onValue should get the previous value', function (assert) { + var a = new Compute('a'); + var done = assert.async(); + canReflect.onValue(a, function (newVal, oldVal) { + assert.equal(newVal, 'b'); + assert.equal(oldVal, 'a'); + done(); + }); + a.set('b'); + }); +}); +/*can-compute@4.1.1#can-compute_test*/ +define('can-compute@4.1.1#can-compute_test', [ + 'require', + 'exports', + 'module', + './proto-compute_test', + 'can-compute', + 'steal-qunit', + 'can-observation-recorder', + 'can-symbol', + 'can-reflect', + 'can-event-queue/map/map', + 'can-queues', + 'can-dom-events' +], function (require, exports, module) { + require('./proto-compute_test'); + var compute = require('can-compute'); + var QUnit = require('steal-qunit'); + var ObservationRecorder = require('can-observation-recorder'); + var canSymbol = require('can-symbol'); + var canReflect = require('can-reflect'); + var eventQueue = require('can-event-queue/map/map'); + var queues = require('can-queues'); + var domEvents = require('can-dom-events'); + var metaSymbol = canSymbol.for('can.meta'); + var domDispatch = domEvents.dispatch; + QUnit.module('can/compute'); + QUnit.test('single value compute', function (assert) { + var num = compute(1); + num.on('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 2, 'newVal'); + assert.equal(oldVal, 1, 'oldVal'); + }); + num(2); + }); + QUnit.test('inner computes values are not bound to', function (assert) { + var num = compute(1); + var outer = compute(function () { + var inner = compute(function () { + return num() + 1; + }); + return 2 * inner(); + }); + var handler = function () { + }; + outer.on('change', handler); + var done = assert.async(); + setTimeout(function () { + assert.equal(num.computeInstance[metaSymbol].handlers.get([]).length, 1, 'inner compute only bound once'); + assert.equal(outer.computeInstance[metaSymbol].handlers.get([]).length, 1, 'outer compute only bound once'); + done(); + }, 50); + }); + QUnit.test('compute.truthy', function (assert) { + var result = 0; + var numValue; + var num = compute(numValue = 3); + var truthy = compute.truthy(num); + var tester = compute(function () { + if (truthy()) { + return ++result; + } else { + return ++result; + } + }); + tester.addEventListener('change', function (ev, newVal, oldVal) { + if (num() === 0) { + assert.equal(newVal, 2, '2 is the new val'); + } else if (num() === -1) { + assert.equal(newVal, 3, '3 is the new val'); + } else { + assert.ok(false, 'change should not be called'); + } + }); + assert.equal(tester(), 1, 'on bind, we call tester once'); + num(numValue = 2); + num(numValue = 1); + num(numValue = 0); + num(numValue = -1); + }); + QUnit.test('a binding compute does not double read', function (assert) { + var sourceAge = 30, timesComputeIsCalled = 0; + var age = compute(function (newVal) { + timesComputeIsCalled++; + if (timesComputeIsCalled === 1) { + assert.ok(true, 'reading age to get value'); + } else if (timesComputeIsCalled === 2) { + assert.equal(newVal, 31, 'the second time should be an update'); + } else if (timesComputeIsCalled === 3) { + assert.ok(true, 'called after set to get the value'); + } else { + assert.ok(false, 'You\'ve called the callback ' + timesComputeIsCalled + ' times'); + } + if (arguments.length) { + sourceAge = newVal; + } else { + return sourceAge; + } + }); + var info = compute(function () { + return 'I am ' + age(); + }); + var k = function () { + }; + info.bind('change', k); + assert.equal(info(), 'I am 30'); + age(31); + assert.equal(info(), 'I am 31'); + }); + QUnit.test('cloning a setter compute (#547)', function (assert) { + var name = compute('', function (newVal) { + return this.txt + newVal; + }); + var cloned = name.clone({ txt: '.' }); + cloned('-'); + assert.equal(cloned(), '.-'); + }); + QUnit.test('compute updated method uses get and old value (#732)', function (assert) { + assert.expect(9); + var input = { value: 1 }; + var value = compute('', { + get: function () { + return input.value; + }, + set: function (newVal) { + input.value = newVal; + }, + on: function (update) { + input.onchange = update; + }, + off: function () { + delete input.onchange; + } + }); + assert.equal(value(), 1, 'original value'); + assert.ok(!input.onchange, 'nothing bound'); + value(2); + assert.equal(value(), 2, 'updated value'); + assert.equal(input.value, 2, 'updated input.value'); + function handler(ev, newVal, oldVal) { + assert.equal(newVal, 3, 'newVal'); + assert.equal(oldVal, 2, 'oldVal'); + value.unbind('change', handler); + } + value.bind('change', handler); + assert.ok(input.onchange, 'binding to onchange'); + input.value = 3; + input.onchange({}); + assert.ok(!input.onchange, 'removed binding'); + assert.equal(value(), 3); + }); + QUnit.test('a compute updated by source changes within a batch is part of that batch', function (assert) { + var computeA = compute('a'); + var computeB = compute('b'); + var combined1 = compute(function combined1() { + return computeA() + ' ' + computeB(); + }); + var combined2 = compute(function combined2() { + return computeA() + ' ' + computeB(); + }); + var combo = compute(function combo() { + return combined1() + ' ' + combined2(); + }); + var callbacks = 0; + combo.bind('change', function () { + if (callbacks === 0) { + assert.ok(true, 'called change once'); + } else { + assert.ok(false, 'called change multiple times'); + } + callbacks++; + }); + queues.batch.start(); + computeA('A'); + computeB('B'); + queues.batch.stop(); + }); + QUnit.test('compute.async can be like a normal getter', function (assert) { + var first = compute('Justin'), last = compute('Meyer'), fullName = compute.async('', function () { + return first() + ' ' + last(); + }); + assert.equal(fullName(), 'Justin Meyer'); + }); + QUnit.test('compute.async operate on single value', function (assert) { + var a = compute(1); + var b = compute(2); + var obj = compute.async({}, function (curVal) { + if (a()) { + curVal.a = a(); + } else { + delete curVal.a; + } + if (b()) { + curVal.b = b(); + } else { + delete curVal.b; + } + return curVal; + }); + obj.bind('change', function () { + }); + assert.deepEqual(obj(), { + a: 1, + b: 2 + }, 'object has all properties'); + a(0); + assert.deepEqual(obj(), { b: 2 }, 'removed a'); + b(0); + assert.deepEqual(obj(), {}, 'removed b'); + }); + QUnit.test('compute.async async changing value', function (assert) { + var a = compute(1); + var b = compute(2); + var done; + var async = compute.async(undefined, function (curVal, setVal) { + if (a()) { + setTimeout(function () { + setVal('a'); + }, 10); + } else if (b()) { + setTimeout(function () { + setVal('b'); + }, 10); + } else { + return null; + } + }); + var changeArgs = [ + { + newVal: 'a', + oldVal: undefined, + run: function () { + a(0); + } + }, + { + newVal: 'b', + oldVal: 'a', + run: function () { + b(0); + } + }, + { + newVal: null, + oldVal: 'b', + run: function () { + done(); + } + } + ], changeNum = 0; + done = assert.async(); + async.bind('change', function (ev, newVal, oldVal) { + var data = changeArgs[changeNum++]; + assert.equal(newVal, data.newVal, 'newVal is correct'); + assert.equal(oldVal, data.oldVal, 'oldVal is correct'); + setTimeout(data.run, 10); + }); + }); + QUnit.test('compute.async read without binding', function (assert) { + var source = compute(1); + var async = compute.async([], function (curVal, setVal) { + curVal.push(source()); + return curVal; + }); + assert.ok(async(), 'calling async worked'); + }); + QUnit.test('bug with nested computes and batch ordering (#1519)', function (assert) { + var root = compute('a'); + var isA = compute(function () { + return root() === 'a'; + }); + var isB = compute(function () { + return root() === 'b'; + }); + var combined = compute(function () { + var valA = isA(), valB = isB(); + return valA || valB; + }); + assert.equal(combined(), true); + combined.bind('change', function () { + }); + queues.batch.start(); + root('b'); + queues.batch.stop(); + assert.equal(combined(), true); + }); + QUnit.test('compute change handler context is set to the function not compute', function (assert) { + var comp = compute(null); + comp.bind('change', function () { + assert.equal(typeof this, 'function'); + }); + comp('test'); + }); + QUnit.test('Calling .unbind() on un-bound compute does not throw an error', function (assert) { + var count = compute(0); + count.unbind('change'); + assert.ok(true, 'No error was thrown'); + }); + QUnit.test('dependent computes update in the right order (2093)', function (assert) { + var root = compute('a'), childB = compute(function () { + return root(); + }), combine = compute(function () { + return root() + childB(); + }); + combine.bind('change', function (ev, newVal) { + assert.equal(newVal, 'bb', 'concat changed'); + }); + root('b'); + }); + QUnit.test('dependent computes update in the right order with a batch (#2093)', function (assert) { + var root = compute('a'), child = compute(function () { + return root(); + }), child2 = compute(function () { + return root(); + }), grandChild = compute(function () { + return child(); + }), combine = compute(function () { + return child2() + grandChild(); + }); + combine.bind('change', function (ev, newVal) { + assert.equal(newVal, 'bb', 'concat changed'); + }); + queues.batch.start(); + root('b'); + queues.batch.stop(); + }); + QUnit.test('bug with nested computes and batch ordering (#1519)', function (assert) { + var root = compute('a'); + var isA = compute(function () { + return root() === 'a'; + }); + var isB = compute(function () { + return root() === 'b'; + }); + var combined = compute(function () { + var valA = isA(), valB = isB(); + return valA || valB; + }); + assert.equal(combined(), true); + combined.bind('change', function () { + }); + queues.batch.start(); + root('b'); + queues.batch.stop(); + assert.equal(combined(), true); + }); + QUnit.test('binding, unbinding, and rebinding works after a timeout (#2095)', function (assert) { + var root = compute(1), derived = compute(function () { + return root(); + }); + var change = function () { + }; + derived.bind('change', change); + derived.unbind('change', change); + var done = assert.async(); + setTimeout(function () { + derived.bind('change', function (ev, newVal, oldVal) { + assert.equal(newVal, 2, 'updated'); + done(); + }); + root(2); + }, 10); + }); + QUnit.test('ObservationRecorder.isRecording observes doesn\'t understand ObservationRecorder.ignore (#2099)', function (assert) { + assert.expect(0); + var c = compute(1); + c.computeInstance.bind = function () { + assert.ok(false); + }; + var outer = compute(function () { + ObservationRecorder.ignore(function () { + c(); + })(); + }); + outer.bind('change', function () { + }); + }); + QUnit.test('handles missing update order items (#2121)', function (assert) { + var root1 = compute('root1'), child1 = compute(function () { + return root1(); + }), root2 = compute('root2'), child2 = compute(function () { + return root2(); + }), gc2 = compute(function () { + return child2(); + }), res = compute(function () { + return child1() + gc2(); + }); + res.bind('change', function (ev, newVal) { + assert.equal(newVal, 'ROOT1root2'); + }); + queues.batch.start(); + root1('ROOT1'); + queues.batch.stop(); + }); + QUnit.test('compute should not fire event when NaN is set multiple times #2128', function (assert) { + var c = compute(NaN); + compute.bind('change', function () { + assert.ok(false, 'change event should not be fired'); + }); + assert.ok(isNaN(c())); + c(NaN); + }); + QUnit.test('eventQueue.afterPreviousEvents firing too late (#2198)', function (assert) { + var compute1 = compute('a'), compute2 = compute('b'); + var derived = compute(function () { + return compute1().toUpperCase(); + }); + derived.bind('change', function () { + var afterPrevious = false; + compute2.bind('change', function () { + assert.ok(afterPrevious, 'after previous should have fired so we would respond to this event'); + }); + queues.batch.start(); + queues.batch.stop(); + eventQueue.afterPreviousEvents(function () { + afterPrevious = true; + }); + compute2('c'); + }); + queues.batch.start(); + compute1('x'); + queues.batch.stop(); + }); + QUnit.test('Async getter causes infinite loop (#28)', function (assert) { + var changeCount = 0; + var idCompute = compute(1); + var done = assert.async(); + var comp = compute.async(undefined, function (last, resolve) { + var id = idCompute(); + setTimeout(function () { + resolve(changeCount + '|' + id); + }, 1); + resolve(changeCount + '|' + id); + }, null); + comp.bind('change', function (ev, newVal) { + changeCount++; + comp(); + }); + setTimeout(function () { + idCompute(2); + }, 50); + var checkChangeCount = function () { + if (changeCount === 4) { + assert.equal(changeCount, 4); + done(); + } else { + setTimeout(checkChangeCount, 10); + } + }; + checkChangeCount(); + }); + QUnit.test('Listening to input change', function (assert) { + var input = document.createElement('input'); + var comp = compute(input, 'value', 'input'); + comp.on('change', function () { + assert.ok(true, 'it changed'); + }); + input.value = 'foo'; + domDispatch(input, 'input'); + }); + QUnit.test('Setting an input to change', function (assert) { + var input = document.createElement('input'); + var comp = compute(input, 'value', 'input'); + comp('foo'); + assert.ok(input.value === 'foo'); + }); + QUnit.test('compute.truthy with functions (canjs/can-stache#172)', function (assert) { + var func = compute(function () { + return function () { + assert.ok(false, 'should not be run'); + }; + }); + var truthy = compute.truthy(func); + assert.equal(truthy(), true); + }); + QUnit.test('works with can-reflect', function (assert) { + assert.expect(5); + var c = compute(0); + assert.equal(canReflect.getValue(c), 0, 'unbound value'); + var handler = function (newValue) { + assert.equal(newValue, 1, 'observed new value'); + canReflect.offValue(c, handler); + }; + assert.ok(canReflect.isValueLike(c), 'isValueLike is true'); + canReflect.onValue(c, handler); + assert.equal(canReflect.valueHasDependencies(c), undefined, 'valueHasDependencies'); + c(1); + assert.equal(canReflect.getValue(c), 1, 'bound value'); + c(2); + }); + QUnit.test('can-reflect valueHasDependencies', function (assert) { + var a = compute('a'); + var b = compute('b'); + var c = compute(function () { + return a() + b(); + }); + c.on('change', function () { + }); + assert.ok(canReflect.valueHasDependencies(c), 'valueHasDependencies'); + }); + QUnit.test('registered symbols', function (assert) { + var a = compute('a'); + assert.ok(a[canSymbol.for('can.isValueLike')], 'can.isValueLike'); + assert.equal(a[canSymbol.for('can.getValue')](), 'a', 'can.getValue'); + a[canSymbol.for('can.setValue')]('b'); + assert.equal(a(), 'b', 'can.setValue'); + function handler(val) { + assert.equal(val, 'c', 'can.onValue'); + } + a[canSymbol.for('can.onValue')](handler); + a('c'); + a[canSymbol.for('can.offValue')](handler); + a('d'); + }); + QUnit.test('can-reflect setValue', function (assert) { + var a = compute('a'); + canReflect.setValue(a, 'A'); + assert.equal(a(), 'A', 'compute'); + }); + QUnit.test('Calling .unbind() with no arguments should tear down all event handlers', function (assert) { + var count = compute(0); + count.on('change', function () { + console.log('Count changed'); + }); + var handlers = count.computeInstance[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get(['change']).length, 1, 'Change event added'); + count.unbind(); + assert.equal(handlers.get(['change']).length, 0, 'All events for compute removed'); + }); + QUnit.test('.off() unbinds a given handler', function (assert) { + var handler = function () { + }; + var c = compute('foo'); + c.on('change', handler); + var handlers = c.computeInstance[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get(['change']).length, 1, 'handler added'); + c.off('change', handler); + assert.equal(handlers.get(['change']).length, 0, 'hander removed'); + }); +}); +/*can-map@4.3.12#bubble*/ +define('can-map@4.3.12#bubble', [ + 'require', + 'exports', + 'module', + 'can-event-queue/map/map', + 'can-reflect' +], function (require, exports, module) { + 'use strict'; + var canEvent = require('can-event-queue/map/map'); + var canReflect = require('can-reflect'); + var isMap = function (map) { + return map && !canReflect.isFunctionLike(map) && canReflect.isMapLike(map) && !Array.isArray(map) && canReflect.isObservableLike(map); + }; + var bubble = { + bind: function (parent, eventName) { + if (!parent.__inSetup) { + var bubbleEvents = bubble.events(parent, eventName), len = bubbleEvents.length, bubbleEvent; + if (!parent._bubbleBindings) { + parent._bubbleBindings = {}; + } + for (var i = 0; i < len; i++) { + bubbleEvent = bubbleEvents[i]; + if (!parent._bubbleBindings[bubbleEvent]) { + parent._bubbleBindings[bubbleEvent] = 1; + bubble.childrenOf(parent, bubbleEvent); + } else { + parent._bubbleBindings[bubbleEvent]++; + } + } + } + }, + unbind: function (parent, eventName) { + var bubbleEvents = bubble.events(parent, eventName), len = bubbleEvents.length, bubbleEvent; + for (var i = 0; i < len; i++) { + bubbleEvent = bubbleEvents[i]; + if (parent._bubbleBindings) { + parent._bubbleBindings[bubbleEvent]--; + } + if (parent._bubbleBindings && !parent._bubbleBindings[bubbleEvent]) { + delete parent._bubbleBindings[bubbleEvent]; + bubble.teardownChildrenFrom(parent, bubbleEvent); + if (canReflect.size(parent._bubbleBindings) === 0) { + delete parent._bubbleBindings; + } + } + } + }, + add: function (parent, child, prop) { + if (canReflect.isObservableLike(child) && canReflect.isMapLike(child) && parent._bubbleBindings) { + for (var eventName in parent._bubbleBindings) { + if (parent._bubbleBindings[eventName]) { + bubble.teardownFromParent(parent, child, eventName); + bubble.toParent(child, parent, prop, eventName); + } + } + } + }, + addMany: function (parent, children) { + for (var i = 0, len = children.length; i < len; i++) { + bubble.add(parent, children[i], i); + } + }, + remove: function (parent, child) { + if (canReflect.isObservableLike(child) && canReflect.isMapLike(child) && parent._bubbleBindings) { + for (var eventName in parent._bubbleBindings) { + if (parent._bubbleBindings[eventName]) { + bubble.teardownFromParent(parent, child, eventName); + } + } + } + }, + removeMany: function (parent, children) { + for (var i = 0, len = children.length; i < len; i++) { + bubble.remove(parent, children[i]); + } + }, + set: function (parent, prop, value, current) { + if (canReflect.isObservableLike(value) && canReflect.isMapLike(value)) { + bubble.add(parent, value, prop); + } + if (canReflect.isObservableLike(current) && canReflect.isMapLike(current)) { + bubble.remove(parent, current); + } + return value; + }, + events: function (map, boundEventName) { + if (isMap(map)) { + return map.constructor._bubbleRule(boundEventName, map); + } + }, + toParent: function (child, parent, prop, eventName) { + canEvent.listenTo.call(parent, child, eventName, function () { + var args = canReflect.toArray(arguments), ev = args.shift(); + args[0] = (canReflect.isObservableLike(parent) && canReflect.isListLike(parent) ? parent.indexOf(child) : prop) + (args[0] ? '.' + args[0] : ''); + ev.triggeredNS = ev.triggeredNS || {}; + if (ev.triggeredNS[parent._cid]) { + return; + } + ev.triggeredNS[parent._cid] = true; + canEvent.dispatch.call(parent, ev, args); + if (eventName === 'change') { + canEvent.dispatch.call(parent, args[0], [ + args[2], + args[3] + ]); + } + }); + }, + childrenOf: function (parent, eventName) { + parent._each(function (child, prop) { + if (isMap(child)) { + bubble.toParent(child, parent, prop, eventName); + } + }); + }, + teardownFromParent: function (parent, child, eventName) { + if (child && child.unbind) { + canEvent.stopListening.call(parent, child, eventName); + } + }, + teardownChildrenFrom: function (parent, eventName) { + parent._each(function (child) { + bubble.teardownFromParent(parent, child, eventName); + }); + }, + isBubbling: function (parent, eventName) { + return parent._bubbleBindings && parent._bubbleBindings[eventName]; + } + }; + module.exports = bubble; +}); +/*can-map@4.3.12#map-helpers*/ +define('can-map@4.3.12#map-helpers', [ + 'require', + 'exports', + 'module', + 'can-cid', + 'can-assign', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + 'use strict'; + var CID = require('can-cid'); + var assign = require('can-assign'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var madeMap = null; + var teardownMap = function () { + for (var cid in madeMap) { + if (madeMap[cid].added) { + delete madeMap[cid].obj._cid; + } + } + madeMap = null; + }; + var mapHelpers = { + attrParts: function (attr, keepKey) { + if (keepKey) { + return [attr]; + } + return typeof attr === 'object' ? attr : ('' + attr).split('.'); + }, + canMakeObserve: function (obj) { + return obj && !canReflect.isPromise(obj) && (Array.isArray(obj) || canReflect.isPlainObject(obj)); + }, + reflectSerialize: function (unwrapped) { + this.forEach(function (val, name) { + if (this.___serialize) { + val = this.___serialize(name, val); + } else { + val = canReflect.serialize(val); + } + if (val !== undefined) { + unwrapped[name] = val; + } + }, this); + return unwrapped; + }, + reflectUnwrap: function (unwrapped) { + this.forEach(function (value, key) { + if (value !== undefined) { + unwrapped[key] = canReflect.unwrap(value); + } + }); + return unwrapped; + }, + removeSpecialKeys: function (map) { + if (map) { + [ + '_data', + 'constructor', + '_cid', + '__bindEvents' + ].forEach(function (key) { + delete map[key]; + }); + } + return map; + }, + serialize: function () { + var serializeMap = null; + return function (map, how, where) { + var cid = CID(map), firstSerialize = false; + if (!serializeMap) { + firstSerialize = true; + serializeMap = { + attr: {}, + serialize: {} + }; + } + serializeMap[how][cid] = where; + map.forEach(function (val, name) { + var result, isObservable = canReflect.isObservableLike(val), serialized = isObservable && serializeMap[how][CID(val)]; + if (serialized) { + result = serialized; + } else { + if (map['___' + how]) { + result = map['___' + how](name, val); + } else { + result = mapHelpers.getValue(map, name, val, how); + } + } + if (result !== undefined) { + where[name] = result; + } + }); + if (firstSerialize) { + serializeMap = null; + } + return where; + }; + }(), + getValue: function (map, name, val, how) { + if (how === 'attr') { + how = canSymbol.for('can.getValue'); + } + if (canReflect.isObservableLike(val) && val[how]) { + return val[how](); + } else { + return val; + } + }, + define: null, + addComputedAttr: function (map, attrName, compute) { + map._computedAttrs[attrName] = { + compute: compute, + count: 0, + handler: function (newVal, oldVal) { + map._triggerChange(attrName, 'set', newVal, oldVal); + } + }; + }, + addToMap: function addToMap(obj, instance) { + var teardown; + if (!madeMap) { + teardown = teardownMap; + madeMap = {}; + } + var hasCid = obj._cid; + var cid = CID(obj); + if (!madeMap[cid]) { + madeMap[cid] = { + obj: obj, + instance: instance, + added: !hasCid + }; + } + return teardown; + }, + getMapFromObject: function (obj) { + return madeMap && madeMap[obj._cid] && madeMap[obj._cid].instance; + }, + twoLevelDeepExtend: function (destination, source) { + for (var prop in source) { + destination[prop] = destination[prop] || {}; + assign(destination[prop], source[prop]); + } + } + }; + module.exports = exports = mapHelpers; +}); +/*can-types@1.4.0#can-types*/ +define('can-types@1.4.0#can-types', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-reflect', + 'can-symbol', + 'can-log/dev/dev' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var dev = require('can-log/dev/dev'); + var types = { + isMapLike: function (obj) { + return canReflect.isObservableLike(obj) && canReflect.isMapLike(obj); + }, + isListLike: function (obj) { + return canReflect.isObservableLike(obj) && canReflect.isListLike(obj); + }, + isPromise: function (obj) { + return canReflect.isPromise(obj); + }, + isConstructor: function (func) { + return canReflect.isConstructorLike(func); + }, + isCallableForValue: function (obj) { + return obj && canReflect.isFunctionLike(obj) && !canReflect.isConstructorLike(obj); + }, + isCompute: function (obj) { + return obj && obj.isComputed; + }, + get iterator() { + return canSymbol.iterator || canSymbol.for('iterator'); + }, + DefaultMap: null, + DefaultList: null, + queueTask: function (task) { + var args = task[2] || []; + task[0].apply(task[1], args); + }, + wrapElement: function (element) { + return element; + }, + unwrapElement: function (element) { + return element; + } + }; + if (namespace.types) { + throw new Error('You can\'t have two versions of can-types, check your dependencies'); + } else { + module.exports = namespace.types = types; + } +}); +/*can-cid@1.3.1#helpers*/ +define('can-cid@1.3.1#helpers', function (require, exports, module) { + 'use strict'; + module.exports = { + each: function (obj, cb, context) { + for (var prop in obj) { + cb.call(context, obj[prop], prop); + } + return obj; + } + }; +}); +/*can-cid@1.3.1#set/set*/ +define('can-cid@1.3.1#set/set', [ + 'require', + 'exports', + 'module', + '../can-cid', + '../helpers' +], function (require, exports, module) { + 'use strict'; + var getCID = require('../can-cid').get; + var helpers = require('../helpers'); + var CIDSet; + if (typeof Set !== 'undefined') { + CIDSet = Set; + } else { + var CIDSet = function () { + this.values = {}; + }; + CIDSet.prototype.add = function (value) { + this.values[getCID(value)] = value; + }; + CIDSet.prototype['delete'] = function (key) { + var has = getCID(key) in this.values; + if (has) { + delete this.values[getCID(key)]; + } + return has; + }; + CIDSet.prototype.forEach = function (cb, thisArg) { + helpers.each(this.values, cb, thisArg); + }; + CIDSet.prototype.has = function (value) { + return getCID(value) in this.values; + }; + CIDSet.prototype.clear = function () { + return this.values = {}; + }; + Object.defineProperty(CIDSet.prototype, 'size', { + get: function () { + var size = 0; + helpers.each(this.values, function () { + size++; + }); + return size; + } + }); + } + module.exports = CIDSet; +}); +/*can-cid@1.3.1#map/map*/ +define('can-cid@1.3.1#map/map', [ + 'require', + 'exports', + 'module', + '../can-cid', + '../helpers' +], function (require, exports, module) { + 'use strict'; + var getCID = require('../can-cid').get; + var helpers = require('../helpers'); + var CIDMap; + if (typeof Map !== 'undefined') { + CIDMap = Map; + } else { + var CIDMap = function () { + this.values = {}; + }; + CIDMap.prototype.set = function (key, value) { + this.values[getCID(key)] = { + key: key, + value: value + }; + }; + CIDMap.prototype['delete'] = function (key) { + var has = getCID(key) in this.values; + if (has) { + delete this.values[getCID(key)]; + } + return has; + }; + CIDMap.prototype.forEach = function (cb, thisArg) { + helpers.each(this.values, function (pair) { + return cb.call(thisArg || this, pair.value, pair.key, this); + }, this); + }; + CIDMap.prototype.has = function (key) { + return getCID(key) in this.values; + }; + CIDMap.prototype.get = function (key) { + var obj = this.values[getCID(key)]; + return obj && obj.value; + }; + CIDMap.prototype.clear = function () { + return this.values = {}; + }; + Object.defineProperty(CIDMap.prototype, 'size', { + get: function () { + var size = 0; + helpers.each(this.values, function () { + size++; + }); + return size; + } + }); + } + module.exports = CIDMap; +}); +/*can-map@4.3.12#can-map*/ +define('can-map@4.3.12#can-map', [ + 'require', + 'exports', + 'module', + './bubble', + './map-helpers', + 'can-event-queue/map/map', + 'can-event-queue/type/type', + 'can-construct', + 'can-observation-recorder', + 'can-stache-key', + 'can-compute', + 'can-single-reference', + 'can-observation', + 'can-namespace', + 'can-log/dev/dev', + 'can-cid', + 'can-assign', + 'can-types', + 'can-reflect', + 'can-symbol', + 'can-cid/set/set', + 'can-cid/map/map', + 'can-queues' +], function (require, exports, module) { + 'use strict'; + var bubble = require('./bubble'); + var mapHelpers = require('./map-helpers'); + var canEvent = require('can-event-queue/map/map'); + var addTypeEvents = require('can-event-queue/type/type'); + var Construct = require('can-construct'); + var ObservationRecorder = require('can-observation-recorder'); + var ObserveReader = require('can-stache-key'); + var canCompute = require('can-compute'); + var singleReference = require('can-single-reference'); + var Observation = require('can-observation'); + var namespace = require('can-namespace'); + var dev = require('can-log/dev/dev'); + var CID = require('can-cid'); + var assign = require('can-assign'); + var types = require('can-types'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var CIDSet = require('can-cid/set/set'); + var CIDMap = require('can-cid/map/map'); + var canQueues = require('can-queues'); + var unobservable = { 'constructor': true }; + var hasOwnProperty = {}.hasOwnProperty; + var inSetupSymbol = canSymbol.for('can.initializing'); + var Map = Construct.extend({ + setup: function (baseMap) { + Construct.setup.apply(this, arguments); + this._computedPropertyNames = []; + if (Map) { + addTypeEvents(this); + this[canSymbol.for('can.defineInstanceKey')] = function (prop, definition) { + if (definition.value !== undefined) { + this.defaults[prop] = definition.value; + } + if (definition.enumerable === false) { + this.enumerable[prop] = false; + } + }; + if (!this.defaults) { + this.defaults = {}; + } + if (!this.enumerable) { + this.enumerable = {}; + } + for (var prop in this.prototype) { + if (prop !== 'define' && prop !== 'constructor' && (typeof this.prototype[prop] !== 'function' || this.prototype[prop].prototype instanceof Construct)) { + this.defaults[prop] = this.prototype[prop]; + } else if (canReflect.isObservableLike(this.prototype[prop])) { + this._computedPropertyNames.push(prop); + } + } + if (mapHelpers.define) { + mapHelpers.define(this, baseMap.prototype.define); + } + } + }, + shortName: 'Map', + _bubbleRule: function (eventName) { + return eventName === 'change' || eventName.indexOf('.') >= 0 ? ['change'] : []; + }, + addEventListener: canEvent.addEventListener, + removeEventListener: canEvent.removeEventListener, + keys: function (map) { + return canReflect.getOwnEnumerableKeys(map); + } + }, { + setup: function (obj) { + if (canReflect.isObservableLike(obj) && typeof obj.serialize === 'function') { + obj = obj.serialize(); + } + this._data = Object.create(null); + CID(this, '.map'); + this._setupComputedProperties(); + var teardownMapping = obj && mapHelpers.addToMap(obj, this); + var defaultValues = this._setupDefaults(obj); + var data = assign(canReflect.assignDeep({}, defaultValues), obj); + this.attr(data); + if (teardownMapping) { + teardownMapping(); + } + }, + _setupComputedProperties: function () { + this._computedAttrs = Object.create(null); + var computes = this.constructor._computedPropertyNames; + for (var i = 0, len = computes.length; i < len; i++) { + var attrName = computes[i]; + mapHelpers.addComputedAttr(this, attrName, this[attrName]); + } + }, + _setupDefaults: function () { + return this.constructor.defaults || {}; + }, + attr: function (attr, val) { + var type = typeof attr; + if (attr === undefined) { + return this._getAttrs(); + } else if (type !== 'string' && type !== 'number') { + return this._setAttrs(attr, val); + } else if (arguments.length === 1) { + return this._get(attr); + } else { + this._set(attr + '', val); + return this; + } + }, + _get: function (attr) { + attr = attr + ''; + var dotIndex = attr.indexOf('.'); + if (dotIndex >= 0) { + var value = this.___get(attr); + if (value !== undefined) { + ObservationRecorder.add(this, attr); + return value; + } + var first = attr.substr(0, dotIndex), second = attr.substr(dotIndex + 1); + var current = this.__get(first); + return current && canReflect.getKeyValue(current, second); + } else { + return this.__get(attr); + } + }, + __get: function (attr) { + if (!unobservable[attr] && !this._computedAttrs[attr]) { + ObservationRecorder.add(this, attr); + } + return this.___get(attr); + }, + ___get: function (attr) { + if (attr !== undefined) { + var computedAttr = this._computedAttrs[attr]; + if (computedAttr) { + return canReflect.getValue(computedAttr.compute); + } else { + return hasOwnProperty.call(this._data, attr) ? this._data[attr] : undefined; + } + } else { + return this._data; + } + }, + _set: function (attr, value, keepKey) { + attr = attr + ''; + var dotIndex = attr.indexOf('.'), current; + if (dotIndex >= 0 && !keepKey) { + var first = attr.substr(0, dotIndex), second = attr.substr(dotIndex + 1); + current = this[inSetupSymbol] ? undefined : this.___get(first); + if (canReflect.isMapLike(current)) { + canReflect.setKeyValue(current, second, value); + } else { + current = this[inSetupSymbol] ? undefined : this.___get(attr); + if (this.__convert) { + value = this.__convert(attr, value); + } + this.__set(attr, this.__type(value, attr), current); + } + } else { + current = this[inSetupSymbol] ? undefined : this.___get(attr); + if (this.__convert) { + value = this.__convert(attr, value); + } + this.__set(attr, this.__type(value, attr), current); + } + }, + __type: function (value, prop) { + if (typeof value === 'object' && !canReflect.isObservableLike(value) && mapHelpers.canMakeObserve(value) && !canReflect.isListLike(value)) { + var cached = mapHelpers.getMapFromObject(value); + if (cached) { + return cached; + } + var MapConstructor = this.constructor.Map || Map; + return new MapConstructor(value); + } + return value; + }, + __set: function (prop, value, current) { + if (value !== current || !Object.prototype.hasOwnProperty.call(this._data, prop)) { + var computedAttr = this._computedAttrs[prop]; + var changeType = computedAttr || current !== undefined || hasOwnProperty.call(this.___get(), prop) ? 'set' : 'add'; + this.___set(prop, typeof value === 'object' ? bubble.set(this, prop, value, current) : value); + if (!computedAttr || !computedAttr.count) { + this._triggerChange(prop, changeType, value, current); + } + if (typeof current === 'object') { + bubble.teardownFromParent(this, current); + } + } + }, + ___set: function (prop, val) { + var computedAttr = this._computedAttrs[prop]; + if (computedAttr) { + canReflect.setValue(computedAttr.compute, val); + } else { + this._data[prop] = val; + } + if (typeof this.constructor.prototype[prop] !== 'function' && !computedAttr) { + this[prop] = val; + } + }, + removeAttr: function (attr) { + return this._remove(attr); + }, + _remove: function (attr) { + var parts = mapHelpers.attrParts(attr), prop = parts.shift(), current = this.___get(prop); + if (parts.length && current) { + return canReflect.deleteKeyValue(current, parts.join('.')); + } else { + if (typeof attr === 'string' && !!~attr.indexOf('.')) { + prop = attr; + } + this.__remove(prop, current); + return current; + } + }, + __remove: function (prop, current) { + if (prop in this._data) { + this.___remove(prop); + this._triggerChange(prop, 'remove', undefined, current); + } + }, + ___remove: function (prop) { + delete this._data[prop]; + if (!(prop in this.constructor.prototype)) { + delete this[prop]; + } + }, + ___serialize: function (name, val) { + if (this._legacyAttrBehavior) { + return mapHelpers.getValue(this, name, val, 'serialize'); + } else { + return canReflect.serialize(val, CIDMap); + } + }, + _getAttrs: function () { + if (this._legacyAttrBehavior) { + return mapHelpers.serialize(this, 'attr', {}); + } else { + return canReflect.unwrap(this, CIDMap); + } + }, + _setAttrs: function (props, remove) { + if (this._legacyAttrBehavior) { + return this.__setAttrs(props, remove); + } + if (remove === true || remove === 'true') { + this[canSymbol.for('can.updateDeep')](props); + } else { + this[canSymbol.for('can.assignDeep')](props); + } + return this; + }, + __setAttrs: function (props, remove) { + props = assign({}, props); + var prop, self = this, newVal; + canQueues.batch.start(); + this._each(function (curVal, prop) { + if (prop === '_cid') { + return; + } + newVal = props[prop]; + if (newVal === undefined) { + if (remove) { + self.removeAttr(prop); + } + return; + } + if (self.__convert) { + newVal = self.__convert(prop, newVal); + } + if (canReflect.isObservableLike(curVal) && canReflect.isMapLike(curVal) && mapHelpers.canMakeObserve(newVal)) { + if (remove === true) { + canReflect.updateDeep(curVal, newVal); + } else { + canReflect.assignDeep(curVal, newVal); + } + } else if (curVal !== newVal) { + self.__set(prop, self.__type(newVal, prop), curVal); + } + delete props[prop]; + }); + for (prop in props) { + if (prop !== '_cid') { + newVal = props[prop]; + this._set(prop, newVal, true); + } + } + canQueues.batch.stop(); + return this; + }, + serialize: function () { + return canReflect.serialize(this, CIDMap); + }, + _triggerChange: function (attr, how, newVal, oldVal, batchNum) { + canQueues.batch.start(); + if (bubble.isBubbling(this, 'change')) { + canEvent.dispatch.call(this, { + type: 'change', + target: this, + batchNum: batchNum + }, [ + attr, + how, + newVal, + oldVal + ]); + } + canEvent.dispatch.call(this, { + type: attr, + target: this, + batchNum: batchNum, + patches: [{ + type: 'set', + key: attr, + value: newVal + }] + }, [ + newVal, + oldVal + ]); + if (how === 'remove' || how === 'add') { + canEvent.dispatch.call(this, { + type: '__keys', + target: this, + batchNum: batchNum + }); + } + canQueues.batch.stop(); + }, + compute: function (prop) { + if (typeof this.constructor.prototype[prop] === 'function') { + return canCompute(this[prop], this); + } else { + var reads = ObserveReader.reads(prop); + var last = reads.length - 1; + return canCompute(function (newVal) { + if (arguments.length) { + ObserveReader.write(this, reads[last].key, newVal, {}); + } else { + return ObserveReader.get(this, prop); + } + }, this); + } + }, + forEach: function (callback, context) { + var key, item; + var keys = canReflect.getOwnEnumerableKeys(this); + for (var i = 0, len = keys.length; i < len; i++) { + key = keys[i]; + item = this.attr(key); + if (callback.call(context || item, item, key, this) === false) { + break; + } + } + return this; + }, + _each: function (callback) { + var data = this.___get(); + for (var prop in data) { + if (hasOwnProperty.call(data, prop)) { + callback(data[prop], prop); + } + } + }, + dispatch: canEvent.dispatch + }); + canEvent(Map.prototype); + Map.prototype.addEventListener = function (eventName, handler) { + var computedBinding = this._computedAttrs && this._computedAttrs[eventName]; + if (computedBinding && computedBinding.compute) { + if (!computedBinding.count) { + computedBinding.count = 1; + canReflect.onValue(computedBinding.compute, computedBinding.handler, 'notify'); + } else { + computedBinding.count++; + } + } + bubble.bind(this, eventName); + return canEvent.addEventListener.apply(this, arguments); + }; + Map.prototype.removeEventListener = function (eventName, handler) { + var computedBinding = this._computedAttrs && this._computedAttrs[eventName]; + if (computedBinding) { + if (computedBinding.count === 1) { + computedBinding.count = 0; + canReflect.offValue(computedBinding.compute, computedBinding.handler, 'notify'); + } else { + computedBinding.count--; + } + } + bubble.unbind(this, eventName); + return canEvent.removeEventListener.apply(this, arguments); + }; + Map.prototype.on = Map.prototype.bind = Map.prototype.addEventListener; + Map.prototype.off = Map.prototype.unbind = Map.prototype.removeEventListener; + Map.on = Map.bind = Map.addEventListener; + Map.off = Map.unbind = Map.removeEventListener; + canReflect.assignSymbols(Map.prototype, { + 'can.isMapLike': true, + 'can.isListLike': false, + 'can.isValueLike': false, + 'can.getKeyValue': Map.prototype._get, + 'can.setKeyValue': Map.prototype._set, + 'can.deleteKeyValue': Map.prototype._remove, + 'can.getOwnEnumerableKeys': function () { + if (!this[inSetupSymbol]) { + ObservationRecorder.add(this, '__keys'); + } + var enumerable = this.constructor.enumerable; + if (enumerable) { + return Object.keys(this._data).filter(function (key) { + return enumerable[key] !== false; + }, this); + } else { + return Object.keys(this._data); + } + }, + 'can.assignDeep': function (source) { + canQueues.batch.start(); + canReflect.assignDeepMap(this, mapHelpers.removeSpecialKeys(canReflect.assignMap({}, source))); + canQueues.batch.stop(); + }, + 'can.updateDeep': function (source) { + canQueues.batch.start(); + canReflect.updateDeepMap(this, mapHelpers.removeSpecialKeys(canReflect.assignMap({}, source))); + canQueues.batch.stop(); + }, + 'can.unwrap': mapHelpers.reflectUnwrap, + 'can.serialize': mapHelpers.reflectSerialize, + 'can.onKeyValue': function (key, handler, queue) { + var translationHandler = function (ev, newValue, oldValue) { + handler.call(this, newValue, oldValue); + }; + singleReference.set(handler, this, translationHandler, key); + this.addEventListener(key, translationHandler, queue); + }, + 'can.offKeyValue': function (key, handler, queue) { + this.removeEventListener(key, singleReference.getAndDelete(handler, this, key), queue); + }, + 'can.keyHasDependencies': function (key) { + return !!(this._computedAttrs && this._computedAttrs[key] && this._computedAttrs[key].compute); + }, + 'can.getKeyDependencies': function (key) { + var ret; + if (this._computedAttrs && this._computedAttrs[key] && this._computedAttrs[key].compute) { + ret = {}; + ret.valueDependencies = new CIDSet(); + ret.valueDependencies.add(this._computedAttrs[key].compute); + } + return ret; + } + }); + if (!types.DefaultMap) { + types.DefaultMap = Map; + } + module.exports = namespace.Map = Map; +}); +/*can-list@4.2.2#can-list*/ +define('can-list@4.2.2#can-list', [ + 'require', + 'exports', + 'module', + 'can-namespace', + 'can-map', + 'can-map/bubble', + 'can-map/map-helpers', + 'can-queues', + 'can-event-queue/map/map', + 'can-observation-recorder', + 'can-cid', + 'can-reflect', + 'can-assign', + 'can-types', + 'can-symbol', + 'can-cid/map/map' +], function (require, exports, module) { + 'use strict'; + var namespace = require('can-namespace'); + var Map = require('can-map'); + var bubble = require('can-map/bubble'); + var mapHelpers = require('can-map/map-helpers'); + var queues = require('can-queues'); + var canEvent = require('can-event-queue/map/map'); + var ObservationRecorder = require('can-observation-recorder'); + var CID = require('can-cid'); + var canReflect = require('can-reflect'); + var assign = require('can-assign'); + var types = require('can-types'); + var canSymbol = require('can-symbol'); + var CIDMap = require('can-cid/map/map'); + var splice = [].splice, spliceRemovesProps = function () { + var obj = { + 0: 'a', + length: 1 + }; + splice.call(obj, 0, 1); + return !obj[0]; + }(); + var serializeNonTypes = function (MapType, arg, args) { + if (arg && arg.serialize && !(arg instanceof MapType)) { + args.push(new MapType(arg.serialize())); + } else { + args.push(arg); + } + }; + var List = Map.extend({ Map: Map }, { + setup: function (instances, options) { + this.length = 0; + CID(this, '.map'); + this._setupComputedProperties(); + instances = instances === undefined ? [] : canReflect.toArray(instances); + var teardownMapping; + if (canReflect.isPromise(instances)) { + this.replace(instances); + } else { + teardownMapping = instances.length && mapHelpers.addToMap(instances, this); + this.push.apply(this, instances); + } + if (teardownMapping) { + teardownMapping(); + } + assign(this, options); + }, + _triggerChange: function (attr, how, newVal, oldVal) { + queues.batch.start(); + var index = +attr, patches; + if (!~('' + attr).indexOf('.') && !isNaN(index)) { + if (bubble.isBubbling(this, 'change')) { + canEvent.dispatch.call(this, { + type: 'change', + target: this + }, [ + attr, + how, + newVal, + oldVal + ]); + } + if (how === 'add') { + patches = [{ + insert: newVal, + index: index, + deleteCount: 0, + type: 'splice' + }]; + canEvent.dispatch.call(this, { + type: how, + patches: patches + }, [ + newVal, + index + ]); + canEvent.dispatch.call(this, 'length', [this.length]); + canEvent.dispatch.call(this, 'can.patches', [patches]); + } else if (how === 'remove') { + patches = [{ + index: index, + deleteCount: oldVal.length, + type: 'splice' + }]; + canEvent.dispatch.call(this, { + type: how, + patches: patches + }, [ + oldVal, + index + ]); + canEvent.dispatch.call(this, 'length', [this.length]); + canEvent.dispatch.call(this, 'can.patches', [patches]); + } else { + canEvent.dispatch.call(this, how, [ + newVal, + index + ]); + } + } else { + Map.prototype._triggerChange.apply(this, arguments); + } + queues.batch.stop(); + }, + __get: function (prop) { + prop = isNaN(+prop) || prop % 1 ? prop : +prop; + if (typeof prop === 'number') { + ObservationRecorder.add(this, 'can.patches'); + return this.___get('' + prop); + } else { + return Map.prototype.__get.call(this, prop); + } + }, + ___get: function (attr) { + if (attr) { + var computedAttr = this._computedAttrs[attr]; + if (computedAttr && computedAttr.compute) { + return canReflect.getValue(computedAttr.compute); + } + if (this[attr] && this[attr].isComputed && typeof this.constructor.prototype[attr] === 'function') { + return canReflect.getValue(this[attr]); + } else { + return this[attr]; + } + } else { + return this; + } + }, + __set: function (prop, value, current) { + prop = isNaN(+prop) || prop % 1 ? prop : +prop; + if (typeof prop === 'number') { + if (prop > this.length - 1) { + var newArr = new Array(prop + 1 - this.length); + newArr[newArr.length - 1] = value; + this.push.apply(this, newArr); + return newArr; + } else { + this.splice(prop, 1, value); + return this; + } + } + return Map.prototype.__set.call(this, '' + prop, value, current); + }, + ___set: function (attr, val) { + this[attr] = val; + if (+attr >= this.length) { + this.length = +attr + 1; + } + }, + __remove: function (prop, current) { + if (isNaN(+prop)) { + delete this[prop]; + this._triggerChange(prop, 'remove', undefined, current); + } else { + this.splice(prop, 1); + } + }, + _each: function (callback) { + var data = this.___get(); + for (var i = 0; i < data.length; i++) { + callback(data[i], i); + } + }, + serialize: function () { + return canReflect.serialize(this, CIDMap); + }, + splice: function (index, howMany) { + var args = canReflect.toArray(arguments), added = [], i, len, listIndex, allSame = args.length > 2; + index = index || 0; + for (i = 0, len = args.length - 2; i < len; i++) { + listIndex = i + 2; + args[listIndex] = this.__type(args[listIndex], listIndex); + added.push(args[listIndex]); + if (this[i + index] !== args[listIndex]) { + allSame = false; + } + } + if (allSame && this.length <= added.length) { + return added; + } + if (howMany === undefined) { + howMany = args[1] = this.length - index; + } + var removed = splice.apply(this, args); + if (!spliceRemovesProps) { + for (i = this.length; i < removed.length + this.length; i++) { + delete this[i]; + } + } + queues.batch.start(); + if (howMany > 0) { + bubble.removeMany(this, removed); + this._triggerChange('' + index, 'remove', undefined, removed); + } + if (args.length > 2) { + bubble.addMany(this, added); + this._triggerChange('' + index, 'add', added, removed); + } + queues.batch.stop(); + return removed; + } + }), getArgs = function (args) { + return args[0] && Array.isArray(args[0]) ? args[0] : canReflect.toArray(args); + }; + canReflect.eachKey({ + push: 'length', + unshift: 0 + }, function (where, name) { + var orig = [][name]; + List.prototype[name] = function () { + var args = [], len = where ? this.length : 0, i = arguments.length, res, val; + while (i--) { + val = arguments[i]; + args[i] = bubble.set(this, i, this.__type(val, i)); + } + res = orig.apply(this, args); + if (!this.comparator || args.length) { + this._triggerChange('' + len, 'add', args, undefined); + } + return res; + }; + }); + canReflect.eachKey({ + pop: 'length', + shift: 0 + }, function (where, name) { + List.prototype[name] = function () { + if (!this.length) { + return undefined; + } + var args = getArgs(arguments), len = where && this.length ? this.length - 1 : 0; + var res = [][name].apply(this, args); + this._triggerChange('' + len, 'remove', undefined, [res]); + if (res && res.removeEventListener) { + bubble.remove(this, res); + } + return res; + }; + }); + assign(List.prototype, { + indexOf: function (item, fromIndex) { + ObservationRecorder.add(this, 'length'); + for (var i = fromIndex || 0, len = this.length; i < len; i++) { + if (this.attr(i) === item) { + return i; + } + } + return -1; + }, + join: function () { + ObservationRecorder.add(this, 'length'); + return [].join.apply(this, arguments); + }, + reverse: function () { + var list = [].reverse.call(canReflect.toArray(this)); + return this.replace(list); + }, + slice: function () { + ObservationRecorder.add(this, 'length'); + var temp = Array.prototype.slice.apply(this, arguments); + return new this.constructor(temp); + }, + concat: function () { + var args = [], MapType = this.constructor.Map; + canReflect.each(arguments, function (arg) { + if (canReflect.isObservableLike(arg) && canReflect.isListLike(arg) || Array.isArray(arg)) { + var arr = canReflect.isObservableLike(arg) && canReflect.isListLike(arg) ? canReflect.toArray(arg) : arg; + canReflect.each(arr, function (innerArg) { + serializeNonTypes(MapType, innerArg, args); + }); + } else { + serializeNonTypes(MapType, arg, args); + } + }); + return new this.constructor(Array.prototype.concat.apply(canReflect.toArray(this), args)); + }, + forEach: function (cb, thisarg) { + var item; + for (var i = 0, len = this.attr('length'); i < len; i++) { + item = this.attr(i); + if (item !== undefined && cb.call(thisarg || item, item, i, this) === false) { + break; + } + } + return this; + }, + replace: function (newList) { + if (canReflect.isPromise(newList)) { + if (this._promise) { + this._promise.__isCurrentPromise = false; + } + var promise = this._promise = newList; + promise.__isCurrentPromise = true; + var self = this; + newList.then(function (newList) { + if (promise.__isCurrentPromise) { + self.replace(newList); + } + }); + } else { + newList = newList === undefined ? [] : canReflect.toArray(newList); + this.splice.apply(this, [ + 0, + this.length + ].concat(newList)); + } + return this; + }, + filter: function (callback, thisArg) { + var filteredList = new this.constructor(), self = this, filtered; + this.forEach(function (item, index, list) { + filtered = callback.call(thisArg || self, item, index, self); + if (filtered) { + filteredList.push(item); + } + }); + return filteredList; + }, + map: function (callback, thisArg) { + var filteredList = new List(), self = this; + this.forEach(function (item, index, list) { + var mapped = callback.call(thisArg || self, item, index, self); + filteredList.push(mapped); + }); + return filteredList; + }, + sort: function (compareFunction) { + var sorting = Array.prototype.slice.call(this); + Array.prototype.sort.call(sorting, compareFunction); + this.splice.apply(this, [ + 0, + sorting.length + ].concat(sorting)); + return this; + } + }); + var oldType = Map.prototype.__type; + Map.prototype.__type = function (value, prop) { + if (typeof value === 'object' && Array.isArray(value)) { + var cached = mapHelpers.getMapFromObject(value); + if (cached) { + return cached; + } + return new List(value); + } + return oldType.apply(this, arguments); + }; + var oldSetup = Map.setup; + Map.setup = function () { + oldSetup.apply(this, arguments); + if (!(this.prototype instanceof List)) { + this.List = Map.List.extend({ Map: this }, {}); + } + }; + if (!types.DefaultList) { + types.DefaultList = List; + } + canReflect.assignSymbols(List.prototype, { + 'can.isMoreListLikeThanMapLike': true, + 'can.isListLike': true, + 'can.getKeyValue': List.prototype._get, + 'can.setKeyValue': List.prototype._set, + 'can.deleteKeyValue': List.prototype._remove, + 'can.getOwnEnumerableKeys': function () { + return Object.keys(this._data || {}).concat(this.map(function (val, index) { + return index; + })); + }, + 'can.assignDeep': function (source) { + queues.batch.start(); + canReflect.assignDeepList(this, source); + queues.batch.stop(); + }, + 'can.updateDeep': function (source) { + queues.batch.start(); + canReflect.updateDeepList(this, source); + queues.batch.stop(); + }, + 'can.unwrap': mapHelpers.reflectUnwrap, + 'can.serialize': mapHelpers.reflectSerialize, + 'can.onKeysAdded': function (handler) { + this[canSymbol.for('can.onKeyValue')]('add', handler); + }, + 'can.onKeysRemoved': function (handler) { + this[canSymbol.for('can.onKeyValue')]('remove', handler); + }, + 'can.splice': function (index, deleteCount, insert) { + this.splice.apply(this, [ + index, + deleteCount + ].concat(insert)); + }, + 'can.onPatches': function (handler, queue) { + this[canSymbol.for('can.onKeyValue')]('can.patches', handler, queue); + }, + 'can.offPatches': function (handler, queue) { + this[canSymbol.for('can.offKeyValue')]('can.patches', handler, queue); + } + }); + Map.List = List; + module.exports = namespace.List = List; +}); +/*can-list@4.2.2#can-list_test*/ +define('can-list@4.2.2#can-list_test', [ + 'require', + 'exports', + 'module', + 'can-list', + 'steal-qunit', + 'can-observation', + 'can-map', + 'can-reflect', + 'can-symbol' +], function (require, exports, module) { + var List = require('can-list'); + var QUnit = require('steal-qunit'); + var Observation = require('can-observation'); + var Map = require('can-map'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + QUnit.module('can-list'); + QUnit.test('list attr changes length', function (assert) { + var l = new List([ + 0, + 1, + 2 + ]); + l.attr(3, 3); + assert.equal(l.length, 4); + }); + QUnit.test('removeAttr on list', function (assert) { + var l = new List([ + 0, + 1, + 2 + ]); + l.removeAttr(1); + assert.equal(l.attr('length'), 2); + assert.deepEqual(l.attr(), [ + 0, + 2 + ]); + }); + QUnit.test('list splice', function (assert) { + var l = new List([ + 0, + 1, + 2, + 3 + ]), first = true; + l.bind('change', function (ev, attr, how, newVals, oldVals) { + assert.equal(attr, '1'); + if (first) { + assert.equal(how, 'remove', 'removing items'); + assert.equal(newVals, undefined, 'no new Vals'); + } else { + assert.deepEqual(newVals, [ + 'a', + 'b' + ], 'got the right newVals'); + assert.equal(how, 'add', 'adding items'); + } + first = false; + }); + l.splice(1, 2, 'a', 'b'); + assert.deepEqual(l.serialize(), [ + 0, + 'a', + 'b', + 3 + ], 'serialized'); + }); + QUnit.test('list pop', function (assert) { + var l = new List([ + 0, + 1, + 2, + 3 + ]); + l.bind('change', function (ev, attr, how, newVals, oldVals) { + assert.equal(attr, '3'); + assert.equal(how, 'remove'); + assert.equal(newVals, undefined); + assert.deepEqual(oldVals, [3]); + }); + l.pop(); + assert.deepEqual(l.serialize(), [ + 0, + 1, + 2 + ]); + }); + QUnit.test('remove nested property in item of array map', function (assert) { + var state = new List([{ nested: true }]); + state.bind('change', function (ev, attr, how, newVal, old) { + assert.equal(attr, '0.nested'); + assert.equal(how, 'remove'); + assert.deepEqual(old, true); + }); + state.removeAttr('0.nested'); + assert.equal(undefined, state.attr('0.nested')); + }); + QUnit.test('pop unbinds', function (assert) { + var l = new List([{ foo: 'bar' }]); + var o = l.attr(0), count = 0; + l.bind('change', function (ev, attr, how, newVal, oldVal) { + count++; + if (count === 1) { + assert.equal(attr, '0.foo', 'count is set'); + } else if (count === 2) { + assert.equal(how, 'remove'); + assert.equal(attr, '0'); + } else { + assert.ok(false, 'called too many times'); + } + }); + assert.equal(o.attr('foo'), 'bar', 'read foo property'); + o.attr('foo', 'car'); + l.pop(); + o.attr('foo', 'bad'); + }); + QUnit.test('splice unbinds', function (assert) { + var l = new List([{ foo: 'bar' }]); + var o = l.attr(0), count = 0; + l.bind('change', function (ev, attr, how, newVal, oldVal) { + count++; + if (count === 1) { + assert.equal(attr, '0.foo', 'count is set'); + } else if (count === 2) { + assert.equal(how, 'remove'); + assert.equal(attr, '0'); + } else { + assert.ok(false, 'called too many times'); + } + }); + assert.equal(o.attr('foo'), 'bar'); + o.attr('foo', 'car'); + l.splice(0, 1); + o.attr('foo', 'bad'); + }); + QUnit.test('always gets right attr even after moving array items', function (assert) { + var l = new List([{ foo: 'bar' }]); + var o = l.attr(0); + l.unshift('A new Value'); + l.bind('change', function (ev, attr, how) { + assert.equal(attr, '1.foo'); + }); + o.attr('foo', 'led you'); + }); + QUnit.test('Array accessor methods', function (assert) { + assert.expect(11); + var l = new List([ + 'a', + 'b', + 'c' + ]), sliced = l.slice(2), joined = l.join(' | '), concatenated = l.concat([ + 2, + 1 + ], new List([0])); + assert.ok(sliced instanceof List, 'Slice is an Observable list'); + assert.equal(sliced.length, 1, 'Sliced off two elements'); + assert.equal(sliced[0], 'c', 'Single element as expected'); + assert.equal(joined, 'a | b | c', 'Joined list properly'); + assert.ok(concatenated instanceof List, 'Concatenated is an Observable list'); + assert.deepEqual(concatenated.serialize(), [ + 'a', + 'b', + 'c', + 2, + 1, + 0 + ], 'List concatenated properly'); + l.forEach(function (letter, index) { + assert.ok(true, 'Iteration'); + if (index === 0) { + assert.equal(letter, 'a', 'First letter right'); + } + if (index === 2) { + assert.equal(letter, 'c', 'Last letter right'); + } + }); + }); + QUnit.test('Concatenated list items Equal original', function (assert) { + var l = new List([ + { firstProp: 'Some data' }, + { secondProp: 'Next data' } + ]), concatenated = l.concat([ + { hello: 'World' }, + { foo: 'Bar' } + ]); + assert.ok(l[0] === concatenated[0], 'They are Equal'); + assert.ok(l[1] === concatenated[1], 'They are Equal'); + }); + QUnit.test('Lists with maps concatenate properly', function (assert) { + var Person = Map.extend(); + var People = List.extend({ Map: Person }, {}); + var Genius = Person.extend(); + var Animal = Map.extend(); + var me = new Person({ name: 'John' }); + var animal = new Animal({ name: 'Tak' }); + var genius = new Genius({ name: 'Einstein' }); + var hero = { name: 'Ghandi' }; + var people = new People([]); + var specialPeople = new People([ + genius, + hero + ]); + people = people.concat([ + me, + animal, + specialPeople + ], specialPeople, [ + 1, + 2 + ], 3); + assert.ok(people.attr('length') === 8, 'List length is right'); + assert.ok(people[0] === me, 'Map in list === vars created before concat'); + assert.ok(people[1] instanceof Person, 'Animal got serialized to Person'); + }); + QUnit.test('splice removes items in IE (#562)', function (assert) { + var l = new List(['a']); + l.splice(0, 1); + assert.ok(!l.attr(0), 'all props are removed'); + }); + QUnit.test('reverse triggers add/remove events (#851)', function (assert) { + assert.expect(6); + var l = new List([ + 1, + 2, + 3 + ]); + l.bind('change', function () { + assert.ok(true, 'change should be called'); + }); + l.bind('set', function () { + assert.ok(false, 'set should not be called'); + }); + l.bind('add', function () { + assert.ok(true, 'add called'); + }); + l.bind('remove', function () { + assert.ok(true, 'remove called'); + }); + l.bind('length', function () { + assert.ok(true, 'length should be called'); + }); + l.reverse(); + }); + QUnit.test('filter', function (assert) { + var l = new List([ + { + id: 1, + name: 'John' + }, + { + id: 2, + name: 'Mary' + } + ]); + var filtered = l.filter(function (item) { + return item.name === 'Mary'; + }); + assert.notEqual(filtered._cid, l._cid, 'not same object'); + assert.equal(filtered.length, 1, 'one item'); + assert.equal(filtered[0].name, 'Mary', 'filter works'); + }); + QUnit.test('removing expandos on lists', function (assert) { + var list = new List([ + 'a', + 'b' + ]); + list.removeAttr('foo'); + assert.equal(list.length, 2); + }); + QUnit.test('No Add Events if List Splice adds the same items that it is removing. (#1277, #1399)', function (assert) { + var list = new List([ + 'a', + 'b' + ]); + list.bind('add', function () { + assert.ok(false, 'Add callback should not be called.'); + }); + list.bind('remove', function () { + assert.ok(false, 'Remove callback should not be called.'); + }); + var result = list.splice(0, 2, 'a', 'b'); + assert.deepEqual(result, [ + 'a', + 'b' + ]); + }); + QUnit.test('add event always returns an array as the value (#998)', function (assert) { + var list = new List([]), msg; + list.bind('add', function (ev, newElements, index) { + assert.deepEqual(newElements, [4], msg); + }); + msg = 'works on push'; + list.push(4); + list.pop(); + msg = 'works on attr()'; + list.attr(0, 4); + list.pop(); + msg = 'works on replace()'; + list.replace([4]); + }); + QUnit.test('Setting with .attr() out of bounds of length triggers add event with leading undefineds', function (assert) { + var list = new List([1]); + list.bind('add', function (ev, newElements, index) { + assert.deepEqual(newElements, [ + undefined, + undefined, + 4 + ], 'Leading undefineds are included'); + assert.equal(index, 1, 'Index takes into account the leading undefineds from a .attr()'); + }); + list.attr(3, 4); + }); + QUnit.test('No events should fire if removals happened on empty arrays', function (assert) { + var list = new List([]), msg; + list.bind('remove', function (ev, removed, index) { + assert.ok(false, msg); + }); + msg = 'works on pop'; + list.pop(); + msg = 'works on shift'; + list.shift(); + assert.ok(true, 'No events were fired.'); + }); + QUnit.test('setting an index out of bounds does not create an array', function (assert) { + assert.expect(1); + var l = new List(); + l.attr('1', 'foo'); + assert.equal(l.attr('1'), 'foo'); + }); + QUnit.test('splice with similar but less items works (#1606)', function (assert) { + var list = new List([ + 'aa', + 'bb', + 'cc' + ]); + list.splice(0, list.length, 'aa', 'cc', 'dd'); + assert.deepEqual(list.attr(), [ + 'aa', + 'cc', + 'dd' + ]); + list.splice(0, list.length, 'aa', 'cc'); + assert.deepEqual(list.attr(), [ + 'aa', + 'cc' + ]); + }); + QUnit.test('filter returns same list type (#1744)', function (assert) { + var ParentList = List.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + assert.ok(children.filter(function () { + }) instanceof ChildList); + }); + QUnit.test('reverse returns the same list instance (#1744)', function (assert) { + var ParentList = List.extend(); + var ChildList = ParentList.extend(); + var children = new ChildList([ + 1, + 2, + 3 + ]); + assert.ok(children.reverse() === children); + }); + QUnit.test('slice and join are observable by a compute (#1884)', function (assert) { + assert.expect(2); + var list = new List([ + 1, + 2, + 3 + ]); + var sliced = new Observation(function () { + return list.slice(0, 1); + }); + canReflect.onValue(sliced, function (newVal) { + assert.deepEqual(newVal.attr(), [2], 'got a new List'); + }); + var joined = new Observation(function () { + return list.join(','); + }); + canReflect.onValue(joined, function (newVal) { + assert.equal(newVal, '2,3', 'joined is observable'); + }); + list.shift(); + }); + QUnit.test('list is always updated with the last promise passed to replace (#2136)', function (assert) { + var list = new List(); + var done = assert.async(); + list.replace(new Promise(function (resolve) { + setTimeout(function () { + resolve(['A']); + setTimeout(function () { + assert.equal(list.attr(0), 'B', 'list set to last promise\'s value'); + done(); + }, 10); + }, 20); + })); + list.replace(new Promise(function (resolve) { + setTimeout(function () { + resolve(['B']); + }, 10); + })); + }); + QUnit.test('forEach callback', function (assert) { + var list = new List([]), counter = 0; + list.attr(9, 'foo'); + list.forEach(function (element, index, list) { + counter++; + }); + assert.equal(counter, 1, 'Should not be invoked for uninitialized attr keys'); + }); + QUnit.test('filter with context', function (assert) { + var l = new List([{ id: 1 }]); + var context = {}; + var contextWasCorrect = false; + l.filter(function () { + contextWasCorrect = this === context; + return true; + }, context); + assert.equal(contextWasCorrect, true, 'context was correctly passed'); + }); + QUnit.test('map with context', function (assert) { + var l = new List([{ id: 1 }]); + var context = {}; + var contextWasCorrect = false; + l.map(function () { + contextWasCorrect = this === context; + return true; + }, context); + assert.equal(contextWasCorrect, true, 'context was correctly passed'); + }); + QUnit.test('works with can-reflect', function (assert) { + assert.expect(11); + var a = new Map({ foo: 4 }); + var b = new List([ + 'foo', + 'bar' + ]); + assert.equal(canReflect.getKeyValue(b, '0'), 'foo', 'unbound value'); + var handler = function (newValue) { + assert.equal(newValue, 'quux', 'observed new value'); + }; + assert.ok(!canReflect.isValueLike(b), 'isValueLike is false'); + assert.ok(canReflect.isMapLike(b), 'isMapLike is true'); + assert.ok(canReflect.isListLike(b), 'isListLike is false'); + assert.ok(!canReflect.keyHasDependencies(b, 'length'), 'keyHasDependencies -- false'); + b._computedAttrs['length'] = { + compute: new Observation(function () { + return a.attr('foo'); + }, null) + }; + b._computedAttrs['length'].compute.start(); + assert.ok(canReflect.keyHasDependencies(b, 'length'), 'keyHasDependencies -- true'); + canReflect.onKeysAdded(b, handler); + canReflect.onKeysRemoved(b, handler); + var handlers = b[canSymbol.for('can.meta')].handlers; + assert.ok(handlers.get(['add']).length, 'add handler added'); + assert.ok(handlers.get(['remove']).length, 'remove handler added'); + b.push('quux'); + assert.equal(canReflect.getKeyValue(b, 'length'), '4', 'bound value'); + b.pop(); + }); + QUnit.test('can-reflect setKeyValue', function (assert) { + var a = new Map({ 'a': 'b' }); + canReflect.setKeyValue(a, 'a', 'c'); + assert.equal(a.attr('a'), 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect getKeyDependencies', function (assert) { + var a = new Map({ foo: 4 }); + var b = new List([ + 'foo', + 'bar' + ]); + assert.ok(!canReflect.getKeyDependencies(b, 'length'), 'No dependencies before binding'); + b._computedAttrs.length = { + compute: new Observation(function () { + return a.attr('foo'); + }, null) + }; + b._computedAttrs.length.compute.start(); + assert.ok(canReflect.getKeyDependencies(b, 'length'), 'dependencies exist'); + assert.ok(canReflect.getKeyDependencies(b, 'length').valueDependencies.has(b._computedAttrs.length.compute), 'dependencies returned'); + }); + QUnit.test('registered symbols', function (assert) { + var a = new Map({ 'a': 'a' }); + assert.ok(a[canSymbol.for('can.isMapLike')], 'can.isMapLike'); + assert.equal(a[canSymbol.for('can.getKeyValue')]('a'), 'a', 'can.getKeyValue'); + a[canSymbol.for('can.setKeyValue')]('a', 'b'); + assert.equal(a.attr('a'), 'b', 'can.setKeyValue'); + function handler(val) { + assert.equal(val, 'c', 'can.onKeyValue'); + } + a[canSymbol.for('can.onKeyValue')]('a', handler); + a.attr('a', 'c'); + a[canSymbol.for('can.offKeyValue')]('a', handler); + a.attr('a', 'd'); + }); + QUnit.test('onPatches', function (assert) { + var list = new List([ + 'a', + 'b' + ]); + var PATCHES = [ + [{ + deleteCount: 2, + index: 0, + type: 'splice' + }], + [{ + index: 0, + insert: [ + 'A', + 'B' + ], + deleteCount: 0, + type: 'splice' + }] + ]; + var handlerCalls = 0; + var handler = function (patches) { + assert.deepEqual(patches, PATCHES[handlerCalls], 'patches looked right for ' + handlerCalls); + handlerCalls++; + }; + list[canSymbol.for('can.onPatches')](handler, 'notify'); + list.replace([ + 'A', + 'B' + ]); + list[canSymbol.for('can.offPatches')](handler, 'notify'); + list.replace([ + '1', + '2' + ]); + }); + QUnit.test('can.onInstancePatches basics', function (assert) { + var People = List.extend({}); + var calls = []; + function handler(obj, patches) { + calls.push([ + obj, + patches + ]); + } + People[canSymbol.for('can.onInstancePatches')](handler); + var list = new People([ + 1, + 2 + ]); + list.push(3); + list.attr('count', 8); + People[canSymbol.for('can.offInstancePatches')](handler); + list.push(4); + list.attr('count', 7); + assert.deepEqual(calls, [ + [ + list, + [{ + type: 'splice', + index: 2, + deleteCount: 0, + insert: [3] + }] + ], + [ + list, + [{ + type: 'set', + key: 'count', + value: 8 + }] + ] + ]); + }); + QUnit.test('can.onInstanceBoundChange basics', function (assert) { + var People = List.extend({}); + var calls = []; + function handler(obj, patches) { + calls.push([ + obj, + patches + ]); + } + People[canSymbol.for('can.onInstanceBoundChange')](handler); + var people = new People([]); + var bindHandler = function () { + }; + canReflect.onKeyValue(people, 'length', bindHandler); + canReflect.offKeyValue(people, 'length', bindHandler); + People[canSymbol.for('can.offInstanceBoundChange')](handler); + canReflect.onKeyValue(people, 'length', bindHandler); + canReflect.offKeyValue(people, 'length', bindHandler); + assert.deepEqual(calls, [ + [ + people, + true + ], + [ + people, + false + ] + ]); + }); + QUnit.test('list.sort a simple list', function (assert) { + var myList = new List([ + 'Marshall', + 'Austin', + 'Hyrum' + ]); + myList.sort(); + assert.equal(myList.length, 3); + assert.equal(myList[0], 'Austin'); + assert.equal(myList[1], 'Hyrum'); + assert.equal(myList[2], 'Marshall', 'Basic list was properly sorted.'); + }); + QUnit.test('list.sort a list of objects', function (assert) { + var objList = new List([ + { + id: 1, + name: 'Marshall' + }, + { + id: 2, + name: 'Austin' + }, + { + id: 3, + name: 'Hyrum' + } + ]); + objList.sort(function (a, b) { + if (a.name < b.name) { + return -1; + } else if (a.name > b.name) { + return 1; + } else { + return 0; + } + }); + assert.equal(objList.length, 3); + assert.equal(objList[0].name, 'Austin'); + assert.equal(objList[1].name, 'Hyrum'); + assert.equal(objList[2].name, 'Marshall', 'List of objects was properly sorted.'); + }); + QUnit.test('list.sort a list of objects without losing reference (#137)', function (assert) { + var unSorted = new List([ + { id: 3 }, + { id: 2 }, + { id: 1 } + ]); + var sorted = unSorted.slice(0).sort(function (a, b) { + return a.id > b.id ? 1 : a.id < b.id ? -1 : 0; + }); + assert.equal(unSorted[0], sorted[2], 'items should be equal'); + }); + QUnit.test('list receives patch events', function (assert) { + assert.expect(2); + var list = new List([]); + function handler(patches) { + if (patches[0].index === 0 && patches[0].insert) { + assert.ok(true); + } + } + canReflect.onPatches(list, handler); + list.push('foo'); + list.attr(0, 'bar'); + canReflect.offPatches(list, handler); + }); +}); +/*can-map@4.3.12#can-map_test*/ +define('can-map@4.3.12#can-map_test', [ + 'require', + 'exports', + 'module', + 'can-map', + 'steal-qunit', + 'can-compute', + 'can-observation-recorder', + 'can-construct', + 'can-stache-key', + 'can-reflect', + 'can-symbol', + 'can-queues', + 'can-test-helpers', + 'can-reflect-tests/observables/map-like/type/type' +], function (require, exports, module) { + var Map = require('can-map'); + var QUnit = require('steal-qunit'); + var canCompute = require('can-compute'); + var ObservationRecorder = require('can-observation-recorder'); + var Construct = require('can-construct'); + var observeReader = require('can-stache-key'); + var canReflect = require('can-reflect'); + var canSymbol = require('can-symbol'); + var queues = require('can-queues'); + var testHelpers = require('can-test-helpers'); + QUnit.module('can-map'); + QUnit.test('Basic Map', function (assert) { + assert.expect(4); + var state = new Map({ + category: 5, + productType: 4 + }); + state.bind('change', function (ev, attr, how, val, old) { + assert.equal(attr, 'category', 'correct change name'); + assert.equal(how, 'set'); + assert.equal(val, 6, 'correct'); + assert.equal(old, 5, 'correct'); + }); + state.attr('category', 6); + state.unbind('change'); + }); + QUnit.test('Nested Map', function (assert) { + assert.expect(5); + var me = new Map({ + name: { + first: 'Justin', + last: 'Meyer' + } + }); + assert.ok(me.attr('name') instanceof Map); + me.bind('change', function (ev, attr, how, val, old) { + assert.equal(attr, 'name.first', 'correct change name'); + assert.equal(how, 'set'); + assert.equal(val, 'Brian', 'correct'); + assert.equal(old, 'Justin', 'correct'); + }); + me.attr('name.first', 'Brian'); + me.unbind('change'); + }); + QUnit.test('remove attr', function (assert) { + var state = new Map({ + category: 5, + productType: 4 + }); + state.removeAttr('category'); + assert.deepEqual(Map.keys(state), ['productType'], 'one property'); + }); + QUnit.test('remove attr on key with dot', function (assert) { + var state = new Map({ + 'key.with.dots': 12, + productType: 4 + }); + var state2 = new Map({ + 'key.with.dots': 4, + key: { 'with': { someValue: 20 } } + }); + state.removeAttr('key.with.dots'); + state2.removeAttr('key.with.someValue'); + assert.deepEqual(Map.keys(state), ['productType'], 'one property'); + assert.deepEqual(Map.keys(state2), [ + 'key.with.dots', + 'key' + ], 'two properties'); + assert.deepEqual(Map.keys(state2.key['with']), [], 'zero properties'); + }); + QUnit.test('nested event handlers are not run by changing the parent property (#280)', function (assert) { + var person = new Map({ name: { first: 'Justin' } }); + person.bind('name.first', function (ev, newName) { + assert.ok(false, 'name.first should never be called'); + }); + person.bind('name', function () { + assert.ok(true, 'name event triggered'); + }); + person.attr('name', { first: 'Hank' }); + }); + QUnit.test('cyclical objects (#521)', function (assert) { + var foo = {}; + foo.foo = foo; + var fooed = new Map(foo); + assert.ok(true, 'did not cause infinate recursion'); + assert.ok(fooed.attr('foo') === fooed, 'map points to itself'); + var me = { name: 'Justin' }; + var references = { + husband: me, + friend: me + }; + var ref = new Map(references); + assert.ok(ref.attr('husband') === ref.attr('friend'), 'multiple properties point to the same thing'); + }); + QUnit.test('_cid add to original object', function (assert) { + var map = new Map(), obj = { 'name': 'thecountofzero' }; + map.attr('myObj', obj); + assert.ok(!obj._cid, '_cid not added to original object'); + }); + QUnit.test('Map serialize triggers reading (#626)', function (assert) { + var old = ObservationRecorder.add; + var attributesRead = []; + var readingTriggeredForKeys = false; + ObservationRecorder.add = function (object, attribute) { + if (attribute === '__keys') { + readingTriggeredForKeys = true; + } else { + attributesRead.push(attribute); + } + }; + var testMap = new Map({ + cats: 'meow', + dogs: 'bark' + }); + testMap.serialize(); + assert.ok(attributesRead.indexOf('cats') !== -1 && attributesRead.indexOf('dogs') !== -1, 'map serialization triggered __reading on all attributes'); + assert.ok(readingTriggeredForKeys, 'map serialization triggered __reading for __keys'); + ObservationRecorder.add = old; + }); + QUnit.test('Test top level attributes', function (assert) { + assert.expect(7); + var test = new Map({ + 'my.enable': false, + 'my.item': true, + 'my.count': 0, + 'my.newCount': 1, + 'my': { + 'value': true, + 'nested': { 'value': 100 } + } + }); + assert.equal(test.attr('my.value'), true, 'correct'); + assert.equal(test.attr('my.nested.value'), 100, 'correct'); + assert.ok(test.attr('my.nested') instanceof Map); + assert.equal(test.attr('my.enable'), false, 'falsey (false) value accessed correctly'); + assert.equal(test.attr('my.item'), true, 'truthey (true) value accessed correctly'); + assert.equal(test.attr('my.count'), 0, 'falsey (0) value accessed correctly'); + assert.equal(test.attr('my.newCount'), 1, 'falsey (1) value accessed correctly'); + }); + QUnit.test('serializing cycles', function (assert) { + var map1 = new Map({ name: 'map1' }); + var map2 = new Map({ name: 'map2' }); + map1.attr('map2', map2); + map2.attr('map1', map1); + var res = map1.serialize(); + assert.equal(res.name, 'map1'); + assert.equal(res.map2.name, 'map2'); + }); + QUnit.test('Unbinding from a map with no bindings doesn\'t throw an error (#1015)', function (assert) { + assert.expect(0); + var test = new Map({}); + try { + test.unbind('change'); + } catch (e) { + assert.ok(false, 'No error should be thrown'); + } + }); + QUnit.test('Fast dispatch event still has target and type (#1082)', function (assert) { + assert.expect(4); + var data = new Map({ name: 'CanJS' }); + data.bind('change', function (ev) { + assert.equal(ev.type, 'change'); + assert.equal(ev.target, data); + }); + data.bind('name', function (ev) { + assert.equal(ev.type, 'name'); + assert.equal(ev.target, data); + }); + data.attr('name', 'David'); + }); + QUnit.test('map passed to Map constructor (#1166)', function (assert) { + function y() { + } + var map = new Map({ + x: 1, + y: y + }); + var res = new Map(map); + assert.deepEqual(res.attr(), { + x: 1, + y: y + }, 'has the same properties'); + }); + QUnit.test('constructor passed to scope is threated as a property (#1261)', function (assert) { + var Constructor = Construct.extend({}); + var MyMap = Map.extend({ Todo: Constructor }); + var m = new MyMap(); + assert.equal(m.attr('Todo'), Constructor); + }); + QUnit.test('_bindings count maintained after calling .off() on undefined property (#1490) ', function (assert) { + var map = new Map({ test: 1 }); + map.on('test', function () { + }); + var handlers = map[canSymbol.for('can.meta')].handlers; + assert.equal(handlers.get([]).length, 1, 'The number of bindings is correct'); + map.off('undefined_property'); + assert.equal(handlers.get([]).length, 1, 'The number of bindings is still correct'); + }); + QUnit.test('Should be able to get and set attribute named \'watch\' on Map in Firefox', function (assert) { + var map = new Map({}); + map.attr('watch'); + assert.ok(true, 'can have attribute named \'watch\' on a Map instance'); + }); + QUnit.test('Should be able to get and set attribute named \'unwatch\' on Map in Firefox', function (assert) { + var map = new Map({}); + map.attr('unwatch'); + assert.ok(true, 'can have attribute named \'unwatch\' on a Map instance'); + }); + QUnit.test('should get an empty string property value correctly', function (assert) { + var map = new Map({ + foo: 'foo', + '': 'empty string' + }); + assert.equal(map.attr(''), 'empty string'); + }); + QUnit.test('ObserveReader - can.Construct derived classes should be considered objects, not functions (#450)', function (assert) { + var foostructor = Map.extend({ text: 'bar' }, {}), obj = { + next_level: { + thing: foostructor, + text: 'In the inner context' + } + }, read; + foostructor.self = foostructor; + read = observeReader.read(obj, observeReader.reads('next_level.thing.self.text')); + assert.equal(read.value, 'bar', 'static properties on a can.Construct-based function'); + read = observeReader.read(obj, observeReader.reads('next_level.thing.self'), { isArgument: true }); + assert.ok(read.value === foostructor, 'arguments shouldn\'t be executed'); + }); + QUnit.test('works with can-reflect', function (assert) { + assert.expect(7); + var b = new Map({ 'foo': 'bar' }); + var c = new (Map.extend({ + 'baz': canCompute(function () { + return b.attr('foo'); + }) + }))({ + 'foo': 'bar', + thud: 'baz' + }); + assert.equal(canReflect.getKeyValue(b, 'foo'), 'bar', 'unbound value'); + function bazHandler(newValue) { + assert.equal(newValue, 'quux', 'observed new value on baz'); + canReflect.offKeyValue(c, 'baz', bazHandler); + } + function thudHandler(newValue) { + assert.equal(newValue, 'quux', 'observed new value on thud'); + canReflect.offKeyValue(c, 'thud', thudHandler); + } + assert.ok(!canReflect.isValueLike(c), 'isValueLike is false'); + assert.ok(canReflect.isMapLike(c), 'isMapLike is true'); + assert.ok(!canReflect.isListLike(c), 'isListLike is false'); + canReflect.onKeyValue(c, 'baz', bazHandler); + canReflect.onKeyValue(c, 'thud', thudHandler); + b.attr('foo', 'quux'); + c.attr('thud', 'quux'); + assert.equal(canReflect.getKeyValue(c, 'baz'), 'quux', 'bound value'); + b.attr('foo', 'thud'); + c.attr('baz', 'jeek'); + }); + QUnit.test('onKeyValue and queues', function (assert) { + var b = new Map({ 'foo': 'bar' }); + var order = []; + canReflect.onKeyValue(b, 'foo', function () { + order.push('onKeyValue'); + }, 'notify'); + queues.batch.start(); + queues.mutateQueue.enqueue(function () { + order.push('mutate'); + }); + b.attr('foo', 'baz'); + queues.batch.stop(); + assert.deepEqual(order, [ + 'onKeyValue', + 'mutate' + ]); + }); + QUnit.test('can-reflect setKeyValue', function (assert) { + var a = new Map({ 'a': 'b' }); + canReflect.setKeyValue(a, 'a', 'c'); + assert.equal(a.attr('a'), 'c', 'setKeyValue'); + }); + QUnit.test('can-reflect getKeyDependencies', function (assert) { + var a = new Map({ 'a': 'a' }); + var b = new (Map.extend({ + 'a': canCompute(function () { + return a.attr('a'); + }), + 'b': 'b' + }))(); + assert.ok(canReflect.getKeyDependencies(b, 'a'), 'Dependencies on computed attr'); + assert.ok(!canReflect.getKeyDependencies(b, 'b'), 'No dependencies on data attr'); + b.on('a', function () { + }); + assert.ok(canReflect.getKeyDependencies(b, 'a').valueDependencies.has(b._computedAttrs.a.compute), 'dependencies returned'); + assert.ok(canReflect.getValueDependencies(b._computedAttrs.a.compute).valueDependencies, 'dependencies returned from compute'); + }); + QUnit.test('registered symbols', function (assert) { + var a = new Map({ 'a': 'a' }); + assert.ok(a[canSymbol.for('can.isMapLike')], 'can.isMapLike'); + assert.equal(a[canSymbol.for('can.getKeyValue')]('a'), 'a', 'can.getKeyValue'); + a[canSymbol.for('can.setKeyValue')]('a', 'b'); + assert.equal(a.attr('a'), 'b', 'can.setKeyValue'); + function handler(val) { + assert.equal(this, a); + assert.equal(val, 'c', 'can.onKeyValue'); + } + a[canSymbol.for('can.onKeyValue')]('a', handler); + a.attr('a', 'c'); + a[canSymbol.for('can.offKeyValue')]('a', handler); + a.attr('a', 'd'); + }); + require('can-reflect-tests/observables/map-like/type/type')('Map', function () { + return Map.extend({}); + }); + QUnit.test('can.isBound', function (assert) { + var Person = Map.extend({ + first: 'any', + last: 'any' + }); + var p = new Person(); + assert.ok(!p[canSymbol.for('can.isBound')](), 'not bound'); + }); + QUnit.test('prototype properties', function (assert) { + var MyMap = Map.extend({ letters: 'ABC' }); + var map = new MyMap(); + assert.equal(map.attr('letters'), 'ABC'); + }); + QUnit.test('can read numbers', function (assert) { + var map = new Map({ 0: 'zero' }); + assert.equal(canReflect.getKeyValue(map, 0), 'zero'); + assert.equal(map.attr(0), 'zero'); + canReflect.onKeyValue(0, function handler(ev, newVal) { + assert.equal(newVal, 'one'); + canReflect.offKeyValue(0, handler); + }); + canReflect.setKeyValue(map, 0, 'one'); + }); + QUnit.test('attr should work when remove === \'true\'', function (assert) { + var map = new Map({ 0: 'zero' }); + map.attr({ 1: 'one' }, 'true'); + assert.equal(canReflect.getKeyValue(map, 0), undefined); + assert.equal(map.attr(0), undefined); + assert.equal(canReflect.getKeyValue(map, 1), 'one'); + assert.equal(map.attr(1), 'one'); + }); + QUnit.test('constructor should not bind on __keys (#106)', function (assert) { + var map; + var comp = canCompute(function () { + map = new Map(); + }); + canReflect.onValue(comp, function () { + }); + map.attr('foo', 'bar'); + assert.equal(map.attr('foo'), 'bar', 'map should not be reset'); + }); + QUnit.test('.attr(props) should overwrite if _legacyAttrBehavior is true (#112)', function (assert) { + Map.prototype._legacyAttrBehavior = true; + var myMap1Instance = new Map({ prop1: new Map() }); + var changes = 0; + myMap1Instance.on('prop1', function () { + changes++; + }); + var map2 = new Map({ prop1: 'xyz' }); + myMap1Instance.attr({ 'prop1': map2 }); + delete Map.prototype._legacyAttrBehavior; + assert.equal(changes, 1, 'caused a change event'); + assert.equal(myMap1Instance.attr('prop1'), map2, 'overwrite with maps'); + }); + QUnit.test('.attr() leaves typed instances alone if _legacyAttrBehavior is true (#111)', function (assert) { + Map.prototype._legacyAttrBehavior = true; + function MyClass(value) { + this.value = value; + } + MyClass.prototype.log = function () { + return this.value; + }; + var myMap = new Map({ myClass: new MyClass(5) }); + assert.equal(myMap.attr().myClass, myMap.attr('myClass')); + delete Map.prototype._legacyAttrBehavior; + }); + QUnit.test('.serialize() leaves typed instances alone if _legacyAttrBehavior is true', function (assert) { + function MyClass(value) { + this.value = value; + } + var myMap = new Map({ + _legacyAttrBehavior: true, + myClass: new MyClass('foo') + }); + var ser = myMap.serialize(); + assert.equal(ser.myClass, myMap.attr('myClass')); + }); + QUnit.test('keys with undefined values should not be dropped (#118)', function (assert) { + var obj1 = { 'keepMe': undefined }; + var map = new Map(obj1); + map.attr('foo', undefined); + var keys = Map.keys(map); + assert.deepEqual(keys, [ + 'keepMe', + 'foo' + ]); + }); + QUnit.test('Can assign nested properties that are not CanMaps', function (assert) { + var MyType = function () { + this.one = 'one'; + this.two = 'two'; + this.three = 'three'; + }; + MyType.prototype[canSymbol.for('can.onKeyValue')] = function () { + }; + MyType.prototype[canSymbol.for('can.isMapLike')] = true; + var map = new Map({ + _legacyAttrBehavior: true, + foo: 'bar', + prop: new MyType() + }); + map.attr({ + prop: { + one: '1', + two: '2' + } + }); + assert.equal(map.attr('prop.one'), '1'); + assert.equal(map.attr('prop.two'), '2'); + assert.equal(map.attr('prop.three'), 'three'); + map.attr({ + prop: { + one: 'one', + two: 'two' + } + }, true); + assert.equal(map.attr('prop.one'), 'one'); + assert.equal(map.attr('prop.two'), 'two'); + assert.equal(map.attr('prop.three'), undefined); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get', function (assert) { + var msg = /.* This can cause infinite loops and performance issues.*/; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + var noop = function () { + }; + var Type = Map.extend('Type', { + prop: '', + prop2: '' + }); + var inst = new Type(); + var Type2 = Map.extend('Type2', { + baz: canCompute(function getterThatWrites() { + inst.attr('prop', 'foo'); + return inst.attr('prop2'); + }) + }); + var obs = new Type2(); + canReflect.setName(Type2.prototype.baz, 'a test observation'); + obs.on('baz', noop); + inst.attr('prop2', 'bar'); + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + obs.off('baz', noop); + inst.attr('prop2', 'baz'); + teardownWarn(); + }); + testHelpers.dev.devOnlyTest('warning when setting during a get (batched)', function (assert) { + var msg = /.* This can cause infinite loops and performance issues.*/; + var teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(true, 'warning fired'); + } + }); + var noop = function () { + }; + var Type = Map.extend('Type', { + prop: '', + prop2: '' + }); + var inst = new Type(); + queues.batch.start(); + var Type2 = Map.extend('Type2', { + baz: canCompute(function getterThatWrites() { + inst.attr('prop', 'foo'); + return inst.attr('prop2'); + }) + }); + var obs = new Type2(); + canReflect.setName(Type2.prototype.baz, 'a test observation'); + obs.on('baz', noop); + inst.attr('prop2', 'bar'); + queues.batch.stop(); + assert.equal(teardownWarn(), 1, 'warning correctly generated'); + teardownWarn = testHelpers.dev.willWarn(msg, function (text, match) { + if (match) { + assert.ok(false, 'warning incorrectly fired'); + } + }); + obs.off('baz', noop); + queues.batch.start(); + inst.attr('prop2', 'baz'); + queues.batch.stop(); + teardownWarn(); + }); +}); +/*can-map-define@4.4.0#can-map-define*/ +define('can-map-define@4.4.0#can-map-define', [ + 'require', + 'exports', + 'module', + 'can-log/dev/dev', + 'can-assign', + 'can-event-queue/map/map', + 'can-queues', + 'can-map/map-helpers', + 'can-map', + 'can-compute', + 'can-reflect', + 'can-observation-recorder', + 'can-simple-observable/resolver/resolver', + 'can-symbol', + 'can-list' +], function (require, exports, module) { + 'use strict'; + var dev = require('can-log/dev/dev'); + var extend = require('can-assign'); + var mapEventsMixin = require('can-event-queue/map/map'); + var queues = require('can-queues'); + var mapHelpers = require('can-map/map-helpers'); + var CanMap = require('can-map'); + var compute = require('can-compute'); + var canReflect = require('can-reflect'); + var ObservationRecorder = require('can-observation-recorder'); + var Resolver = require('can-simple-observable/resolver/resolver'); + var canSymbol = require('can-symbol'); + require('can-list'); + var define = {}; + var inSetupSymbol = canSymbol.for('can.initializing'); + var hasDefaultForSerialize = function (defaultDefinition) { + return typeof defaultDefinition === 'object' && 'serialize' in defaultDefinition; + }; + var getDefaultForSerialize = function (defaultDefinition) { + var shouldSerialize = true; + if (hasDefaultForSerialize(defaultDefinition)) { + shouldSerialize = !!defaultDefinition.serialize; + } + return shouldSerialize; + }; + var keysForDefinition = function (definitions) { + var keys = []; + var defaultDefinition = definitions && definitions['*']; + for (var prop in definitions) { + var definition = definitions[prop]; + var shouldSerialize = getDefaultForSerialize(defaultDefinition); + if (typeof definition === 'object' && 'serialize' in definition) { + shouldSerialize = !!definition.serialize; + } else if (typeof definition === 'object' && !hasDefaultForSerialize(defaultDefinition)) { + shouldSerialize = !definition.get; + } + if (shouldSerialize) { + keys.push(prop); + } + } + return keys; + }; + var getPropDefineBehavior = function (behavior, attr, define) { + var prop, defaultProp; + if (define) { + prop = define[attr]; + defaultProp = define['*']; + if (prop && prop[behavior] !== undefined) { + return prop[behavior]; + } else if (defaultProp && defaultProp[behavior] !== undefined) { + return defaultProp[behavior]; + } + } + }; + mapHelpers.define = function (Map, baseDefine) { + var definitions = Map.prototype.define; + if (baseDefine) { + var defines = {}; + mapHelpers.twoLevelDeepExtend(defines, baseDefine); + mapHelpers.twoLevelDeepExtend(defines, definitions); + extend(definitions, defines); + } + Map.defaultGenerators = {}; + for (var prop in definitions) { + var type = definitions[prop].type; + if (typeof type === 'string') { + if (typeof define.types[type] === 'object') { + delete definitions[prop].type; + extend(definitions[prop], define.types[type]); + } + } + if ('value' in definitions[prop]) { + if (typeof definitions[prop].value === 'function') { + Map.defaultGenerators[prop] = definitions[prop].value; + } else { + Map.defaults[prop] = definitions[prop].value; + } + } + if (typeof definitions[prop].Value === 'function') { + (function (Constructor) { + Map.defaultGenerators[prop] = function () { + return new Constructor(); + }; + }(definitions[prop].Value)); + } + } + }; + var oldSetupDefaults = CanMap.prototype._setupDefaults; + CanMap.prototype._setupDefaults = function (obj) { + var defaults = extend({}, oldSetupDefaults.call(this)), propsCommittedToAttr = {}, Map = this.constructor, originalGet = this._get; + this._get = function (originalProp) { + var prop = originalProp.indexOf('.') !== -1 ? originalProp.substr(0, originalProp.indexOf('.')) : originalProp; + if (prop in defaults && !(prop in propsCommittedToAttr)) { + this.attr(prop, defaults[prop]); + propsCommittedToAttr[prop] = true; + } + return originalGet.apply(this, arguments); + }; + for (var prop in Map.defaultGenerators) { + if (!obj || !(prop in obj)) { + defaults[prop] = Map.defaultGenerators[prop].call(this); + } + } + delete this._get; + return defaults; + }; + var proto = CanMap.prototype, oldSet = proto.__set; + proto.__set = function (prop, value, current, success, error) { + var self = this; + var errorCallback = function (errors) { + var stub = error && error.call(self, errors); + if (stub !== false) { + mapEventsMixin.dispatch.call(self, 'error', [ + prop, + errors + ], true); + } + return false; + }, setter = getPropDefineBehavior('set', prop, this.define), getter = getPropDefineBehavior('get', prop, this.define); + if (setter) { + queues.batch.start(); + var setterCalled = false, setValue = setter.call(this, value, function (value) { + if (getter) { + self[prop](value); + } else { + oldSet.call(self, prop, value, current, success, errorCallback); + } + setterCalled = true; + }, errorCallback, getter ? this._computedAttrs[prop].compute.computeInstance.lastSetValue.get() : current); + if (getter) { + if (setValue !== undefined && !setterCalled && setter.length >= 1) { + this._computedAttrs[prop].compute(setValue); + } + queues.batch.stop(); + return; + } else if (setValue === undefined && !setterCalled && setter.length > 1) { + queues.batch.stop(); + return; + } else { + if (!setterCalled) { + oldSet.call(self, prop, setter.length === 0 && setValue === undefined ? value : setValue, current, success, errorCallback); + } + queues.batch.stop(); + return this; + } + } else { + oldSet.call(self, prop, value, current, success, errorCallback); + } + return this; + }; + define.types = { + 'date': function (str) { + var type = typeof str; + if (type === 'string') { + str = Date.parse(str); + return isNaN(str) ? null : new Date(str); + } else if (type === 'number') { + return new Date(str); + } else { + return str; + } + }, + 'number': function (val) { + if (val == null) { + return val; + } + return +val; + }, + 'boolean': function (val) { + if (val == null) { + return val; + } + if (val === 'false' || val === '0' || !val) { + return false; + } + return true; + }, + 'htmlbool': function (val) { + return typeof val === 'string' || !!val; + }, + '*': function (val) { + return val; + }, + 'string': function (val) { + if (val == null) { + return val; + } + return '' + val; + }, + 'compute': { + set: function (newValue, setVal, setErr, oldValue) { + if (newValue && newValue.isComputed) { + return newValue; + } + if (oldValue && oldValue.isComputed) { + oldValue(newValue); + return oldValue; + } + return newValue; + }, + get: function (value) { + return value && value.isComputed ? value() : value; + } + } + }; + var oldType = proto.__type; + proto.__type = function (value, prop) { + var type = getPropDefineBehavior('type', prop, this.define), Type = getPropDefineBehavior('Type', prop, this.define), newValue = value; + if (typeof type === 'string') { + type = define.types[type]; + } + if (type || Type) { + if (type) { + newValue = type.call(this, newValue, prop); + } + if (Type && newValue != null && !(newValue instanceof Type)) { + newValue = new Type(newValue); + } + return newValue; + } else if (canReflect.isPlainObject(newValue) && newValue.define) { + newValue = CanMap.extend(newValue); + newValue = new newValue(); + } + return oldType.call(this, newValue, prop); + }; + var oldRemove = proto.__remove; + proto.__remove = function (prop, current) { + var remove = getPropDefineBehavior('remove', prop, this.define), res; + if (remove) { + queues.batch.start(); + res = remove.call(this, current); + if (res === false) { + queues.batch.stop(); + return; + } else { + res = oldRemove.call(this, prop, current); + queues.batch.stop(); + return res; + } + } + return oldRemove.call(this, prop, current); + }; + var oldSetupComputes = proto._setupComputedProperties; + proto._setupComputedProperties = function () { + oldSetupComputes.apply(this, arguments); + for (var attr in this.define) { + var def = this.define[attr], get = def.get; + if (get) { + mapHelpers.addComputedAttr(this, attr, compute.async(undefined, get, this)); + } + if (def.resolver) { + mapHelpers.addComputedAttr(this, attr, new Resolver(def.resolver, this, def.value)); + } + } + }; + var oldSingleSerialize = proto.___serialize; + var serializeProp = function (map, attr, val) { + var serializer = attr === '*' ? false : getPropDefineBehavior('serialize', attr, map.define); + if (serializer === undefined) { + return oldSingleSerialize.call(map, attr, val); + } else if (serializer !== false) { + return typeof serializer === 'function' ? serializer.call(map, val, attr) : oldSingleSerialize.call(map, attr, val); + } + }; + proto.___serialize = function (name, val) { + return serializeProp(this, name, val); + }; + var oldSerialize = proto.serialize; + proto.serialize = function (property) { + var serialized = oldSerialize.apply(this, arguments); + if (property) { + return serialized; + } + var serializer, val; + for (var attr in this.define) { + if (!(attr in serialized)) { + serializer = this.define && (this.define[attr] && this.define[attr].serialize || this.define['*'] && this.define['*'].serialize); + if (serializer) { + val = serializeProp(this, attr, this.attr(attr)); + if (val !== undefined) { + serialized[attr] = val; + } + } + } + } + return serialized; + }; + canReflect.assignSymbols(proto, { + 'can.hasKey': function (key) { + var defined = this.define && key in this.define; + var dataExists = this._data && key in this._data; + var propExists = key in this; + return defined || dataExists || propExists; + }, + 'can.getOwnEnumerableKeys': function () { + if (!this[inSetupSymbol]) { + ObservationRecorder.add(this, '__keys'); + } + var definedKeys = keysForDefinition(this.define); + var dataKeys = Object.keys(this._data); + var shouldSerialize = getDefaultForSerialize(this.define && this.define['*']); + var enumerable = this.constructor.enumerable; + dataKeys = dataKeys.filter(function (key) { + return enumerable ? shouldSerialize && enumerable[key] !== false : shouldSerialize; + }); + var i, newKey; + for (i = 0; i < dataKeys.length; i++) { + newKey = dataKeys[i]; + if (definedKeys.indexOf(newKey) < 0 && (!this.define || !this.define[newKey])) { + definedKeys.push(dataKeys[i]); + } + } + return definedKeys; + } + }); + module.exports = define; +}); +/*can-map-define@4.4.0#can-map-define_test*/ +define('can-map-define@4.4.0#can-map-define_test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-key/sub/sub', + 'can-map', + 'can-list', + 'can-compute', + 'can-reflect', + './can-map-define', + 'can-reflect-tests/observables/map-like/type/type' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var sub = require('can-key/sub/sub'); + var CanMap = require('can-map'); + var List = require('can-list'); + var compute = require('can-compute'); + var canReflect = require('can-reflect'); + require('./can-map-define'); + QUnit.module('can-map-define'); + QUnit.test('basics set', function (assert) { + var Defined = CanMap.extend({ + define: { + prop: { + set: function (newVal) { + return 'foo' + newVal; + } + } + } + }); + var def = new Defined(); + def.attr('prop', 'bar'); + assert.equal(def.attr('prop'), 'foobar', 'setter works'); + Defined = CanMap.extend({ + define: { + prop: { + set: function (newVal, setter) { + setter('foo' + newVal); + } + } + } + }); + def = new Defined(); + def.attr('prop', 'bar'); + assert.equal(def.attr('prop'), 'foobar', 'setter callback works'); + }); + QUnit.test('basics remove', function (assert) { + var ViewModel = CanMap.extend({ + define: { + makeId: { + remove: function () { + this.removeAttr('models'); + } + }, + models: { + remove: function () { + this.removeAttr('modelId'); + } + }, + modelId: { + remove: function () { + this.removeAttr('years'); + } + }, + years: { + remove: function () { + this.removeAttr('year'); + } + } + } + }); + var mmy = new ViewModel({ + makes: [{ id: 1 }], + makeId: 1, + models: [{ id: 2 }], + modelId: 2, + years: [2010], + year: 2010 + }); + var events = [ + 'year', + 'years', + 'modelId', + 'models', + 'makeId' + ], eventCount = 0, batchNum; + mmy.bind('change', function (ev, attr) { + if (batchNum === undefined) { + batchNum = ev.batchNum; + } + assert.equal(attr, events[eventCount++], 'got correct attribute'); + assert.ok(ev.batchNum && ev.batchNum === batchNum, 'batched'); + }); + mmy.removeAttr('makeId'); + }); + QUnit.test('basics get', function (assert) { + var done = assert.async(); + var Person = CanMap.extend({ + define: { + fullName: { + get: function () { + return this.attr('first') + ' ' + this.attr('last'); + } + } + } + }); + var p = new Person({ + first: 'Justin', + last: 'Meyer' + }); + assert.equal(p.attr('fullName'), 'Justin Meyer', 'sync getter works'); + var Adder = CanMap.extend({ + define: { + more: { + get: function (curVal, setVal) { + var num = this.attr('num'); + setTimeout(function () { + setVal(num + 1); + }, 10); + } + } + } + }); + var callbackCount = 0; + var a = new Adder({ num: 1 }); + var callbackVals = [ + { + newVal: 2, + oldVal: undefined, + next: function next() { + a.attr('num', 2); + } + }, + { + newVal: 3, + oldVal: 2, + next: done + } + ]; + a.bind('more', function (ev, newVal, oldVal) { + var vals = callbackVals[callbackCount++]; + assert.equal(newVal, vals.newVal, 'newVal is correct'); + assert.equal(a.attr('more'), vals.newVal, 'attr value is correct'); + assert.equal(oldVal, vals.oldVal, 'oldVal is correct'); + setTimeout(vals.next, 10); + }); + }); + QUnit.test('basic type', function (assert) { + assert.expect(6); + var Typer = CanMap.extend({ + define: { + arrayWithAddedItem: { + type: function (value) { + if (value && value.push) { + value.push('item'); + } + return value; + } + }, + listWithAddedItem: { + type: function (value) { + if (value && value.push) { + value.push('item'); + } + return value; + }, + Type: List + } + } + }); + var t = new Typer(); + assert.deepEqual(CanMap.keys(t), [ + 'arrayWithAddedItem', + 'listWithAddedItem' + ], 'defined keys'); + var array = []; + t.attr('arrayWithAddedItem', array); + assert.deepEqual(array, ['item'], 'updated array'); + assert.equal(t.attr('arrayWithAddedItem'), array, 'leave value as array'); + t.attr('listWithAddedItem', []); + assert.ok(t.attr('listWithAddedItem') instanceof List, 'convert to List'); + assert.equal(t.attr('listWithAddedItem').attr(0), 'item', 'has item in it'); + t.bind('change', function (ev, attr) { + assert.equal(attr, 'listWithAddedItem.1', 'got a bubbling event'); + }); + t.attr('listWithAddedItem').push('another item'); + }); + QUnit.test('basic Type', function (assert) { + var Foo = function (name) { + this.name = name; + }; + Foo.prototype.getName = function () { + return this.name; + }; + var Typer = CanMap.extend({ define: { foo: { Type: Foo } } }); + var t = new Typer({ foo: 'Justin' }); + assert.equal(t.attr('foo').getName(), 'Justin', 'correctly created an instance'); + var brian = new Foo('brian'); + t.attr('foo', brian); + assert.equal(t.attr('foo'), brian, 'same instances'); + }); + QUnit.test('type converters', function (assert) { + var Typer = CanMap.extend({ + define: { + date: { type: 'date' }, + string: { type: 'string' }, + number: { type: 'number' }, + 'boolean': { type: 'boolean' }, + htmlbool: { type: 'htmlbool' }, + leaveAlone: { type: '*' } + } + }); + var obj = {}; + var t = new Typer({ + date: 1395896701516, + string: 5, + number: '5', + 'boolean': 'false', + htmlbool: '', + leaveAlone: obj + }); + assert.ok(t.attr('date') instanceof Date, 'converted to date'); + assert.equal(t.attr('string'), '5', 'converted to string'); + assert.equal(t.attr('number'), 5, 'converted to number'); + assert.equal(t.attr('boolean'), false, 'converted to boolean'); + assert.equal(t.attr('htmlbool'), true, 'converted to htmlbool'); + assert.equal(t.attr('leaveAlone'), obj, 'left as object'); + t.attr({ 'number': '15' }); + assert.ok(t.attr('number') === 15, 'converted to number'); + }); + QUnit.test('basics value', function (assert) { + var Typer = CanMap.extend({ define: { prop: { value: 'foo' } } }); + assert.equal(new Typer().attr('prop'), 'foo', 'value is used as default value'); + var Typer2 = CanMap.extend({ + define: { + prop: { + value: function () { + return []; + }, + type: '*' + } + } + }); + var t1 = new Typer2(), t2 = new Typer2(); + assert.ok(t1.attr('prop') !== t2.attr('prop'), 'different array instances'); + assert.ok(Array.isArray(t1.attr('prop')), 'its an array'); + }); + QUnit.test('basics Value', function (assert) { + var Typer = CanMap.extend({ + define: { + prop: { + Value: Array, + type: '*' + } + } + }); + var t1 = new Typer(), t2 = new Typer(); + assert.ok(t1.attr('prop') !== t2.attr('prop'), 'different array instances'); + assert.ok(Array.isArray(t1.attr('prop')), 'its an array'); + }); + QUnit.test('setter with no arguments and returns undefined does the default behavior, the setter is for side effects only', function (assert) { + var Typer = CanMap.extend({ + define: { + prop: { + set: function () { + this.attr('foo', 'bar'); + } + } + } + }); + var t = new Typer(); + t.attr('prop', false); + assert.deepEqual(t.attr(), { + foo: 'bar', + prop: false + }); + }); + QUnit.test('type happens before the set', function (assert) { + var MyMap = CanMap.extend({ + define: { + prop: { + type: 'number', + set: function (newValue) { + assert.equal(typeof newValue, 'number', 'got a number'); + return newValue + 1; + } + } + } + }); + var map = new MyMap(); + map.attr('prop', '5'); + assert.equal(map.attr('prop'), 6, 'number'); + }); + QUnit.test('getter and setter work', function (assert) { + assert.expect(5); + var Paginate = CanMap.extend({ + define: { + page: { + set: function (newVal) { + this.attr('offset', (parseInt(newVal) - 1) * this.attr('limit')); + }, + get: function () { + return Math.floor(this.attr('offset') / this.attr('limit')) + 1; + } + } + } + }); + var p = new Paginate({ + limit: 10, + offset: 20 + }); + assert.equal(p.attr('page'), 3, 'page get right'); + p.bind('page', function (ev, newValue, oldValue) { + assert.equal(newValue, 2, 'got new value event'); + assert.equal(oldValue, 3, 'got old value event'); + }); + p.attr('page', 2); + assert.equal(p.attr('page'), 2, 'page set right'); + assert.equal(p.attr('offset'), 10, 'page offset set'); + }); + QUnit.test('getter with initial value', function (assert) { + var comp = compute(1); + var Grabber = CanMap.extend({ + define: { + vals: { + type: '*', + Value: Array, + get: function (current, setVal) { + if (setVal) { + current.push(comp()); + } + return current; + } + } + } + }); + var g = new Grabber(); + assert.equal(g.attr('vals').length, 0, 'zero items in array'); + }); + QUnit.test('serialize basics', function (assert) { + var MyMap = CanMap.extend({ + define: { + name: { + serialize: function () { + return; + } + }, + locations: { serialize: false }, + locationIds: { + get: function () { + var ids = []; + this.attr('locations').forEach(function (location) { + ids.push(location.id); + }); + return ids; + }, + serialize: function (locationIds) { + return locationIds.join(','); + } + }, + bared: { + get: function () { + return this.attr('name') + '+bar'; + }, + serialize: true + }, + ignored: { + get: function () { + return this.attr('name') + '+ignored'; + } + } + } + }); + var map = new MyMap({ name: 'foo' }); + map.attr('locations', [ + { + id: 1, + name: 'Chicago' + }, + { + id: 2, + name: 'LA' + } + ]); + assert.equal(map.attr('locationIds').length, 2, 'get locationIds'); + assert.equal(map.attr('locationIds')[0], 1, 'get locationIds index 0'); + assert.equal(map.attr('locations')[0].id, 1, 'get locations index 0'); + var serialized = map.serialize(); + assert.equal(serialized.locations, undefined, 'locations doesn\'t serialize'); + assert.equal(serialized.locationIds, '1,2', 'locationIds serializes'); + assert.equal(serialized.name, undefined, 'name doesn\'t serialize'); + assert.equal(serialized.bared, 'foo+bar', 'true adds computed props'); + assert.equal(serialized.ignored, undefined, 'computed props are not serialized by default'); + }); + QUnit.test('serialize context', function (assert) { + var context, serializeContext; + var MyMap = CanMap.extend({ + define: { + name: { + serialize: function (obj) { + context = this; + return obj; + } + } + }, + serialize: function () { + serializeContext = this; + CanMap.prototype.serialize.apply(this, arguments); + } + }); + var map = new MyMap(); + map.serialize(); + assert.equal(context, map); + assert.equal(serializeContext, map); + }); + QUnit.test('methods contexts', function (assert) { + var contexts = {}; + var MyMap = CanMap.extend({ + define: { + name: { + value: 'John Galt', + get: function (obj) { + contexts.get = this; + return obj; + }, + remove: function (obj) { + contexts.remove = this; + return obj; + }, + set: function (obj) { + contexts.set = this; + return obj; + }, + serialize: function (obj) { + contexts.serialize = this; + return obj; + }, + type: function (val) { + contexts.type = this; + return val; + } + } + } + }); + var map = new MyMap(); + map.serialize(); + map.removeAttr('name'); + assert.equal(contexts.get, map); + assert.equal(contexts.remove, map); + assert.equal(contexts.set, map); + assert.equal(contexts.serialize, map); + assert.equal(contexts.type, map); + }); + QUnit.test('value generator is not called if default passed', function (assert) { + var TestMap = CanMap.extend({ + define: { + foo: { + value: function () { + throw '"foo"\'s value method should not be called.'; + } + } + } + }); + var tm = new TestMap({ foo: 'baz' }); + assert.equal(tm.attr('foo'), 'baz'); + }); + QUnit.test('Value generator can read other properties', function (assert) { + var Map = CanMap.extend({ + letters: 'ABC', + numbers: [ + 1, + 2, + 3 + ], + define: { + definedLetters: { value: 'DEF' }, + definedNumbers: { + value: [ + 4, + 5, + 6 + ] + }, + generatedLetters: { + value: function () { + return 'GHI'; + } + }, + generatedNumbers: { + value: function () { + return new List([ + 7, + 8, + 9 + ]); + } + }, + firstLetter: { + value: function () { + return this.attr('letters').substr(0, 1); + } + }, + firstNumber: { + value: function () { + return this.attr('numbers.0'); + } + }, + middleLetter: { + value: function () { + return this.attr('definedLetters').substr(1, 1); + } + }, + middleNumber: { + value: function () { + return this.attr('definedNumbers.1'); + } + }, + lastLetter: { + value: function () { + return this.attr('generatedLetters').substr(2, 1); + } + }, + lastNumber: { + value: function () { + return this.attr('generatedNumbers.2'); + } + } + } + }); + var map = new Map(); + var prefix = 'Was able to read dependent value from '; + assert.equal(map.attr('firstLetter'), 'A', prefix + 'traditional CanMap style property definition'); + assert.equal(map.attr('firstNumber'), 1, prefix + 'traditional CanMap style property definition'); + assert.equal(map.attr('middleLetter'), 'E', prefix + 'define plugin style default property definition'); + assert.equal(map.attr('middleNumber'), 5, prefix + 'define plugin style default property definition'); + assert.equal(map.attr('lastLetter'), 'I', prefix + 'define plugin style generated default property definition'); + assert.equal(map.attr('lastNumber'), 9, prefix + 'define plugin style generated default property definition'); + }); + QUnit.test('default behaviors with "*" work for attributes', function (assert) { + assert.expect(9); + var DefaultMap = CanMap.extend({ + define: { + someNumber: { value: '5' }, + '*': { + type: 'number', + serialize: function (value) { + return '' + value; + }, + set: function (newVal) { + assert.ok(true, 'set called'); + return newVal; + }, + remove: function (currentVal) { + assert.ok(true, 'remove called'); + return false; + } + } + } + }); + var map = new DefaultMap(), serializedMap; + assert.equal(map.attr('someNumber'), 5, 'value of someNumber should be converted to a number'); + map.attr('number', '10'); + assert.equal(map.attr('number'), 10, 'value of number should be converted to a number'); + map.removeAttr('number'); + assert.equal(map.attr('number'), 10, 'number should not be removed'); + serializedMap = map.serialize(); + assert.equal(serializedMap.number, '10', 'number serialized as string'); + assert.equal(serializedMap.someNumber, '5', 'someNumber serialized as string'); + assert.equal(serializedMap['*'], undefined, '"*" is not a value in serialized object'); + }); + QUnit.test('models properly serialize with default behaviors', function (assert) { + var DefaultMap = CanMap.extend({ + define: { + name: { value: 'Alex' }, + shirt: { + value: 'blue', + serialize: true + }, + '*': { serialize: false } + } + }); + var map = new DefaultMap({ + age: 10, + name: 'John' + }), serializedMap = map.serialize(); + assert.equal(serializedMap.age, undefined, 'age doesn\'t exist'); + assert.equal(serializedMap.name, undefined, 'name doesn\'t exist'); + assert.equal(serializedMap.shirt, 'blue', 'shirt exists'); + }); + QUnit.test('nested define', function (assert) { + var nailedIt = 'Nailed it'; + var Example = CanMap.extend({}, { define: { name: { value: nailedIt } } }); + var NestedMap = CanMap.extend({}, { + define: { + isEnabled: { value: true }, + test: { Value: Example }, + examples: { + value: { + define: { + one: { Value: Example }, + two: { value: { define: { deep: { Value: Example } } } } + } + } + } + } + }); + var nested = new NestedMap(); + assert.equal(nested.attr('test.name'), nailedIt); + assert.equal(nested.attr('examples.one.name'), nailedIt); + assert.equal(nested.attr('examples.two.deep.name'), nailedIt); + assert.ok(nested.attr('test') instanceof Example); + assert.ok(nested.attr('examples.one') instanceof Example); + assert.ok(nested.attr('examples.two.deep') instanceof Example); + }); + QUnit.test('Can make an attr alias a compute (#1470)', function (assert) { + assert.expect(9); + var computeValue = compute(1); + var GetMap = CanMap.extend({ + define: { + value: { + set: function (newValue, setVal, setErr, oldValue) { + if (newValue.isComputed) { + return newValue; + } + if (oldValue && oldValue.isComputed) { + oldValue(newValue); + return oldValue; + } + return newValue; + }, + get: function (value) { + return value && value.isComputed ? value() : value; + } + } + } + }); + var getMap = new GetMap(); + getMap.attr('value', computeValue); + assert.equal(getMap.attr('value'), 1); + var bindCallbacks = 0; + getMap.bind('value', function (ev, newVal, oldVal) { + switch (bindCallbacks) { + case 0: + assert.equal(newVal, 2, '0 - bind called with new val'); + assert.equal(oldVal, 1, '0 - bind called with old val'); + break; + case 1: + assert.equal(newVal, 3, '1 - bind called with new val'); + assert.equal(oldVal, 2, '1 - bind called with old val'); + break; + case 2: + assert.equal(newVal, 4, '2 - bind called with new val'); + assert.equal(oldVal, 3, '2 - bind called with old val'); + break; + } + bindCallbacks++; + }); + computeValue(2); + getMap.attr('value', 3); + assert.equal(getMap.attr('value'), 3, 'read value is 3'); + assert.equal(computeValue(), 3, 'the compute value is 3'); + var newComputeValue = compute(4); + getMap.attr('value', newComputeValue); + }); + QUnit.test('setting a value of a property with type "compute" triggers change events', function (assert) { + var handler; + var message = 'The change event passed the correct {prop} when set with {method}'; + var createChangeHandler = function (expectedOldVal, expectedNewVal, method) { + return function (ev, newVal, oldVal) { + var subs = { + prop: 'newVal', + method: method + }; + assert.equal(newVal, expectedNewVal, sub(message, subs)); + subs.prop = 'oldVal'; + assert.equal(oldVal, expectedOldVal, sub(message, subs)); + }; + }; + var ComputableMap = CanMap.extend({ define: { computed: { type: 'compute' } } }); + var computed = compute(0); + var m1 = new ComputableMap({ computed: computed }); + assert.equal(m1.attr('computed'), 0, 'm1 is 1'); + handler = createChangeHandler(0, 1, '.attr(\'computed\', newVal)'); + m1.bind('computed', handler); + m1.attr('computed', 1); + m1.unbind('computed', handler); + handler = createChangeHandler(1, 2, 'computed()'); + m1.bind('computed', handler); + computed(2); + m1.unbind('computed', handler); + }); + QUnit.test('replacing the compute on a property with type "compute"', function (assert) { + var compute1 = compute(0); + var compute2 = compute(1); + var ComputableMap = CanMap.extend({ define: { computable: { type: 'compute' } } }); + var m = new ComputableMap(); + m.attr('computable', compute1); + assert.equal(m.attr('computable'), 0, 'compute1 readable via .attr()'); + m.attr('computable', compute2); + assert.equal(m.attr('computable'), 1, 'compute2 readable via .attr()'); + }); + QUnit.test('value and get (#1521)', function (assert) { + var MyMap = CanMap.extend({ + define: { + data: { + value: function () { + return new List(['test']); + } + }, + size: { + value: 1, + get: function (val) { + var list = this.attr('data'); + var length = list.attr('length'); + return val + length; + } + } + } + }); + var map = new MyMap({}); + assert.equal(map.attr('size'), 2); + }); + QUnit.test('One event on getters (#1585)', function (assert) { + var AppState = CanMap.extend({ + define: { + person: { + get: function (lastSetValue, setAttrValue) { + if (lastSetValue) { + return lastSetValue; + } else if (this.attr('personId')) { + setAttrValue(new CanMap({ + name: 'Jose', + id: 5 + })); + } else { + return null; + } + } + } + } + }); + var appState = new AppState(); + var personEvents = 0; + appState.bind('person', function (ev, person) { + personEvents++; + }); + appState.attr('personId', 5); + appState.attr('person', new CanMap({ name: 'Julia' })); + assert.equal(personEvents, 2); + }); + QUnit.test('Can read a defined property with a set/get method (#1648)', function (assert) { + var Map = CanMap.extend({ + define: { + foo: { + value: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + } + }); + var map = new Map(); + assert.equal(map.attr('foo'), '', 'Calling .attr(\'foo\') returned the correct value'); + map.attr('foo', 'baz'); + assert.equal(map.attr('foo'), 'baz', 'Calling .attr(\'foo\') returned the correct value'); + }); + QUnit.test('Can bind to a defined property with a set/get method (#1648)', function (assert) { + assert.expect(3); + var Map = CanMap.extend({ + define: { + foo: { + value: '', + set: function (setVal) { + return setVal; + }, + get: function (lastSetVal) { + return lastSetVal; + } + } + } + }); + var map = new Map(); + map.bind('foo', function () { + assert.ok(true, 'Bound function is called'); + }); + assert.equal(map.attr('foo'), '', 'Calling .attr(\'foo\') returned the correct value'); + map.attr('foo', 'baz'); + assert.equal(map.attr('foo'), 'baz', 'Calling .attr(\'foo\') returned the correct value'); + }); + QUnit.test('type converters handle null and undefined in expected ways (1693)', function (assert) { + var Typer = CanMap.extend({ + define: { + date: { + type: 'date', + value: 'Mon Jul 30 2018 11:57:14 GMT-0500 (Central Daylight Time)' + }, + string: { + type: 'string', + value: 'mudd' + }, + number: { + type: 'number', + value: 42 + }, + 'boolean': { + type: 'boolean', + value: false + }, + htmlbool: { + type: 'htmlbool', + value: true + }, + leaveAlone: { type: '*' } + } + }); + var t = new Typer().attr({ + date: undefined, + string: undefined, + number: undefined, + 'boolean': undefined, + htmlbool: undefined, + leaveAlone: undefined + }); + assert.equal(t.attr('date'), undefined, 'converted to date'); + assert.equal(t.attr('string'), undefined, 'converted to string'); + assert.equal(t.attr('number'), undefined, 'converted to number'); + assert.equal(t.attr('boolean'), undefined, 'converted to boolean'); + assert.equal(t.attr('htmlbool'), false, 'converted to htmlbool'); + assert.equal(t.attr('leaveAlone'), undefined, 'left as object'); + t = new Typer().attr({ + date: null, + string: null, + number: null, + 'boolean': null, + htmlbool: null, + leaveAlone: null + }); + assert.equal(t.attr('date'), null, 'converted to date'); + assert.equal(t.attr('string'), null, 'converted to string'); + assert.equal(t.attr('number'), null, 'converted to number'); + assert.equal(t.attr('boolean'), null, 'converted to boolean'); + assert.equal(t.attr('htmlbool'), false, 'converted to htmlbool'); + assert.equal(t.attr('leaveAlone'), null, 'left as object'); + }); + QUnit.test('Initial value does not call getter', function (assert) { + assert.expect(0); + var Map = CanMap.extend({ + define: { + count: { + get: function (lastVal) { + assert.ok(false, 'Should not be called'); + return lastVal; + } + } + } + }); + new Map({ count: 100 }); + }); + QUnit.test('getters produce change events', function (assert) { + var Map = CanMap.extend({ + define: { + count: { + get: function (lastVal) { + return lastVal; + } + } + } + }); + var map = new Map(); + map.bind('change', function () { + assert.ok(true, 'change called'); + }); + map.attr('count', 22); + }); + QUnit.test('Asynchronous virtual properties cause extra recomputes (#1915)', function (assert) { + var done = assert.async(); + var ran = false; + var VM = CanMap.extend({ + define: { + foo: { + get: function (lastVal, setVal) { + setTimeout(function () { + if (setVal) { + setVal(5); + } + }, 10); + } + }, + bar: { + get: function () { + var foo = this.attr('foo'); + if (foo) { + if (ran) { + assert.ok(false, 'Getter ran twice'); + } + ran = true; + return foo * 2; + } + } + } + } + }); + var vm = new VM(); + vm.bind('bar', function () { + }); + setTimeout(function () { + assert.equal(vm.attr('bar'), 10); + done(); + }, 200); + }); + QUnit.test('double get in a compute (#2230)', function (assert) { + var VM = CanMap.extend({ + define: { + names: { + get: function (val, setVal) { + assert.ok(setVal, 'setVal passed'); + return 'Hi!'; + } + } + } + }); + var vm = new VM(); + var c = compute(function () { + return vm.attr('names'); + }); + c.bind('change', function () { + }); + }); + QUnit.test('nullish values are not converted for Type', function (assert) { + var VM = CanMap.extend({ + define: { + map: { Type: CanMap }, + notype: {} + } + }); + var vm = new VM({ + num: 1, + bool: true, + htmlbool: 'foo', + str: 'foo', + date: Date.now(), + map: {}, + notype: {} + }); + assert.ok(vm.attr('map') instanceof CanMap, 'map is a Map'); + assert.ok(vm.attr('notype') instanceof CanMap, 'notype is a Map'); + vm.attr({ + map: null, + notype: null + }); + assert.equal(vm.attr('map'), null, 'map is null'); + assert.equal(vm.attr('map'), null, 'notype is null'); + }); + QUnit.test('Wildcard serialize doesn\'t apply to getter properties (#4)', function (assert) { + var VM = CanMap.extend({ + define: { + explicitlySerialized: { + get: function () { + return true; + }, + serialize: true + }, + implicitlySerialized: { + get: function () { + return true; + } + }, + '*': { serialize: true } + } + }); + var vm = new VM(); + vm.bind('change', function () { + }); + assert.deepEqual(vm.serialize(), { + explicitlySerialized: true, + implicitlySerialized: true + }); + }); + QUnit.test('compute props can be set to null or undefined (#2372)', function (assert) { + var VM = CanMap.extend({ define: { foo: { type: 'compute' } } }); + var vmNull = new VM({ foo: null }); + assert.equal(vmNull.foo, null, 'foo is null, no error thrown'); + var vmUndef = new VM({ foo: undefined }); + assert.equal(vmUndef.foo, undefined, 'foo is null, no error thrown'); + }); + QUnit.test('can inherit computes from another map (#2)', function (assert) { + assert.expect(4); + var string1 = 'a string'; + var string2 = 'another string'; + var MapA = CanMap.extend({ + define: { + propA: { + get: function () { + return string1; + } + }, + propB: { + get: function () { + return string1; + }, + set: function (newVal) { + assert.equal(newVal, string1, 'set was called'); + } + } + } + }); + var MapB = MapA.extend({ + define: { + propC: { + get: function () { + return string2; + } + }, + propB: { + get: function () { + return string2; + } + } + } + }); + var map = new MapB(); + assert.equal(map.attr('propC'), string2, 'props only in the child have the correct values'); + assert.equal(map.attr('propB'), string2, 'props in both have the child values'); + assert.equal(map.attr('propA'), string1, 'props only in the parent have the correct values'); + map.attr('propB', string1); + }); + QUnit.test('can inherit primitive values from another map (#2)', function (assert) { + var string1 = 'a'; + var string2 = 'b'; + var MapA = CanMap.extend({ + define: { + propA: { value: string1 }, + propB: { value: string1 } + } + }); + var MapB = MapA.extend({ + define: { + propC: { value: string2 }, + propB: { value: string2 } + } + }); + var map = new MapB(); + assert.equal(map.propC, string2, 'props only in the child have the correct values'); + assert.equal(map.propB, string2, 'props in both have the child values'); + assert.equal(map.propA, string1, 'props only in the parent have the correct values'); + }); + QUnit.test('can inherit object values from another map (#2)', function (assert) { + var object1 = { a: 'a' }; + var object2 = { b: 'b' }; + var MapA = CanMap.extend({ + define: { + propA: { + get: function () { + return object1; + } + }, + propB: { + get: function () { + return object1; + } + } + } + }); + var MapB = MapA.extend({ + define: { + propB: { + get: function () { + return object2; + } + }, + propC: { + get: function () { + return object2; + } + } + } + }); + var map = new MapB(); + assert.equal(map.attr('propC'), object2, 'props only in the child have the correct values'); + assert.equal(map.attr('propB'), object2, 'props in both have the child values'); + assert.equal(map.attr('propA'), object1, 'props only in the parent have the correct values'); + }); + QUnit.test('can set properties to undefined', function (assert) { + var MyMap = CanMap.extend({ + define: { + foo: { + set: function (newVal) { + return newVal; + } + } + } + }); + var map = new MyMap(); + map.attr('foo', 'bar'); + assert.equal(map.attr('foo'), 'bar', 'foo should be bar'); + map.attr('foo', undefined); + assert.equal(typeof map.attr('foo'), 'undefined', 'foo should be undefined'); + }); + QUnit.test('subclass defines do not affect superclass ones', function (assert) { + var VM = CanMap.extend({ + define: { + foo: { + type: 'string', + value: 'bar' + } + } + }); + var VM2 = VM.extend({ define: { foo: { value: 'baz' } } }); + var VM2a = VM.extend({}); + var VM2b = VM.extend({ + define: { + foo: { + get: function () { + return 'quux'; + } + } + } + }); + var VM2c = VM.extend({ + define: { + foo: { + type: function (oldVal) { + return oldVal + 'thud'; + } + } + } + }); + assert.equal(new VM().attr('foo'), 'bar', 'correct define on parent class object'); + assert.equal(new VM2().attr('foo'), 'baz', 'correct define on redefined child class object'); + assert.equal(new VM2a().attr('foo'), 'bar', 'correct define on non-redefined child class object'); + assert.equal(new VM2b().attr('foo'), 'quux', 'correct define on child class object with different define'); + assert.equal(new VM2c().attr('foo'), 'barthud', 'correct define on child class object with extending define'); + }); + QUnit.test('value function not set on constructor defaults', function (assert) { + var MyMap = CanMap.extend({ + define: { + propA: { + value: function () { + return 1; + } + } + } + }); + var map = new MyMap(); + assert.equal(MyMap.defaults.propA, undefined, 'Generator function does not result in property set on defaults'); + assert.notEqual(MyMap.defaultGenerators.propA, undefined, 'Generator function set on defaultGenerators'); + assert.equal(map.attr('propA'), 1, 'Instance value set properly'); + }); + QUnit.test('can.hasKey', function (assert) { + var Parent = CanMap.extend({ + define: { + parentProp: { type: '*' }, + parentDerivedProp: { + get: function () { + if (this.parentProp) { + return 'parentDerived'; + } + } + } + }, + parentFunction: function () { + return 'parentFunction return value'; + } + }); + var VM = Parent.extend({ + define: { + prop: { type: '*' }, + derivedProp: { + get: function () { + if (this.prop) { + return 'derived'; + } + } + } + }, + aFunction: function () { + return 'aFunction return value'; + } + }); + var vm = new VM(); + assert.equal(canReflect.hasKey(vm, 'prop'), true, 'vm.hasKey(\'prop\') true'); + assert.equal(canReflect.hasKey(vm, 'derivedProp'), true, 'vm.hasKey(\'derivedProp\') true'); + assert.equal(canReflect.hasKey(vm, 'parentProp'), true, 'vm.hasKey(\'parentProp\') true'); + assert.equal(canReflect.hasKey(vm, 'parentDerivedProp'), true, 'vm.hasKey(\'parentDerivedProp\') true'); + assert.equal(canReflect.hasKey(vm, 'anotherProp'), false, 'vm.hasKey(\'anotherProp\') false'); + assert.equal(canReflect.hasKey(vm, 'aFunction'), true, 'vm.hasKey(\'aFunction\') true'); + assert.equal(canReflect.hasKey(vm, 'parentFunction'), true, 'vm.hasKey(\'parentFunction\') true'); + vm.attr('lateProp', 'something'); + assert.equal(canReflect.hasKey(vm, 'lateProp'), true, 'vm.hasKey(\'lateProp\') true'); + }); + QUnit.test('can.getOwnEnumerableKeys', function (assert) { + var ParentMap = CanMap.extend({ + define: { + parentNoEnum: { + serialize: false, + value: 'parent_no' + }, + parentEnum: { + serialize: true, + value: 'parent_yes' + }, + parentEnumByDefault: { value: 'maybe' }, + parentEnumGetter: { + get: function () { + return 'parent_get'; + } + } + } + }); + var VM = ParentMap.extend({ + define: { + notEnumerable: { + serialize: false, + value: 'no' + }, + enumerableProp: { + serialize: true, + value: 'yes' + }, + enumByDefault: { value: 'maybe' }, + enumGetter: { + get: function () { + return 'got'; + } + } + } + }); + var vm = new VM(); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'enumByDefault', + 'parentEnum', + 'parentEnumByDefault' + ], 'vm.getOwnEnumerableKeys()'); + vm.attr('lateProp', true); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'enumByDefault', + 'parentEnum', + 'parentEnumByDefault', + 'lateProp' + ], 'vm.getOwnEnumerableKeys() with late prop'); + }); + QUnit.test('can.getOwnEnumerableKeys works without define (#81)', function (assert) { + var VM = CanMap.extend({}); + var vm = new VM({ foo: 'bar' }); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['foo'], 'without define'); + vm.attr('abc', 'xyz'); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'foo', + 'abc' + ], 'without define, with late prop'); + VM = CanMap.extend({ define: {} }); + vm = new VM({ foo: 'bar' }); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['foo'], 'with empty define'); + vm.attr('abc', 'xyz'); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'foo', + 'abc' + ], 'with empty define, with late prop'); + }); + QUnit.test('can.getOwnEnumerableKeys works with null', function (assert) { + var VM = CanMap.extend({}); + var vm = new VM({ foo: null }); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['foo'], 'getOwnEnumerableKeys works with null'); + }); + require('can-reflect-tests/observables/map-like/type/type')('CanMap / can-map-define', function () { + return CanMap.extend({}); + }); + QUnit.test('can.getOwnEnumerableKeys with default behavior', function (assert) { + var VM = CanMap.extend({ + define: { + '*': { serialize: false }, + notEnumerable: { value: 'no' }, + enumerableProp: { + serialize: true, + value: 'yes' + }, + notEnumerable2: { + serialize: false, + value: 'maybe' + }, + enumGetter: { + get: function () { + return 'got'; + } + } + } + }); + var vm = new VM(); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['enumerableProp'], 'vm.getOwnEnumerableKeys()'); + }); + QUnit.test('can.getOwnEnumerableKeys with default behavior and late set properties', function (assert) { + var VM = CanMap.extend({ + define: { + '*': { serialize: false }, + notEnumerable: { value: 'no' }, + enumerableProp: { + serialize: true, + value: 'yes' + } + } + }); + var vm = new VM(); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['enumerableProp'], 'getOwnEnumerableKeys() should return explicitly serializable properties'); + vm.attr('lateProperty', true); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), ['enumerableProp'], 'late set properties should inherit default behavior'); + }); + QUnit.test('can.getOwnEnumerableKeys with default behavior, nested maps and late set props', function (assert) { + var ParentMap = CanMap.extend({ + define: { + parentNoEnum: { + serialize: false, + value: 'parent_no' + }, + parentEnum: { + serialize: true, + value: 'parent_yes' + }, + parentEnumByDefault: { value: 'maybe' }, + parentEnumGetter: { + get: function () { + return 'parent_get'; + } + } + } + }); + var VM = ParentMap.extend({ + define: { + '*': { serialize: false }, + notEnumerable: { + serialize: false, + value: 'no' + }, + enumerableProp: { + serialize: true, + value: 'yes' + }, + alsoNotEnumerable: { value: 'maybe' }, + enumGetter: { + get: function () { + return 'got'; + } + } + } + }); + var vm = new VM(); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'parentEnum' + ], 'vm.getOwnEnumerableKeys()'); + vm.attr('lateProperty', true); + assert.deepEqual(canReflect.getOwnEnumerableKeys(vm), [ + 'enumerableProp', + 'parentEnum' + ], 'late added properties should inherit default behavior'); + }); + QUnit.test('resolver behavior: with counter (#96)', function (assert) { + var Person = CanMap.extend('Person', { + define: { + name: { type: 'string' }, + nameChangedCount: { + resolver: function (prop) { + var count = prop.resolve(0); + prop.listenTo('name', function () { + prop.resolve(++count); + }); + } + } + } + }); + var me = new Person(); + assert.equal(me.attr('nameChangedCount'), 0, 'unbound value'); + me.attr('name', 'first'); + assert.equal(me.attr('nameChangedCount'), 0, 'unbound value'); + me.on('nameChangedCount', function (ev, newVal, oldVal) { + assert.equal(newVal, 1, 'updated count'); + assert.equal(oldVal, 0, 'updated count from old value'); + }); + me.attr('name', 'second'); + assert.equal(me.attr('nameChangedCount'), 1, 'bound value'); + }); +}); +/*can-fixture@3.1.7#test/matches-test*/ +define('can-fixture@3.1.7#test/matches-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + '../matches' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var matches = require('../matches'); + QUnit.test('core.defaultCompare', function (assert) { + var same = matches.request({ url: '/thingers/5' }, { url: '/thingers/{id}' }); + assert.ok(same, 'they are similar'); + same = matches.request({ url: '/thingers/5' }, { url: '/thingers' }); + assert.ok(!same, 'they are not the same'); + }); + QUnit.test('core.matches', function (assert) { + var same = matches.matches({ url: '/thingers/5' }, { url: '/thingers/{id}' }); + assert.ok(same, 'similar'); + same = matches.matches({ + url: '/thingers/5', + type: 'get' + }, { url: '/thingers/{id}' }); + assert.ok(same, 'similar with extra pops on settings'); + var exact = matches.matches({ + url: '/thingers/5', + type: 'get' + }, { url: '/thingers/{id}' }, true); + assert.ok(!exact, 'not exact'); + exact = matches.matches({ url: '/thingers/5' }, { url: '/thingers/5' }, true); + assert.ok(exact, 'exact'); + }); +}); +/*can-fixture@3.1.7#test/store-test*/ +define('can-fixture@3.1.7#test/store-test', [ + 'require', + 'exports', + 'module', + 'steal-qunit', + 'can-fixture', + 'can-query-logic', + 'can-reflect' +], function (require, exports, module) { + var QUnit = require('steal-qunit'); + var fixture = require('can-fixture'); + var QueryLogic = require('can-query-logic'); + var canReflect = require('can-reflect'); + QUnit.module('can-fixture.store'); + QUnit.test('createInstance, destroyInstance, updateInstance', function (assert) { + var store = fixture.store([{ + id: 0, + name: 'foo' + }], new QueryLogic({ identity: ['id'] })); + var done = assert.async(); + store.createInstance({ name: 'bar' }).then(function (instance) { + var data = store.getList({}); + assert.deepEqual(data, { + count: 2, + data: [ + { + id: 0, + name: 'foo' + }, + { + id: 1, + name: 'bar' + } + ] + }); + return store.updateInstance({ + id: 1, + name: 'updated' + }); + }).then(function (instance) { + var data = store.getList({}); + assert.deepEqual(data, { + count: 2, + data: [ + { + id: 0, + name: 'foo' + }, + { + id: 1, + name: 'updated' + } + ] + }); + return store.destroyInstance(instance); + }).then(function () { + var data = store.getList({}); + assert.deepEqual(data, { + count: 1, + data: [{ + id: 0, + name: 'foo' + }] + }); + done(); + }); + }); + QUnit.test('anything with a schema will be converted to a queryLogic automatically', function (assert) { + var store = fixture.store([{ + _id: 0, + name: 'foo' + }], { identity: ['id'] }); + var res = store.get({ _id: 0 }); + assert.ok(res, 'an object works'); + var type = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + return { identity: ['id'] }; + } + }); + store = fixture.store([{ + _id: 0, + name: 'foo' + }], type); + res = store.get({ _id: 0 }); + assert.ok(res, 'an object works'); + }); + QUnit.test('createData, destroyData, updateData', function (assert) { + var store = fixture.store([{ + id: 0, + name: 'foo' + }], new QueryLogic({ identity: ['id'] })); + var done = assert.async(); + store.createData({ data: { name: 'bar' } }, function (instance) { + assert.deepEqual(instance, { + id: 1, + name: 'bar' + }); + done(); + }); + }); + QUnit.test('createData with a string id', function (assert) { + var store = fixture.store([{ + id: 'helloorld', + name: 'foo' + }], new QueryLogic({ identity: ['id'] })); + var done = assert.async(); + store.createData({ data: { name: 'bar' } }, function (instance) { + assert.deepEqual(instance, { + id: '1', + name: 'bar' + }); + done(); + }); + }); +}); +/*can-set-legacy@1.0.1#can-set-legacy*/ +define('can-set-legacy@1.0.1#can-set-legacy', [ + 'require', + 'exports', + 'module', + 'can-query-logic', + 'can-reflect', + 'can-key/transform/transform', + 'can-key/delete/delete', + 'can-key/get/get', + 'can-query-logic/src/helpers', + 'can-query-logic/src/types/make-enum', + 'can-query-logic/src/set' +], function (require, exports, module) { + var Query = require('can-query-logic'); + var canReflect = require('can-reflect'); + var transform = require('can-key/transform/transform'); + var deleteKey = require('can-key/delete/delete'); + var getKey = require('can-key/get/get'); + var helpers = require('can-query-logic/src/helpers'); + var makeEnum = require('can-query-logic/src/types/make-enum'); + var SET = require('can-query-logic/src/set'); + var IsBoolean = function () { + }; + makeEnum(IsBoolean, [ + true, + false + ], function (value) { + if (value === 'true') { + return true; + } else if (value === 'false') { + return false; + } else { + return value; + } + }); + function hasKey(obj, keys, parent, parentKey) { + if (obj && typeof obj === 'object') { + for (var key in obj) { + if (keys[key]) { + if (typeof keys[key] === 'function') { + parent[parentKey] = keys[key](obj); + } else { + return true; + } + } else { + if (hasKey(obj[key], keys, obj, key)) { + return true; + } + } + } + } + return false; + } + function convertToJSONAPISort(sortPropValue) { + var parts = sortPropValue.split(' '); + var isDesc = (parts[1] || '').toLowerCase() === 'desc'; + return isDesc ? '-' + parts[0] : parts[0]; + } + function convertToLegacySort(value) { + var result = helpers.sortData(value); + return result.desc ? '-' + result.prop : result.prop; + } + var defaultAlgebra; + var set = { + UNIVERSAL: SET.UNIVERSAL, + EMPTY: SET.EMPTY, + UNDEFINABLE: SET.UNDEFINABLE, + UNKNOWABLE: SET.UNKNOWABLE, + Algebra: function () { + var mutators = { + schema: [], + hydrate: [], + serialize: [] + }; + canReflect.eachIndex(arguments, function (value) { + for (var prop in value) { + if (mutators[prop]) { + mutators[prop].push(value[prop]); + } else { + throw new Error('can-query-logic: This type of configuration is not supported. Please use can-query-logic directly.'); + } + } + }); + var obj = canReflect.assignSymbols({}, { + 'can.getSchema': function () { + var schema = { + kind: 'record', + identity: [], + keys: {} + }; + mutators.schema.forEach(function (updateSchema) { + updateSchema(schema); + }); + if (!schema.identity.length) { + schema.identity.push('id'); + } + return schema; + } + }); + return new Query(obj, { + toQuery: function (data) { + return mutators.hydrate.reduce(function (last, hydrator) { + return hydrator(last); + }, { filter: data }); + }, + toParams: function (data) { + if (SET.isSpecial(data)) { + return data; + } + if (Array.isArray(data.filter)) { + return SET.UNDEFINABLE; + } + var filter = data.filter || {}; + if (hasKey(filter, { + '$ne': true, + '$in': function (val) { + return val.$in; + } + })) { + return SET.UNDEFINABLE; + } + var out = mutators.serialize.reduce(function (last, serializer) { + return serializer(last); + }, data); + filter = out.filter || {}; + delete out.filter; + return canReflect.assign(out, filter); + } + }); + }, + Translate: function (clause, prop) { + if (clause !== 'where') { + throw new Error('can-query-logic/compat.Translate is only able to translate the where clause'); + } + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + var value = clone.filter[prop]; + delete clone.filter[prop]; + if (value) { + canReflect.assign(clone.filter, value); + } + return clone; + }, + serialize: function (query) { + if (query.filter) { + var clone = canReflect.serialize(query); + var filter = query.filter; + clone.filter = {}; + clone.filter[prop] = filter; + return clone; + } else { + return query; + } + } + }; + }, + props: { + boolean: function (prop) { + return { + schema: function (schema) { + schema.keys[prop] = IsBoolean; + } + }; + }, + dotNotation: function () { + return {}; + }, + enum: function (property, propertyValues) { + function Enum() { + } + makeEnum(Enum, propertyValues); + return { + schema: function (schema) { + schema.keys[property] = Enum; + } + }; + }, + id: function (id) { + return { + 'schema': function (schema) { + schema.identity.push(id); + } + }; + }, + offsetLimit: function (offset, limit) { + offset = offset || 'offset'; + limit = limit || 'limit'; + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + if (offset in clone.filter || limit in clone.filter) { + clone.page = {}; + } + if (offset in clone.filter) { + clone.page.start = parseInt(clone.filter[offset], 10); + delete clone.filter[offset]; + } + if (limit in clone.filter) { + clone.page.end = (clone.page.start || 0) + parseInt(clone.filter[limit], 10) - 1; + delete clone.filter[limit]; + } + return clone; + }, + serialize: function (raw) { + var clone = canReflect.serialize(raw); + if (clone.page) { + clone[offset] = clone.page.start; + clone[limit] = clone.page.end - clone.page.start + 1; + delete clone.page; + } + return clone; + } + }; + }, + rangeInclusive: function (start, end) { + var hydrateTransfomer = {}; + hydrateTransfomer['filter.' + start] = 'page.start'; + hydrateTransfomer['filter.' + end] = 'page.end'; + var serializeTransformer = { + 'page.start': start, + 'page.end': end + }; + return { + hydrate: function (raw) { + var res = transform(raw, hydrateTransfomer); + if (res.page) { + if (res.page.start) { + res.page.start = parseInt(res.page.start, 10); + } + if (res.page.end) { + res.page.end = parseInt(res.page.end, 10); + } + } + return res; + }, + serialize: function (raw) { + return transform(raw, serializeTransformer); + } + }; + }, + ignore: function (prop) { + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + delete clone.filter[prop]; + return clone; + } + }; + }, + sort: function (prop, sortFunc) { + if (!prop) { + prop = 'sort'; + } + if (sortFunc) { + throw new Error('can-query-logic/compat.sort - sortFunc is not supported'); + } + return { + hydrate: function (raw) { + var clone = canReflect.serialize(raw); + var sort = getKey(clone, 'filter.' + prop); + if (sort !== undefined) { + deleteKey(clone, 'filter.' + prop); + clone.sort = convertToJSONAPISort(sort); + } + return clone; + }, + serialize: function (raw) { + var clone = canReflect.serialize(raw); + var sort = clone.sort; + if (sort !== undefined) { + delete clone.sort; + clone[prop] = convertToLegacySort(sort); + } + return clone; + } + }; + } + } + }; + function makeAlgebra(algebra) { + if (!algebra) { + return defaultAlgebra; + } else if (!(algebra instanceof Query)) { + return new set.Algebra(algebra); + } + return algebra; + } + function makeFromTwoQueries(prop) { + set[prop] = function (a, b, algebra) { + return makeAlgebra(algebra)[prop](a, b); + }; + } + makeFromTwoQueries('difference'); + makeFromTwoQueries('union'); + makeFromTwoQueries('intersection'); + makeFromTwoQueries('isSubset'); + makeFromTwoQueries('isEqual'); + makeFromTwoQueries('isProperSubset'); + set.count = function (query, algebra) { + return makeAlgebra(algebra).count(query); + }; + set.comparators = set.props; + defaultAlgebra = new set.Algebra(); + module.exports = set; +}); +/*can-fixture@3.1.7#test/fixture_test*/ +define('can-fixture@3.1.7#test/fixture_test', [ + 'require', + 'exports', + 'module', + './matches-test', + './store-test', + 'steal-qunit', + 'can-fixture', + 'can-set-legacy', + 'jquery', + 'can-log/dev/dev', + '../data-from-url', + 'can-reflect', + '../matches', + 'can-query-logic', + 'can-test-helpers', + 'can-define/map/map' +], function (require, exports, module) { + (function (global, __dirname, require, exports, module) { + require('./matches-test'); + require('./store-test'); + var QUnit = require('steal-qunit'); + var fixture = require('can-fixture'); + var set = require('can-set-legacy'); + var $ = require('jquery'); + var canDev = require('can-log/dev/dev'); + var dataFromUrl = require('../data-from-url'); + var canReflect = require('can-reflect'); + var matches = require('../matches'); + var QueryLogic = require('can-query-logic'); + var testHelpers = require('can-test-helpers'); + var DefineMap = require('can-define/map/map'); + var errorCallback = function (xhr, status, error) { + assert.ok(false, error); + done(); + }; + var parseHeaders = function (str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + lines.pop(); + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = line.slice(index + 1).replace(/(^\s*|\s*$)/g, ''); + fields[field] = val; + } + return fields; + }; + QUnit.module('can-fixture'); + if (__dirname !== '/') { + QUnit.test('static fixtures', function (assert) { + var done = assert.async(); + fixture('GET something', __dirname + '/fixtures/test.json'); + fixture('POST something', __dirname + '/fixtures/test.json'); + fixture('PATCH something', __dirname + '/fixtures/test.json'); + $.ajax({ + url: 'something', + dataType: 'json' + }).then(function (data) { + assert.equal(data.sweet, 'ness', 'can.get works'); + $.ajax({ + url: 'something', + method: 'POST', + dataType: 'json' + }).then(function (data) { + assert.equal(data.sweet, 'ness', 'can.post works'); + $.ajax({ + url: 'something', + method: 'PATCH', + dataType: 'json' + }).then(function (data) { + assert.equal(data.sweet, 'ness', 'can.patch works'); + done(); + }, errorCallback); + }, errorCallback); + }, errorCallback); + }); + } + if (__dirname !== '/') { + QUnit.test('static fixtures (using method signature)', function (assert) { + var done = assert.async(); + fixture({ + method: 'get', + url: 'method/{id}' + }, __dirname + '/fixtures/method.{id}.json'); + $.ajax({ + url: 'method/4', + dataType: 'json' + }).then(function (data) { + assert.equal(data.id, 4, 'Got data with proper id using method'); + done(); + }, errorCallback); + }); + } + if (__dirname !== '/') { + QUnit.test('static fixtures (using type signature)', function (assert) { + var done = assert.async(); + fixture({ + type: 'get', + url: 'type/{id}' + }, __dirname + '/fixtures/type.{id}.json'); + $.ajax({ + url: 'type/4', + dataType: 'json' + }).then(function (data) { + assert.equal(data.id, 4, 'Got data with proper id using type'); + done(); + }, errorCallback); + }); + } + if (__dirname !== '/') { + QUnit.test('templated static fixtures', function (assert) { + var done = assert.async(); + fixture('GET some/{id}', __dirname + '/fixtures/stuff.{id}.json'); + $.ajax({ + url: 'some/3', + dataType: 'json' + }).then(function (data) { + assert.equal(data.id, 3, 'Got data with proper id'); + done(); + }, errorCallback); + }); + } + QUnit.test('dynamic fixtures', function (assert) { + var done = assert.async(); + fixture.delay = 10; + fixture('something', function () { + return [{ sweet: 'ness' }]; + }); + $.ajax({ + url: 'something', + dataType: 'json' + }).done(function (data) { + assert.equal(data[0].sweet, 'ness', 'can.get works'); + done(); + }); + }); + QUnit.test('dynamic fixtures return promises', function (assert) { + var done = assert.async(); + fixture.delay = 10; + fixture('something', function () { + return Promise.resolve([{ sweet: 'ness' }]); + }); + $.ajax({ + url: 'something', + dataType: 'json' + }).then(function (data) { + assert.equal(data[0].sweet, 'ness', 'can.get works'); + done(); + }); + }); + if (__dirname !== '/') { + QUnit.test('fixture function', function (assert) { + assert.expect(3); + var done = assert.async(); + var url = __dirname + '/fixtures/foo.json'; + fixture(url, __dirname + '/fixtures/foobar.json'); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (data) { + assert.equal(data.sweet, 'ner', 'url passed works'); + fixture(url, __dirname + '/fixtures/test.json'); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (data) { + assert.equal(data.sweet, 'ness', 'replaced'); + fixture(url, null); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (data) { + assert.equal(data.a, 'b', 'removed'); + done(); + }); + }); + }); + }); + } + QUnit.test('fixture.store fixtures', function (assert) { + var done = assert.async(); + var SearchText = matches.makeComparatorType(function (searchTextValue, dataSearchTextValue, data, path) { + var regex = new RegExp('^' + searchTextValue); + return regex.test(data.name); + }); + var algebra = new set.Algebra({ + schema: function (schema) { + schema.keys.searchText = SearchText; + } + }, set.props.offsetLimit('offset', 'limit'), set.props.sort('order')); + var store = fixture.store(1000, function (i) { + return { + id: i, + name: 'thing ' + i + }; + }, algebra); + fixture('things', store.getListData); + $.ajax({ + url: 'things', + dataType: 'json', + data: { + offset: 100, + limit: 200, + order: 'name ASC', + searchText: 'thing 2' + }, + success: function (things) { + assert.equal(things.data[0].name, 'thing 29', 'first item is correct'); + assert.equal(things.data.length, 11, 'there are 11 items'); + done(); + } + }); + }); + QUnit.test('fixture.store fixtures should have unique IDs', function (assert) { + var done = assert.async(); + var store = fixture.store(100, function (i) { + return { name: 'Test ' + i }; + }); + fixture('things', store.getListData); + $.ajax({ + url: 'things', + dataType: 'json', + data: { + page: { + start: 0, + end: 199 + }, + order: 'name ASC' + }, + success: function (result) { + var seenIds = []; + var things = result.data; + for (var thingKey in things) { + var thing = things[thingKey]; + assert.ok(seenIds.indexOf(thing.id) === -1); + seenIds.push(thing.id); + } + done(); + } + }); + }); + QUnit.test('fixture.store should assign unique IDs when fixtures provide IDs', function (assert) { + var store = fixture.store([ + { + id: 0, + name: 'Object 0' + }, + { + id: 1, + name: 'Object 1' + }, + { + id: 2, + name: 'Object 2' + } + ]); + fixture('POST /models', store.createData); + function then(ajax, callback) { + ajax.then(callback, function (error) { + assert.ok(false, 'ajax failure: ' + error); + done(); + }); + } + var request = $.ajax({ + url: '/models', + dataType: 'json', + type: 'post', + data: { name: 'My test object' } + }); + var done = assert.async(); + then(request, function (response) { + assert.notEqual(response.id, 0); + assert.notEqual(response.id, 1); + assert.notEqual(response.id, 2); + assert.equal(response.id, 3); + done(); + }); + }); + QUnit.test('simulating an error', function (assert) { + fixture('/foo', function (request, response) { + return response(401, { type: 'unauthorized' }); + }); + var done = assert.async(); + $.ajax({ + url: '/foo', + dataType: 'json' + }).done(function () { + assert.ok(false, 'success called'); + done(); + }).fail(function (original, type) { + assert.ok(true, 'error called'); + assert.deepEqual(JSON.parse(original.responseText), { type: 'unauthorized' }, 'Original text passed'); + done(); + }); + }); + QUnit.test('rand', function (assert) { + var rand = fixture.rand; + var num = rand(3); + assert.equal(typeof num, 'number'); + var matched = {}; + for (var i = 0; i < 100; i++) { + num = rand(3); + matched[num] = true; + } + for (i = 0; i <= 3; i++) { + assert.ok(matched[i], 'has ' + i); + } + matched = {}; + var result, choices = [ + 'a', + 'b', + 'c' + ]; + for (i = 0; i < 100; i++) { + result = rand(choices); + matched[result.length] = true; + matched[result[0]] = true; + } + for (i = 1; i <= 3; i++) { + assert.ok(matched[i], 'has ' + i); + delete matched[i]; + } + choices.forEach(function (choice) { + assert.ok(matched[choice], 'has ' + choice); + delete matched[choice]; + }); + assert.ok(canReflect.size(matched) === 0, 'nothing else unexpected'); + }); + QUnit.test('dataFromUrl', function (assert) { + var data = dataFromUrl('/thingers/{id}', '/thingers/5'); + assert.equal(data.id, 5, 'gets data'); + data = dataFromUrl('/thingers/5?hi.there', '/thingers/5?hi.there'); + assert.deepEqual(data, {}, 'gets data'); + }); + QUnit.test('core.dataFromUrl with double character value', function (assert) { + var data = dataFromUrl('/days/{id}/time_slots.json', '/days/17/time_slots.json'); + assert.equal(data.id, 17, 'gets data'); + }); + QUnit.test('fixture function gets id', function (assert) { + fixture('/thingers/{id}', function (settings) { + return { + id: settings.data.id, + name: 'justin' + }; + }); + var done = assert.async(); + $.ajax({ + url: '/thingers/5', + dataType: 'json', + data: { id: 5 } + }).done(function (data) { + assert.ok(data.id); + done(); + }); + }); + if (__dirname !== '/') { + QUnit.test('replacing and removing a fixture', function (assert) { + var url = __dirname + '/fixtures/remove.json'; + fixture('GET ' + url, function () { + return { weird: 'ness!' }; + }); + var done = assert.async(); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (json) { + assert.equal(json.weird, 'ness!', 'fixture set right'); + fixture('GET ' + url, function () { + return { weird: 'ness?' }; + }); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (json) { + assert.equal(json.weird, 'ness?', 'fixture set right'); + fixture('GET ' + url, null); + $.ajax({ + url: url, + dataType: 'json' + }).done(function (json) { + assert.equal(json.weird, 'ness', 'fixture set right'); + done(); + }); + }); + }); + }); + } + QUnit.test('fixture.store with can.Model', function (assert) { + var store = fixture.store(100, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + fixture('GET /models', store.getListData); + fixture('GET /models/{id}', store.getData); + fixture('POST /models', store.createData); + fixture('PUT /models/{id}', store.updateData); + fixture('DELETE /models/{id}', store.destroyData); + var done = assert.async(); + function errorAndStart(e) { + assert.ok(false, 'borked' + e); + done(); + } + var check100Updated = function () { + return $.ajax({ + url: '/models/100', + dataType: 'json' + }).then(function (model) { + assert.equal(model.name, 'Updated test object', 'Successfully updated object'); + }); + }; + $.ajax({ + url: '/models', + dataType: 'json' + }).then(function (modelsData) { + var models = modelsData.data; + assert.equal(models.length, 100, 'Got 100 models for findAll with no parameters'); + assert.equal(models[95].name, 'Object 95', 'All models generated properly'); + return $.ajax({ + url: '/models/51', + dataType: 'json' + }).then(function (data) { + assert.equal(data.id, 51, 'Got correct object id'); + assert.equal('Object 51', data.name, 'Object name generated correctly'); + return $.ajax({ + url: '/models', + dataType: 'json', + type: 'post', + data: { name: 'My test object' } + }).then(function (newmodel) { + assert.equal(newmodel.id, 100, 'Id got incremented'); + return $.ajax({ + url: '/models/100', + dataType: 'json' + }).then(function (model) { + assert.equal(model.id, 100, 'Loaded new object'); + return $.ajax({ + url: '/models/100', + dataType: 'json', + type: 'put', + data: { name: 'Updated test object' } + }).then(function (model) { + return check100Updated().then(function () { + return $.ajax({ + url: '/models/100', + dataType: 'json', + type: 'delete' + }).then(function (deleted) { + done(); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }, errorAndStart); + }); + QUnit.test('GET fixture.store returns 404 on findOne with bad id (#803)', function (assert) { + var store = fixture.store(2, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + fixture('GET /models/{id}', store.getData); + var done = assert.async(); + $.ajax({ + url: '/models/3', + dataType: 'json' + }).then(function () { + }, function (data) { + assert.equal(data.status, 404, 'status'); + assert.equal(data.statusText, 'error', 'statusText'); + assert.equal(JSON.parse(data.responseText).title, 'no data', 'responseText'); + done(); + }); + }); + QUnit.test('fixture.store returns 404 on update with a bad id (#803)', function (assert) { + var store = fixture.store(5, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + var done = assert.async(); + fixture('POST /models/{id}', store.updateData); + $.ajax({ + url: '/models/6', + dataType: 'json', + data: { 'jedan': 'dva' }, + type: 'POST' + }).then(function () { + assert.ok(false, 'success'); + done(); + }, function (data) { + assert.equal(data.status, 404, 'status'); + assert.equal(data.statusText, 'error', 'statusText'); + assert.equal(JSON.parse(data.responseText).title, 'no data', 'responseText'); + done(); + }); + }); + QUnit.test('fixture.store returns 404 on destroy with a bad id (#803)', function (assert) { + var store = fixture.store(2, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + var done = assert.async(); + fixture('DELETE /models/{id}', store.destroyData); + $.ajax({ + url: '/models/6', + dataType: 'json', + type: 'DELETE' + }).then(function () { + }, function (data) { + assert.equal(data.status, 404, 'status'); + assert.equal(data.statusText, 'error', 'statusText'); + assert.equal(JSON.parse(data.responseText).title, 'no data', 'responseText'); + done(); + }); + }); + QUnit.test('fixture.store can use id of different type (#742)', function (assert) { + var MustBeNumber = matches.makeComparatorType(function (queryVal, propVal) { + return parseInt(queryVal, 10) === propVal; + }); + var query = new QueryLogic({ keys: { parentId: MustBeNumber } }); + var store = fixture.store(100, function (i) { + return { + id: i, + parentId: i * 2, + name: 'Object ' + i + }; + }, query); + fixture('GET /models', store.getListData); + var done = assert.async(); + $.ajax({ + url: '/models', + dataType: 'json', + data: { filter: { parentId: '4' } } + }).then(function (models) { + assert.equal(models.data.length, 1, 'Got one model'); + assert.deepEqual(models.data[0], { + id: 2, + parentId: 4, + name: 'Object 2' + }); + done(); + }); + }); + QUnit.test('fixture("METHOD /path", store) should use the right method', function (assert) { + var store = fixture.store(100, function (i) { + return { + id: i, + name: 'Object ' + i + }; + }); + fixture('GET /models', store); + var done = assert.async(); + $.ajax({ + url: '/models', + dataType: 'json' + }).then(function (models) { + assert.equal(models.data.length, 100, 'Gotta catch up all!'); + done(); + }); + }); + QUnit.test('fixture with response callback', function (assert) { + assert.expect(4); + fixture.delay = 10; + fixture('responseCb', function (orig, response) { + response({ sweet: 'ness' }); + }); + fixture('responseErrorCb', function (orig, response) { + response(404, 'This is an error from callback'); + }); + var done = assert.async(); + $.ajax({ + url: 'responseCb', + dataType: 'json' + }).done(function (data) { + assert.equal(data.sweet, 'ness', 'can.get works'); + }); + $.ajax({ + url: 'responseErrorCb', + dataType: 'json' + }).fail(function (orig, error, text) { + assert.equal(error, 'error', 'Got error status'); + assert.equal(orig.responseText, 'This is an error from callback', 'Got error text'); + }); + fixture('cbWithTimeout', function (orig, response) { + setTimeout(function () { + response([{ epic: 'ness' }]); + }, 10); + }); + $.ajax({ + url: 'cbWithTimeout', + dataType: 'json' + }).done(function (data) { + assert.equal(data[0].epic, 'ness', 'Got responsen with timeout'); + done(); + }); + }); + QUnit.test('store create works with an empty array of items', function (assert) { + var store = fixture.store(0, function () { + return {}; + }); + var done = assert.async(); + store.createData({ data: {} }, function (responseData, responseHeaders) { + assert.equal(responseData.id, 1, 'the first id is 1'); + done(); + }); + }); + QUnit.test('store creates sequential ids', function (assert) { + var store = fixture.store(0, function () { + return {}; + }); + var done = assert.async(); + store.createData({ data: {} }, function (responseData, responseHeaders) { + assert.equal(responseData.id, 1, 'the first id is 1'); + createSecond(); + }); + function createSecond() { + store.createData({ data: {} }, function (responseData, responseHeaders) { + assert.equal(responseData.id, 2, 'the second id is 2'); + destroyFirst(); + }); + } + function destroyFirst() { + store.destroyData({ data: { id: 1 } }, createThird); + } + function createThird() { + store.createData({ data: {} }, function (responseData, responseHeaders) { + assert.equal(responseData.id, 3, 'the third id is 3'); + done(); + }); + } + }); + QUnit.test('fixture updates request.data with id', function (assert) { + assert.expect(1); + var done = assert.async(); + fixture('foo/{id}', function (request) { + assert.equal(request.data.id, 5); + done(); + }); + $.ajax({ url: 'foo/5' }); + }); + QUnit.test('create a store with array and comparison object', function (assert) { + var SoftEq = matches.makeComparatorType(function (a, b) { + return a == b; + }); + var query = new QueryLogic({ + keys: { + year: SoftEq, + modelId: SoftEq + } + }); + var store = fixture.store([ + { + id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + thumb: 'http://mustangsdaily.com/blog/wp-content/uploads/2012/07/01-2013-ford-mustang-gt-review-585x388.jpg' + }, + { + id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + thumb: 'http://mustangsdaily.com/blog/wp-content/uploads/2013/03/2014-roush-mustang.jpg' + }, + { + id: 2, + modelId: 2, + year: 2013, + name: '2013 Focus', + thumb: 'http://images.newcars.com/images/car-pictures/original/2013-Ford-Focus-Sedan-S-4dr-Sedan-Exterior.png' + }, + { + id: 2, + modelId: 2, + year: 2014, + name: '2014 Focus', + thumb: 'http://ipinvite.iperceptions.com/Invitations/survey705/images_V2/top4.jpg' + }, + { + id: 2, + modelId: 3, + year: 2013, + name: '2013 Altima', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/04-2013-nissan-altima-1333416664.jpg' + }, + { + id: 2, + modelId: 3, + year: 2014, + name: '2014 Altima', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/01-2013-nissan-altima-ny.jpg' + }, + { + id: 2, + modelId: 4, + year: 2013, + name: '2013 Leaf', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/01-2013-nissan-altima-ny.jpg' + }, + { + id: 2, + modelId: 4, + year: 2014, + name: '2014 Leaf', + thumb: 'http://images.thecarconnection.com/med/2013-nissan-leaf_100414473_m.jpg' + } + ], query); + fixture('GET /presetStore', store.getListData); + var done = assert.async(); + $.ajax({ + url: '/presetStore', + method: 'get', + data: { + filter: { + year: 2013, + modelId: 1 + } + }, + dataType: 'json' + }).then(function (response) { + assert.equal(response.data[0].id, 1, 'got the first item'); + assert.equal(response.data.length, 1, 'only got one item'); + done(); + }); + }); + QUnit.test('posting an empty data object', function (assert) { + var done = assert.async(); + fixture('/data', function (req, res) { + if (req.data == null) { + throw new Error('req.data should be an empty object'); + } else { + return {}; + } + }); + var def = $.ajax({ + method: 'post', + url: '/data', + dataType: 'json', + data: {} + }); + def.then(function () { + assert.ok(true, 'works!'); + done(); + }, function (e) { + assert.notOk(e, 'should not fail'); + }); + }); + QUnit.test('store with objects allows .create, .update and .destroy (#1471)', function (assert) { + assert.expect(4); + var store = fixture.store([ + { + id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + thumb: 'http://mustangsdaily.com/blog/wp-content/uploads/2012/07/01-2013-ford-mustang-gt-review-585x388.jpg' + }, + { + id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + thumb: 'http://mustangsdaily.com/blog/wp-content/uploads/2013/03/2014-roush-mustang.jpg' + }, + { + id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + thumb: 'http://images.newcars.com/images/car-pictures/original/2013-Ford-Focus-Sedan-S-4dr-Sedan-Exterior.png' + }, + { + id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + thumb: 'http://ipinvite.iperceptions.com/Invitations/survey705/images_V2/top4.jpg' + }, + { + id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/04-2013-nissan-altima-1333416664.jpg' + }, + { + id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/2012/04/01-2013-nissan-altima-ny.jpg' + }, + { + id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + thumb: 'http://www.blogcdn.com/www.autoblog.com/media/201204/01-2013-nissan-altima-ny.jpg' + }, + { + id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + thumb: 'http://images.thecarconnection.com/med/2013-nissan-leaf_100414473_m.jpg' + } + ]); + fixture('GET /cars', store.getListData); + fixture('POST /cars', store.createData); + fixture('PUT /cars/{id}', store.updateData); + fixture('DELETE /cars/{id}', store.destroyData); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + var done = assert.async(); + findAll().then(function (carsData) { + assert.equal(carsData.data.length, 8, 'Got all cars'); + return $.ajax({ + url: '/cars/' + carsData.data[1].id, + method: 'DELETE', + dataType: 'json' + }); + }).then(function () { + return findAll(); + }).then(function (carsData) { + assert.equal(carsData.data.length, 7, 'One car less'); + assert.equal(carsData.data[1].name, '2013 Focus', 'Car actually deleted'); + }).then(function () { + return $.ajax({ + url: '/cars', + method: 'post', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Altima' + } + }); + }).then(function (saved) { + return $.ajax({ + url: '/cars/' + saved.id, + method: 'put', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Nissan Altima' + } + }); + }).then(function (updated) { + return findAll(); + }).then(function (cars) { + assert.equal(cars.data.length, 8, 'New car created'); + done(); + }); + }); + QUnit.test('filtering works', function (assert) { + var next; + var store = fixture.store([ + { + state: 'CA', + name: 'Casadina' + }, + { + state: 'NT', + name: 'Alberny' + } + ], new QueryLogic({ identity: ['state'] })); + fixture({ 'GET /api/cities': store.getListData }); + var done = assert.async(); + $.getJSON('/api/cities?filter[state]=CA').then(function (data) { + assert.deepEqual(data, { + data: [{ + state: 'CA', + name: 'Casadina' + }], + count: 1 + }); + done(); + }, function (e) { + assert.ok(false, '' + e); + done(); + }); + }); + QUnit.test('filtering works with nested props', function (assert) { + var done = assert.async(); + var store = fixture.store([ + { + id: 1, + name: 'Cheese City', + slug: 'cheese-city', + address: { + city: 'Casadina', + state: 'CA' + } + }, + { + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + } + ]); + fixture({ 'GET /restaurants': store.getListData }); + $.getJSON('/api/restaurants?filter[address][city]=Alberny').then(function (responseData) { + assert.deepEqual(responseData, { + count: 1, + data: [{ + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + }] + }); + done(); + }, function (e) { + assert.ok(false); + done(); + }); + }); + QUnit.test('filtering works with nested.props', function (assert) { + var done = assert.async(); + var store = fixture.store([ + { + id: 1, + name: 'Cheese City', + slug: 'cheese-city', + address: { + city: 'Casadina', + state: 'CA' + } + }, + { + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + } + ]); + store.connection.getListData({ filter: { 'address.city': 'Alberny' } }).then(function (responseData) { + assert.deepEqual(responseData, { + count: 1, + data: [{ + id: 2, + name: 'Crab Barn', + slug: 'crab-barn', + address: { + city: 'Alberny', + state: 'NT' + } + }] + }); + done(); + }); + }); + QUnit.test('onreadystatechange, event is passed', function (assert) { + fixture('GET something', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'something'); + xhr.onreadystatechange = function (ev) { + assert.ok(ev.target != null, 'the event object passed to onreadystatechange'); + done(); + }; + xhr.send(); + var done = assert.async(); + }); + if (__dirname !== '/') { + QUnit.test('doesn\'t break onreadystatechange (#3)', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + assert.ok(true, 'we made a successful request'); + ready(); + } + }; + xhr.open('GET', url); + xhr.send(); + }); + } + QUnit.module('XHR Shim'); + QUnit.test('Supports onload', function (assert) { + var xhr = new XMLHttpRequest(); + assert.ok('onload' in xhr, 'shim passes onload detection'); + }); + if (__dirname !== '/') { + QUnit.test('supports addEventListener on XHR shim', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports addEventListener'); + ready(); + }); + xhr.open('GET', url); + xhr.send(); + }); + } + if (__dirname !== '/') { + QUnit.test('supports removeEventListener on XHR shim', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + var onload = function () { + assert.ok(false, 'this should not be called'); + }; + xhr.addEventListener('load', onload); + xhr.removeEventListener('load', onload); + xhr.onload = function () { + setTimeout(function () { + assert.ok(true, 'didn\'t call the event listener'); + ready(); + }); + }; + xhr.open('GET', url); + xhr.send(); + }); + } + QUnit.test('supports setDisableHeaderCheck', function (assert) { + var xhr = new XMLHttpRequest(); + try { + xhr.setDisableHeaderCheck(true); + assert.ok(true, 'did not throw'); + } catch (e) { + assert.ok(false, 'do not support setDisableHeaderCheck'); + } + }); + if (__dirname !== '/') { + QUnit.test('supports setRequestHeader', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.setRequestHeader('foo', 'bar'); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + assert.equal(xhr._requestHeaders.foo, 'bar', 'header was set'); + ready(); + } + }; + xhr.open('GET', url); + xhr.send(); + }); + } + if (__dirname !== '/') { + QUnit.test('supports getResponseHeader', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + var header = xhr.getResponseHeader('Content-Type'); + assert.ok(header.indexOf('application/json') >= 0, 'got correct header back'); + ready(); + } + }; + xhr.open('GET', url); + xhr.send(); + }); + } + QUnit.test('supports getAllResponseHeaders', function (assert) { + var ready = assert.async(); + fixture('GET something', function (req, res) { + res(200, { message: 'this is the body' }, { foo: 'bar' }); + }); + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + var headers = xhr.getAllResponseHeaders(); + var parsed = parseHeaders(headers); + assert.ok(typeof headers === 'string', 'got headers back'); + assert.ok(parsed.foo === 'bar', 'got proper values'); + ready(); + } + }; + xhr.open('GET', 'something'); + xhr.send(); + }); + QUnit.test('pass data to response handler (#13)', function (assert) { + var ready = assert.async(); + fixture('GET something', function (req, res) { + res(403, { message: 'No bad guys' }); + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'something'); + xhr.onreadystatechange = function (ev) { + assert.deepEqual(JSON.parse(this.responseText), { message: 'No bad guys' }, 'correct response'); + assert.equal(this.status, 403, 'correct status'); + ready(); + }; + xhr.send(); + }); + QUnit.test('pass return value for fixture', function (assert) { + var ready = assert.async(); + fixture('GET something', { foo: 'bar' }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'something'); + xhr.onreadystatechange = function (ev) { + assert.deepEqual(JSON.parse(this.responseText), { foo: 'bar' }, 'correct response'); + assert.equal(this.status, 200, 'correct status'); + ready(); + }; + xhr.send(); + }); + if (__dirname !== '/') { + QUnit.test('pass headers in fallthrough', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/foobar.json'; + var xhr = new XMLHttpRequest(); + assert.expect(2); + xhr.open('GET', url); + xhr.setRequestHeader('foo', 'bar'); + xhr.onreadystatechange = function (ev) { + var originalXhr = ev.target; + if (originalXhr.readyState === 1) { + originalXhr.setRequestHeader = function (key, val) { + assert.equal(key, 'foo'); + assert.equal(val, 'bar'); + }; + } + if (originalXhr.readyState === 4) { + ready(); + } + }; + xhr.send(); + }); + } + QUnit.test('first set.Algebra CRUD works (#12)', function (assert) { + assert.expect(5); + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture('GET /cars', store.getListData); + fixture('POST /cars', store.createData); + fixture('PUT /cars/{_id}', store.updateData); + fixture('DELETE /cars/{_id}', store.destroyData); + fixture('GET /cars/{_id}', store.getData); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + var done = assert.async(); + findAll().then(function (carsData) { + assert.equal(carsData.data.length, 8, 'Got all cars'); + return $.ajax({ + url: '/cars/' + carsData.data[1]._id, + method: 'DELETE', + dataType: 'json' + }); + }).then(function () { + return findAll(); + }).then(function (carsData) { + assert.equal(carsData.data.length, 7, 'One car less'); + assert.equal(carsData.data[1].name, '2013 Focus', 'Car actually deleted'); + }).then(function () { + return $.ajax({ + url: '/cars', + method: 'post', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Altima', + type: 'new' + } + }); + }).then(function (saved) { + return $.ajax({ + url: '/cars/' + saved._id, + method: 'put', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Nissan Altima' + } + }); + }).then(function (updated) { + return findAll(); + }).then(function (cars) { + assert.equal(cars.data.length, 8, 'New car created'); + return $.ajax({ + url: '/cars/5', + method: 'get', + dataType: 'json' + }); + }).then(function (car) { + assert.equal(car.name, '2013 Altima', 'get a single car works'); + done(); + }); + }); + QUnit.test('set.Algebra CRUD works (#12)', function (assert) { + assert.expect(5); + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture('GET /cars', store.getListData); + fixture('POST /cars', store.createData); + fixture('PUT /cars/{_id}', store.updateData); + fixture('DELETE /cars/{_id}', store.destroyData); + fixture('GET /cars/{_id}', store.getData); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + var done = assert.async(); + findAll().then(function (carsData) { + assert.equal(carsData.data.length, 8, 'Got all cars'); + return $.ajax({ + url: '/cars/' + carsData.data[1]._id, + method: 'DELETE', + dataType: 'json' + }); + }).then(function () { + return findAll(); + }).then(function (carsData) { + assert.equal(carsData.data.length, 7, 'One car less'); + assert.equal(carsData.data[1].name, '2013 Focus', 'Car actually deleted'); + }).then(function () { + return $.ajax({ + url: '/cars', + method: 'post', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Altima', + type: 'new' + } + }); + }).then(function (saved) { + return $.ajax({ + url: '/cars/' + saved._id, + method: 'put', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Nissan Altima' + } + }); + }).then(function (updated) { + return findAll(); + }).then(function (cars) { + assert.equal(cars.data.length, 8, 'New car created'); + return $.ajax({ + url: '/cars/5', + method: 'get', + dataType: 'json' + }); + }).then(function (car) { + assert.equal(car.name, '2013 Altima', 'get a single car works'); + done(); + }); + }); + QUnit.test('set.Algebra clauses work', function (assert) { + var ready = assert.async(); + var NumberValue = matches.makeComparatorType(function (a, b) { + if (a === b) { + return true; + } + if (a && b) { + return +a === +b; + } + return false; + }); + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end'), { + schema: function (schema) { + schema.keys.year = NumberValue; + } + }); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture('GET /cars', store.getListData); + $.ajax({ + url: '/cars?where[year]=2013', + dataType: 'json' + }).then(function (carsData) { + assert.equal(carsData.data.length, 4, 'Where clause works with numbers'); + return $.ajax({ + url: '/cars?where[year]=2013&orderBy=name', + dataType: 'json' + }); + }).then(function (carsData) { + var names = carsData.data.map(function (c) { + return c.name; + }); + assert.deepEqual(names, [ + '2013 Altima', + '2013 Focus', + '2013 Leaf', + '2013 Mustang' + ], 'sort works'); + return $.ajax({ + url: '/cars?where[year]=2013&orderBy=name&start=1&end=2', + dataType: 'json' + }); + }).then(function (carsData) { + var names = carsData.data.map(function (c) { + return c.name; + }); + assert.deepEqual(names, [ + '2013 Focus', + '2013 Leaf' + ], 'pagination works'); + ready(); + }); + }); + QUnit.test('storeConnection reset', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + } + ], algebra); + fixture('GET /cars', store.getListData); + fixture('POST /cars', store.createData); + fixture('PUT /cars/{_id}', store.updateData); + fixture('DELETE /cars/{_id}', store.destroyData); + fixture('GET /cars/{_id}', store.getData); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + $.ajax({ + url: '/cars/1', + method: 'DELETE', + dataType: 'json' + }).then(function () { + store.reset(); + return findAll(); + }).then(function (carsData) { + assert.equal(carsData.data.length, 2, 'Got all cars'); + done(); + }); + var done = assert.async(); + }); + function makeAlgebraTest(fixtureUrl) { + return function (assert) { + assert.expect(5); + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture(fixtureUrl, store); + var findAll = function () { + return $.ajax({ + url: '/cars', + dataType: 'json' + }); + }; + var done = assert.async(); + findAll().then(function (carsData) { + assert.equal(carsData.data.length, 8, 'Got all cars'); + return $.ajax({ + url: '/cars/' + carsData.data[1]._id, + method: 'DELETE', + dataType: 'json' + }); + }).then(function () { + return findAll(); + }).then(function (carsData) { + assert.equal(carsData.data.length, 7, 'One car less'); + assert.equal(carsData.data[1].name, '2013 Focus', 'Car actually deleted'); + }).then(function () { + return $.ajax({ + url: '/cars', + method: 'post', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Altima', + type: 'new' + } + }); + }).then(function (saved) { + return $.ajax({ + url: '/cars/' + saved._id, + method: 'put', + dataType: 'json', + data: { + modelId: 3, + year: 2015, + name: '2015 Nissan Altima' + } + }); + }).then(function (updated) { + return findAll(); + }).then(function (cars) { + assert.equal(cars.data.length, 8, 'New car created'); + return $.ajax({ + url: '/cars/5', + method: 'get', + dataType: 'json' + }); + }).then(function (car) { + assert.equal(car.name, '2013 Altima', 'get a single car works'); + done(); + }); + }; + } + QUnit.test('set.Algebra CRUD works with easy hookup (#12)', makeAlgebraTest('/cars/{_id}')); + QUnit.test('set.Algebra CRUD works with easy hookup and list-style url (#52)', makeAlgebraTest('/cars')); + QUnit.test('store.getList and store.get', function (assert) { + var algebra = new set.Algebra(set.props.id('_id')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + assert.equal(store.getList({ year: 2013 }).data.length, 4, 'filtered'); + assert.deepEqual(store.get({ _id: 5 }).name, '2013 Altima', 'get'); + }); + QUnit.test('supports addEventListener on shim using fixture', function (assert) { + var ready = assert.async(); + fixture('/addEventListener', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports addEventListener'); + ready(); + }); + xhr.open('GET', '/addEventListener'); + xhr.send(); + }); + if (__dirname !== '/') { + QUnit.test('supports sync on XHR shim (#23)', function (assert) { + var url = __dirname + '/fixtures/test.json'; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports addEventListener'); + }); + xhr.open('GET', url, false); + xhr.send(); + }); + } + QUnit.test('supports sync fixtures (#23)', function (assert) { + fixture('/sync', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports sync'); + }); + xhr.open('GET', '/sync', false); + xhr.send(); + }); + if (__dirname !== '/') { + QUnit.test('supports sync redirect fixtures (#23)', function (assert) { + fixture('/sync_redirect', __dirname + '/fixtures/test.json'); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'our shim supports sync redirect'); + }); + xhr.open('GET', '/sync_redirect', false); + xhr.send(); + }); + } + if (__dirname !== '/') { + QUnit.test('slow mode works (#26)', function (assert) { + var ready = assert.async(); + var url = __dirname + '/fixtures/test.json'; + fixture({ url: url }, 1000); + var xhr = new XMLHttpRequest(); + var startTime = new Date(); + xhr.addEventListener('load', function () { + var delay = new Date() - startTime; + assert.ok(delay >= 900, delay + 'ms >= 900ms'); + fixture({ url: url }, null); + ready(); + }); + xhr.open('GET', url); + xhr.send(); + }); + } + QUnit.test('onload should be triggered for HTTP error responses (#36)', function (assert) { + var done = assert.async(); + fixture('/onload', function (req, res) { + res(400); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + assert.ok(true, 'onload should be invoked'); + fixture('/onload', null); + done(); + }); + xhr.addEventListener('error', function () { + assert.ok(false, 'onerror should not be invoked'); + fixture('/onload', null); + done(); + }); + xhr.open('GET', '/onload'); + xhr.send(); + }); + QUnit.test('responseText & responseXML should not be set for arraybuffer types (#38)', function (assert) { + var done = assert.async(); + fixture('/onload', '/test/fixtures/foo.json'); + var oldError = window.onerror; + window.onerror = function (msg, url, line) { + assert.ok(false, 'There should not be an error'); + done(); + }; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/onload', null); + window.onerror = oldError; + assert.ok(true, 'Got here without an error'); + done(); + }); + xhr.responseType = 'arraybuffer'; + xhr.open('GET', '/onload'); + xhr.send(); + }); + QUnit.test('fixture with timeout does not run if $.ajax timeout less than delay', function (assert) { + var done = assert.async(); + var delay = fixture.delay; + fixture.delay = 1000; + fixture('/onload', function () { + fixture('/onload', null); + assert.ok(false, 'timed out xhr did not abort'); + done(); + }); + $.ajax({ + url: '/onload', + timeout: 50, + error: function (xhr) { + fixture('/onload', null); + assert.ok(true, 'Got to the error handler'); + assert.equal(xhr.statusText, 'timeout'); + assert.equal(xhr.status, '0'); + done(); + } + }); + fixture.delay = delay; + }); + QUnit.test('response headers are set', function (assert) { + var ready = assert.async(); + fixture('GET /todos', function (request, response) { + response(200, '{}', { foo: 'bar' }); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + var headers = parseHeaders(xhr.getAllResponseHeaders()); + assert.ok(headers.foo === 'bar', 'header was set'); + ready(); + }); + xhr.open('GET', '/todos'); + xhr.send(); + }); + QUnit.test('match values in get data', function (assert) { + var ready = assert.async(); + fixture({ + method: 'GET', + url: '/data-value', + data: { name: 'justin' } + }, function (request, response) { + assert.ok(true, 'got it'); + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ready(); + }); + xhr.open('GET', '/data-value?name=justin&age=22'); + xhr.send(); + }); + QUnit.test('universal match (#2000)', function (assert) { + var ready = assert.async(); + fixture({}, function () { + assert.ok(true, 'got hit'); + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + ready(); + fixture.fixtures.splice(0, fixture.fixtures.length); + }); + xhr.open('GET', '/something-totally-unexpected-62'); + xhr.send(); + }); + QUnit.test('set.Algebra stores provide a count (#58)', function (assert) { + var algebra = new set.Algebra(new set.Translate('where', 'where'), set.props.id('_id'), set.props.sort('orderBy'), set.props.enum('type', [ + 'used', + 'new', + 'certified' + ]), set.props.rangeInclusive('start', 'end')); + var store = fixture.store([ + { + _id: 1, + modelId: 1, + year: 2013, + name: '2013 Mustang', + type: 'used' + }, + { + _id: 2, + modelId: 1, + year: 2014, + name: '2014 Mustang', + type: 'new' + }, + { + _id: 3, + modelId: 2, + year: 2013, + name: '2013 Focus', + type: 'used' + }, + { + _id: 4, + modelId: 2, + year: 2014, + name: '2014 Focus', + type: 'certified' + }, + { + _id: 5, + modelId: 3, + year: 2013, + name: '2013 Altima', + type: 'used' + }, + { + _id: 6, + modelId: 3, + year: 2014, + name: '2014 Altima', + type: 'certified' + }, + { + _id: 7, + modelId: 4, + year: 2013, + name: '2013 Leaf', + type: 'used' + }, + { + _id: 8, + modelId: 4, + year: 2014, + name: '2014 Leaf', + type: 'used' + } + ], algebra); + fixture('/cars/{_id}', store); + var done = assert.async(); + $.ajax({ + url: '/cars', + dataType: 'json', + data: { + start: 2, + end: 3 + } + }).then(function (carsData) { + assert.equal(carsData.data.length, 2, 'Got 2 cars'); + assert.equal(carsData.count, 8, 'got the count'); + done(); + }, function () { + assert.ok(false, 'borked'); + done(); + }); + }); + QUnit.test('should allow Arrays as data type (#133)', function (assert) { + var ready = assert.async(); + fixture('/array-data', function (req, res) { + assert.ok(req.data instanceof Array, 'data returned should be instance of Array'); + return {}; + }); + var data = []; + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/array-data', null); + assert.ok(true, 'should not throw when sending Array'); + ready(); + }); + xhr.open('GET', '/array-data'); + xhr.send(data); + }); + QUnit.test('should allow FormData as data type (#133)', function (assert) { + var ready = assert.async(); + fixture('/upload', function (req, res) { + assert.ok(req.data instanceof FormData, 'data returned should be instance of formdata'); + res(400); + }); + var data = new FormData(); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/upload', null); + assert.ok(true, 'should not throw when sending FormData'); + ready(); + }); + xhr.open('POST', '/upload', true); + xhr.send(data); + }); + QUnit.test('fixture returns the old fixture callback when fixtures are removed (#34)', function (assert) { + var funcA = function () { + return 'foo'; + }; + fixture('/services/thing', funcA); + var oldFixtures = fixture('/services/thing', null); + assert.deepEqual(oldFixtures, [{ + fixture: funcA, + url: '/services/thing' + }]); + }); + QUnit.test('Using with nested types', function (assert) { + var done = assert.async(); + var Pet = DefineMap.extend('Pet', { name: 'string' }); + var Person = DefineMap.extend('Person', { + id: { + type: 'number', + identity: true + }, + name: 'string', + pet: Pet + }); + var store = fixture.store([{ + id: 1, + name: 'Dorothy', + pet: { name: 'Max' } + }], new QueryLogic(Person)); + fixture('/api/persons/{id}', store); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + var data = JSON.parse(this.responseText); + var xhr2 = new XMLHttpRequest(); + xhr2.addEventListener('load', function () { + var data = JSON.parse(this.responseText); + assert.equal(data.pet.name, 'Max', 'Still have the Pet type'); + done(); + }); + xhr2.open('PUT', '/api/persons/1', true); + xhr2.send(data); + }); + xhr.open('GET', '/api/persons/1', true); + xhr.send(); + }); + if ('onabort' in XMLHttpRequest._XHR.prototype) { + QUnit.test('fixture with timeout aborts if xhr timeout less than delay', function (assert) { + var done = assert.async(); + fixture('/onload', 1000); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/onload'); + xhr.send(); + setTimeout(function () { + xhr.abort(); + }, 50); + xhr.addEventListener('abort', function () { + fixture('/onload', null); + assert.ok(true, 'Got to the error handler'); + assert.equal(xhr.statusText, ''); + assert.equal(xhr.status, 0); + done(); + }); + xhr.addEventListener('load', function () { + fixture('/onload', null); + assert.ok(false, 'timed out xhr did not abort'); + done(); + }); + }); + QUnit.test('dynamic fixture with timeout does not run if xhr timeout less than delay', function (assert) { + var done = assert.async(); + var delay = fixture.delay; + fixture.delay = 1000; + fixture('/onload', function () { + fixture('/onload', null); + assert.ok(false, 'timed out xhr did not abort'); + done(); + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/onload'); + setTimeout(function () { + xhr.abort(); + }, 50); + xhr.send(); + xhr.addEventListener('abort', function () { + fixture('/onload', null); + assert.ok(true, 'Got to the error handler'); + assert.equal(xhr.statusText, ''); + assert.equal(xhr.status, 0); + done(); + }); + fixture.delay = delay; + }); + QUnit.test('abort() sets readyState correctly', function (assert) { + var done = assert.async(); + fixture('/foo', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/foo'); + xhr.addEventListener('abort', function () { + fixture('/foo', null); + assert.ok(true, 'Got to the error handler'); + assert.equal(xhr.status, 0); + assert.equal(xhr.statusText, ''); + setTimeout(function () { + assert.equal(xhr.readyState, 0); + done(); + }, 50); + }); + xhr.send(); + xhr.abort(); + }); + QUnit.test('abort() of already completed fixture', function (assert) { + var done = assert.async(); + fixture('/foo', function () { + return {}; + }); + var xhr = new XMLHttpRequest(); + xhr.open('GET', '/foo'); + xhr.addEventListener('load', function () { + fixture('/foo', null); + assert.equal(xhr.readyState, 4); + xhr.abort(); + done(); + }); + xhr.send(); + }); + QUnit.test('should be able to call getResponseHeader onload', function (assert) { + var ready = assert.async(); + fixture('/onload', function (req, res) { + res(400); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/onload', null); + xhr.getResponseHeader('Set-Cookie'); + assert.ok(true, 'should not throw when calling getResponseHeader'); + ready(); + }); + xhr.open('GET', '/onload'); + xhr.send(); + }); + testHelpers.dev.devOnlyTest('window.fixture warns when called', function (assert) { + var teardown = testHelpers.dev.willWarn(/You are using the global fixture\. Make sure you import can-fixture\./, function (message, matched) { + if (matched) { + assert.ok(true, 'received warning'); + } + }); + window.fixture('GET /api/products', function () { + return {}; + }); + teardown(); + }); + testHelpers.dev.devOnlyTest('Works with steal-clone', function (assert) { + steal.loader.import('steal-clone', { name: 'can-fixture' }).then(function (clone) { + clone({})['import']('can-fixture').then(function (fixture) { + fixture('/onload', function (req, res) { + res(400); + }); + var xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + fixture('/onload', null); + assert.ok(true, 'Got to the load event without throwing'); + done(); + }); + xhr.open('GET', '/onload'); + xhr.send(); + }); + }); + var done = assert.async(); + }); + } + }(function () { + return this; + }(), '/', require, exports, module)); +}); +/*can-fixture-socket@2.0.3#src/store*/ +define('can-fixture-socket@2.0.3#src/store', [ + 'require', + 'exports', + 'module', + 'can-fixture/core' +], function (require, exports, module) { + 'use strict'; + var extractResponse = require('can-fixture/core').extractResponse; + function requestHandlerToListener(method) { + return function (query, fn) { + var req = { data: query }; + var res = function () { + var response = extractResponse.apply(null, arguments); + if (response[0] === 200) { + fn(null, response[1]); + } else { + fn(response[1]); + } + }; + method(req, res); + }; + } + function storeToListeners(fixtureStore) { + var methods = [ + 'getListData', + 'getData', + 'updateData', + 'createData', + 'destroyData' + ]; + return methods.reduce(function (listeners, method) { + listeners[method] = requestHandlerToListener(fixtureStore[method]); + return listeners; + }, {}); + } + module.exports = { + requestHandlerToListener: requestHandlerToListener, + storeToListeners: storeToListeners + }; +}); +/*can-fixture-socket@2.0.3#src/feathers-client*/ +define('can-fixture-socket@2.0.3#src/feathers-client', [ + 'require', + 'exports', + 'module', + './store', + 'can-assign' +], function (require, exports, module) { + 'use strict'; + var storeToListeners = require('./store').storeToListeners; + var assign = require('can-assign'); + function subscribeFeathersStoreToServer(serviceName, fixtureStore, mockServer, options) { + var listeners = storeToListeners(fixtureStore); + mockServer.on(serviceName + '::find', toFeathersDataHandler(listeners.getListData, null, toFeathersFind)); + mockServer.on(serviceName + '::get', toFeathersDataHandler(listeners.getData, wrapToId(options), null)); + mockServer.on(serviceName + '::remove', toFeathersRemoveHandler(listeners.getData, listeners.destroyData, options)); + mockServer.on(serviceName + '::create', toFeathersCreateHandler(listeners.createData)); + mockServer.on(serviceName + '::update', toFeathersUpdateHandler(listeners.updateData, options)); + } + function toFeathersDataHandler(method, queryTransformer, dataTransformer) { + return function (query) { + var args = Array.prototype.slice.call(arguments), fn; + if (typeof args[args.length - 1] === 'function') { + fn = args[args.length - 1]; + } + query = queryTransformer ? queryTransformer(query) : query; + method(query, function (err, data) { + if (err) { + fn && fn(err); + } else { + data = dataTransformer ? dataTransformer(data) : data; + fn && fn(null, data); + } + }); + }; + } + function wrapToId(options) { + return function (id) { + var o = {}, idProp = options && options.id || 'id'; + o[idProp] = id; + return o; + }; + } + function toFeathersFind(data) { + return { + total: data.count, + limit: data.limit, + skip: data.offset, + data: data.data + }; + } + function toFeathersRemoveHandler(getData, destroyData, options) { + return function (id, query, fn) { + var setQuery = wrapToId(options)(id); + getData(setQuery, function (err, item) { + if (err) { + fn(err); + } else { + destroyData(setQuery, function (err, data) { + if (err) { + fn(err); + } else { + fn(null, item); + } + }); + } + }); + }; + } + function toFeathersUpdateHandler(updateData, options) { + return function (id, data, query, fn) { + var setQuery = wrapToId(options)(id); + updateData(assign(setQuery, data), function (err, data2) { + if (err) { + fn(err); + } else { + fn(null, assign(setQuery, assign(data, data2))); + } + }); + }; + } + function toFeathersCreateHandler(createData) { + return function (data, query, fn) { + createData(data, function (err, data2) { + if (err) { + fn(err); + } else { + fn(null, assign(data, data2)); + } + }); + }; + } + module.exports = { subscribeFeathersStoreToServer: subscribeFeathersStoreToServer }; +}); +/*can-fixture-socket@2.0.3#src/index*/ +define('can-fixture-socket@2.0.3#src/index', [ + 'require', + 'exports', + 'module', + './feathers-client' +], function (require, exports, module) { + 'use strict'; + var subscribeFeathersStoreToServer = require('./feathers-client').subscribeFeathersStoreToServer; + var MockedServer = function (io) { + this.io = io; + this.events = {}; + this.subscribers = {}; + resetManagerCache(io.managers); + this.origs = mockManager(io.Manager.prototype, this); + }; + MockedServer.prototype.on = function (event, cb) { + var self = this; + var events = {}; + if (typeof event === 'string') { + events[event] = cb; + } + if (typeof event === 'object') { + events = event; + } + Object.keys(events).forEach(function (name) { + sub(self.events, name, events[name]); + }); + }; + MockedServer.prototype.emit = function (event) { + var dataArgs = Array.prototype.slice.call(arguments, 1); + pub(this.subscribers, event, dataArgs); + }; + MockedServer.prototype.onFeathersService = function (serviceName, fixtureStore, options) { + subscribeFeathersStoreToServer(serviceName, fixtureStore, this, options); + }; + MockedServer.prototype.restore = function () { + restoreManager(this.io.Manager.prototype, this.origs); + resetManagerCache(this.io.managers); + }; + var MockedSocket = function (server) { + this._server = server; + this.io = { engine: this }; + }; + MockedSocket.prototype = { + on: function (event, cb) { + debug('MockedSocket.on ... ' + event); + sub(this._server.subscribers, event, cb); + }, + emit: function (event) { + var dataArgs = Array.prototype.slice.call(arguments, 1); + debug('MockedSocket.emit ...' + event); + pub(this._server.events, event, dataArgs); + }, + once: function () { + debug('MockedSocket.once ...'); + }, + off: function (event, cb) { + debug('MockedSocket.off ... ' + event); + unsub(this._server.subscribers, event, cb); + }, + open: function () { + return this.connect(); + }, + connect: function () { + this.connected = true; + this.disconnected = false; + }, + close: function () { + return this.disconnect(); + }, + disconnect: function () { + this.connected = false; + this.disconnected = true; + } + }; + function pub(pubsub, event, dataArgs) { + debug(' >>> pub ' + event, dataArgs); + if (dataArgs && typeof dataArgs[0] === 'string' && pubsub[dataArgs[0] + '::' + event]) { + event = dataArgs.shift() + '::' + event; + } + var subscribers = pubsub[event] || []; + subscribers.forEach(function (subscriber) { + subscriber.apply(null, dataArgs); + }); + } + function sub(pubsub, event, cb) { + debug(' <<< sub ' + event); + if (!pubsub[event]) { + pubsub[event] = []; + } + pubsub[event].push(cb); + } + function unsub(pubsub, event, cb) { + debug(' <<< unsub ' + event); + pubsub[event].forEach(function (registeredCb, index) { + if (registeredCb === cb) { + pubsub[event].splice(index, 1); + } + }); + } + function mockManager(managerProto, server) { + var methods = [ + 'open', + 'socket' + ]; + var origs = methods.map(function (name) { + return { + name: name, + method: managerProto[name] + }; + }); + managerProto.open = managerProto.connect = function () { + debug('MockedManager.prototype.open or connect ... arguments:', arguments); + setTimeout(function () { + pub(server.subscribers, 'connect'); + pub(server.events, 'connection'); + }, 0); + }; + managerProto.socket = function () { + debug('MockedManager.prototype.socket ...'); + var socket = new MockedSocket(server); + socket.connected = true; + socket.disconnected = false; + return socket; + }; + return origs; + } + function restoreManager(managerProto, origs) { + debug('Restore.'); + origs.forEach(function (orig) { + managerProto[orig.name] = orig.method; + }); + } + function resetManagerCache(cache) { + for (var i in cache) { + if (cache.hasOwnProperty(i)) { + delete cache[i]; + } + } + } + var _DEBUG = false; + function debug(msg, obj) { + if (_DEBUG) { + console.log.apply(console, arguments); + } + } + module.exports = { + Server: MockedServer, + mockSocketManager: mockManager, + restoreManager: restoreManager + }; +}); +/*can-fixture-socket@2.0.3#can-fixture-socket*/ +define('can-fixture-socket@2.0.3#can-fixture-socket', [ + 'require', + 'exports', + 'module', + './src/index', + './src/store' +], function (require, exports, module) { + 'use strict'; + var fixtureSocket = require('./src/index'); + var fixtureStore = require('./src/store'); + module.exports = { + Server: fixtureSocket.Server, + requestHandlerToListener: fixtureStore.requestHandlerToListener, + storeToListeners: fixtureStore.storeToListeners + }; +}); +/*parseuri@0.0.6#index*/ +define('parseuri@0.0.6#index', function (require, exports, module) { + var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; + var parts = [ + 'source', + 'protocol', + 'authority', + 'userInfo', + 'user', + 'password', + 'host', + 'port', + 'relative', + 'path', + 'directory', + 'file', + 'query', + 'anchor' + ]; + module.exports = function parseuri(str) { + var src = str, b = str.indexOf('['), e = str.indexOf(']'); + if (b != -1 && e != -1) { + str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length); + } + var m = re.exec(str || ''), uri = {}, i = 14; + while (i--) { + uri[parts[i]] = m[i] || ''; + } + if (b != -1 && e != -1) { + uri.source = src; + uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':'); + uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':'); + uri.ipv6uri = true; + } + uri.pathNames = pathNames(uri, uri['path']); + uri.queryKey = queryKey(uri, uri['query']); + return uri; + }; + function pathNames(obj, path) { + var regx = /\/{2,9}/g, names = path.replace(regx, '/').split('/'); + if (path.substr(0, 1) == '/' || path.length === 0) { + names.splice(0, 1); + } + if (path.substr(path.length - 1, 1) == '/') { + names.splice(names.length - 1, 1); + } + return names; + } + function queryKey(uri, query) { + var data = {}; + query.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ($0, $1, $2) { + if ($1) { + data[$1] = $2; + } + }); + return data; + } +}); +/*ms@2.0.0#index*/ +define('ms@2.0.0#index', function (require, exports, module) { + var s = 1000; + var m = s * 60; + var h = m * 60; + var d = h * 24; + var y = d * 365.25; + module.exports = function (val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)); + }; + function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } + } + function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd'; + } + if (ms >= h) { + return Math.round(ms / h) + 'h'; + } + if (ms >= m) { + return Math.round(ms / m) + 'm'; + } + if (ms >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; + } + function fmtLong(ms) { + return plural(ms, d, 'day') || plural(ms, h, 'hour') || plural(ms, m, 'minute') || plural(ms, s, 'second') || ms + ' ms'; + } + function plural(ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name; + } + return Math.ceil(ms / n) + ' ' + name + 's'; + } +}); +/*debug@3.1.0#src/debug*/ +define('debug@3.1.0#src/debug', [ + 'require', + 'exports', + 'module', + 'ms' +], function (require, exports, module) { + exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; + exports.coerce = coerce; + exports.disable = disable; + exports.enable = enable; + exports.enabled = enabled; + exports.humanize = require('ms'); + exports.instances = []; + exports.names = []; + exports.skips = []; + exports.formatters = {}; + function selectColor(namespace) { + var hash = 0, i; + for (i in namespace) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; + } + return exports.colors[Math.abs(hash) % exports.colors.length]; + } + function createDebug(namespace) { + var prevTime; + function debug() { + if (!debug.enabled) + return; + var self = debug; + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + args[0] = exports.coerce(args[0]); + if ('string' !== typeof args[0]) { + args.unshift('%O'); + } + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { + if (match === '%%') + return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + args.splice(index, 1); + index--; + } + return match; + }); + exports.formatArgs.call(self, args); + var logFn = debug.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + debug.namespace = namespace; + debug.enabled = exports.enabled(namespace); + debug.useColors = exports.useColors(); + debug.color = selectColor(namespace); + debug.destroy = destroy; + if ('function' === typeof exports.init) { + exports.init(debug); + } + exports.instances.push(debug); + return debug; + } + function destroy() { + var index = exports.instances.indexOf(this); + if (index !== -1) { + exports.instances.splice(index, 1); + return true; + } else { + return false; + } + } + function enable(namespaces) { + exports.save(namespaces); + exports.names = []; + exports.skips = []; + var i; + var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + var len = split.length; + for (i = 0; i < len; i++) { + if (!split[i]) + continue; + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } + for (i = 0; i < exports.instances.length; i++) { + var instance = exports.instances[i]; + instance.enabled = exports.enabled(instance.namespace); + } + } + function disable() { + exports.enable(''); + } + function enabled(name) { + if (name[name.length - 1] === '*') { + return true; + } + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; + } + function coerce(val) { + if (val instanceof Error) + return val.stack || val.message; + return val; + } +}); +/*debug@3.1.0#src/browser*/ +define('debug@3.1.0#src/browser', [ + 'require', + 'exports', + 'module', + './debug' +], function (require, exports, module) { + exports = module.exports = require('./debug'); + exports.log = log; + exports.formatArgs = formatArgs; + exports.save = save; + exports.load = load; + exports.useColors = useColors; + exports.storage = 'undefined' != typeof chrome && 'undefined' != typeof chrome.storage ? chrome.storage.local : localstorage(); + exports.colors = [ + '#0000CC', + '#0000FF', + '#0033CC', + '#0033FF', + '#0066CC', + '#0066FF', + '#0099CC', + '#0099FF', + '#00CC00', + '#00CC33', + '#00CC66', + '#00CC99', + '#00CCCC', + '#00CCFF', + '#3300CC', + '#3300FF', + '#3333CC', + '#3333FF', + '#3366CC', + '#3366FF', + '#3399CC', + '#3399FF', + '#33CC00', + '#33CC33', + '#33CC66', + '#33CC99', + '#33CCCC', + '#33CCFF', + '#6600CC', + '#6600FF', + '#6633CC', + '#6633FF', + '#66CC00', + '#66CC33', + '#9900CC', + '#9900FF', + '#9933CC', + '#9933FF', + '#99CC00', + '#99CC33', + '#CC0000', + '#CC0033', + '#CC0066', + '#CC0099', + '#CC00CC', + '#CC00FF', + '#CC3300', + '#CC3333', + '#CC3366', + '#CC3399', + '#CC33CC', + '#CC33FF', + '#CC6600', + '#CC6633', + '#CC9900', + '#CC9933', + '#CCCC00', + '#CCCC33', + '#FF0000', + '#FF0033', + '#FF0066', + '#FF0099', + '#FF00CC', + '#FF00FF', + '#FF3300', + '#FF3333', + '#FF3366', + '#FF3399', + '#FF33CC', + '#FF33FF', + '#FF6600', + '#FF6633', + '#FF9900', + '#FF9933', + '#FFCC00', + '#FFCC33' + ]; + function useColors() { + if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { + return true; + } + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); + } + exports.formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (err) { + return '[UnexpectedJSONParseError]: ' + err.message; + } + }; + function formatArgs(args) { + var useColors = this.useColors; + args[0] = (useColors ? '%c' : '') + this.namespace + (useColors ? ' %c' : ' ') + args[0] + (useColors ? '%c ' : ' ') + '+' + exports.humanize(this.diff); + if (!useColors) + return; + var c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function (match) { + if ('%%' === match) + return; + index++; + if ('%c' === match) { + lastC = index; + } + }); + args.splice(lastC, 0, c); + } + function log() { + return 'object' === typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments); + } + function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch (e) { + } + } + function load() { + var r; + try { + r = exports.storage.debug; + } catch (e) { + } + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + return r; + } + exports.enable(load()); + function localstorage() { + try { + return window.localStorage; + } catch (e) { + } + } +}); +/*socket.io-client@2.4.0#lib/url*/ +define('socket.io-client@2.4.0#lib/url', [ + 'require', + 'exports', + 'module', + 'parseuri', + 'debug' +], function (require, exports, module) { + var parseuri = require('parseuri'); + var debug = require('debug')('socket.io-client:url'); + module.exports = url; + function url(uri, loc) { + var obj = uri; + loc = loc || typeof location !== 'undefined' && location; + if (null == uri) + uri = loc.protocol + '//' + loc.host; + if ('string' === typeof uri) { + if ('/' === uri.charAt(0)) { + if ('/' === uri.charAt(1)) { + uri = loc.protocol + uri; + } else { + uri = loc.host + uri; + } + } + if (!/^(https?|wss?):\/\//.test(uri)) { + debug('protocol-less url %s', uri); + if ('undefined' !== typeof loc) { + uri = loc.protocol + '//' + uri; + } else { + uri = 'https://' + uri; + } + } + debug('parse %s', uri); + obj = parseuri(uri); + } + if (!obj.port) { + if (/^(http|ws)$/.test(obj.protocol)) { + obj.port = '80'; + } else if (/^(http|ws)s$/.test(obj.protocol)) { + obj.port = '443'; + } + } + obj.path = obj.path || '/'; + var ipv6 = obj.host.indexOf(':') !== -1; + var host = ipv6 ? '[' + obj.host + ']' : obj.host; + obj.id = obj.protocol + '://' + host + ':' + obj.port; + obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : ':' + obj.port); + return obj; + } +}); +/*component-emitter@1.3.0#index*/ +define('component-emitter@1.3.0#index', function (require, exports, module) { + if (typeof module !== 'undefined') { + module.exports = Emitter; + } + function Emitter(obj) { + if (obj) + return mixin(obj); + } + ; + function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; + } + Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn); + return this; + }; + Emitter.prototype.once = function (event, fn) { + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + on.fn = fn; + this.on(event, on); + return this; + }; + Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + var callbacks = this._callbacks['$' + event]; + if (!callbacks) + return this; + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + if (callbacks.length === 0) { + delete this._callbacks['$' + event]; + } + return this; + }; + Emitter.prototype.emit = function (event) { + this._callbacks = this._callbacks || {}; + var args = new Array(arguments.length - 1), callbacks = this._callbacks['$' + event]; + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + return this; + }; + Emitter.prototype.listeners = function (event) { + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; + }; + Emitter.prototype.hasListeners = function (event) { + return !!this.listeners(event).length; + }; +}); +/*isarray@2.0.1#index*/ +define('isarray@2.0.1#index', function (require, exports, module) { + var toString = {}.toString; + module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; + }; +}); +/*socket.io-parser@3.3.2#is-buffer*/ +define('socket.io-parser@3.3.2#is-buffer', function (require, exports, module) { + module.exports = isBuf; + var withNativeBuffer = typeof Buffer === 'function' && typeof Buffer.isBuffer === 'function'; + var withNativeArrayBuffer = typeof ArrayBuffer === 'function'; + var isView = function (obj) { + return typeof ArrayBuffer.isView === 'function' ? ArrayBuffer.isView(obj) : obj.buffer instanceof ArrayBuffer; + }; + function isBuf(obj) { + return withNativeBuffer && Buffer.isBuffer(obj) || withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj)); + } +}); +/*socket.io-parser@3.3.2#binary*/ +define('socket.io-parser@3.3.2#binary', [ + 'require', + 'exports', + 'module', + 'isarray', + './is-buffer' +], function (require, exports, module) { + (function (global, require, exports, module) { + var isArray = require('isarray'); + var isBuf = require('./is-buffer'); + var toString = Object.prototype.toString; + var withNativeBlob = typeof Blob === 'function' || typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]'; + var withNativeFile = typeof File === 'function' || typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]'; + exports.deconstructPacket = function (packet) { + var buffers = []; + var packetData = packet.data; + var pack = packet; + pack.data = _deconstructPacket(packetData, buffers); + pack.attachments = buffers.length; + return { + packet: pack, + buffers: buffers + }; + }; + function _deconstructPacket(data, buffers) { + if (!data) + return data; + if (isBuf(data)) { + var placeholder = { + _placeholder: true, + num: buffers.length + }; + buffers.push(data); + return placeholder; + } else if (isArray(data)) { + var newData = new Array(data.length); + for (var i = 0; i < data.length; i++) { + newData[i] = _deconstructPacket(data[i], buffers); + } + return newData; + } else if (typeof data === 'object' && !(data instanceof Date)) { + var newData = {}; + for (var key in data) { + newData[key] = _deconstructPacket(data[key], buffers); + } + return newData; + } + return data; + } + exports.reconstructPacket = function (packet, buffers) { + packet.data = _reconstructPacket(packet.data, buffers); + packet.attachments = undefined; + return packet; + }; + function _reconstructPacket(data, buffers) { + if (!data) + return data; + if (data && data._placeholder) { + return buffers[data.num]; + } else if (isArray(data)) { + for (var i = 0; i < data.length; i++) { + data[i] = _reconstructPacket(data[i], buffers); + } + } else if (typeof data === 'object') { + for (var key in data) { + data[key] = _reconstructPacket(data[key], buffers); + } + } + return data; + } + exports.removeBlobs = function (data, callback) { + function _removeBlobs(obj, curKey, containingObject) { + if (!obj) + return obj; + if (withNativeBlob && obj instanceof Blob || withNativeFile && obj instanceof File) { + pendingBlobs++; + var fileReader = new FileReader(); + fileReader.onload = function () { + if (containingObject) { + containingObject[curKey] = this.result; + } else { + bloblessData = this.result; + } + if (!--pendingBlobs) { + callback(bloblessData); + } + }; + fileReader.readAsArrayBuffer(obj); + } else if (isArray(obj)) { + for (var i = 0; i < obj.length; i++) { + _removeBlobs(obj[i], i, obj); + } + } else if (typeof obj === 'object' && !isBuf(obj)) { + for (var key in obj) { + _removeBlobs(obj[key], key, obj); + } + } + } + var pendingBlobs = 0; + var bloblessData = data; + _removeBlobs(bloblessData); + if (!pendingBlobs) { + callback(bloblessData); + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*socket.io-parser@3.3.2#index*/ +define('socket.io-parser@3.3.2#index', [ + 'require', + 'exports', + 'module', + 'debug', + 'component-emitter', + './binary', + 'isarray', + './is-buffer' +], function (require, exports, module) { + var debug = require('debug')('socket.io-parser'); + var Emitter = require('component-emitter'); + var binary = require('./binary'); + var isArray = require('isarray'); + var isBuf = require('./is-buffer'); + exports.protocol = 4; + exports.types = [ + 'CONNECT', + 'DISCONNECT', + 'EVENT', + 'ACK', + 'ERROR', + 'BINARY_EVENT', + 'BINARY_ACK' + ]; + exports.CONNECT = 0; + exports.DISCONNECT = 1; + exports.EVENT = 2; + exports.ACK = 3; + exports.ERROR = 4; + exports.BINARY_EVENT = 5; + exports.BINARY_ACK = 6; + exports.Encoder = Encoder; + exports.Decoder = Decoder; + function Encoder() { + } + var ERROR_PACKET = exports.ERROR + '"encode error"'; + Encoder.prototype.encode = function (obj, callback) { + debug('encoding packet %j', obj); + if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) { + encodeAsBinary(obj, callback); + } else { + var encoding = encodeAsString(obj); + callback([encoding]); + } + }; + function encodeAsString(obj) { + var str = '' + obj.type; + if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) { + str += obj.attachments + '-'; + } + if (obj.nsp && '/' !== obj.nsp) { + str += obj.nsp + ','; + } + if (null != obj.id) { + str += obj.id; + } + if (null != obj.data) { + var payload = tryStringify(obj.data); + if (payload !== false) { + str += payload; + } else { + return ERROR_PACKET; + } + } + debug('encoded %j as %s', obj, str); + return str; + } + function tryStringify(str) { + try { + return JSON.stringify(str); + } catch (e) { + return false; + } + } + function encodeAsBinary(obj, callback) { + function writeEncoding(bloblessData) { + var deconstruction = binary.deconstructPacket(bloblessData); + var pack = encodeAsString(deconstruction.packet); + var buffers = deconstruction.buffers; + buffers.unshift(pack); + callback(buffers); + } + binary.removeBlobs(obj, writeEncoding); + } + function Decoder() { + this.reconstructor = null; + } + Emitter(Decoder.prototype); + Decoder.prototype.add = function (obj) { + var packet; + if (typeof obj === 'string') { + packet = decodeString(obj); + if (exports.BINARY_EVENT === packet.type || exports.BINARY_ACK === packet.type) { + this.reconstructor = new BinaryReconstructor(packet); + if (this.reconstructor.reconPack.attachments === 0) { + this.emit('decoded', packet); + } + } else { + this.emit('decoded', packet); + } + } else if (isBuf(obj) || obj.base64) { + if (!this.reconstructor) { + throw new Error('got binary data when not reconstructing a packet'); + } else { + packet = this.reconstructor.takeBinaryData(obj); + if (packet) { + this.reconstructor = null; + this.emit('decoded', packet); + } + } + } else { + throw new Error('Unknown type: ' + obj); + } + }; + function decodeString(str) { + var i = 0; + var p = { type: Number(str.charAt(0)) }; + if (null == exports.types[p.type]) { + return error('unknown packet type ' + p.type); + } + if (exports.BINARY_EVENT === p.type || exports.BINARY_ACK === p.type) { + var start = i + 1; + while (str.charAt(++i) !== '-' && i != str.length) { + } + var buf = str.substring(start, i); + if (buf != Number(buf) || str.charAt(i) !== '-') { + throw new Error('Illegal attachments'); + } + p.attachments = Number(buf); + } + if ('/' === str.charAt(i + 1)) { + var start = i + 1; + while (++i) { + var c = str.charAt(i); + if (',' === c) + break; + if (i === str.length) + break; + } + p.nsp = str.substring(start, i); + } else { + p.nsp = '/'; + } + var next = str.charAt(i + 1); + if ('' !== next && Number(next) == next) { + var start = i + 1; + while (++i) { + var c = str.charAt(i); + if (null == c || Number(c) != c) { + --i; + break; + } + if (i === str.length) + break; + } + p.id = Number(str.substring(start, i + 1)); + } + if (str.charAt(++i)) { + var payload = tryParse(str.substr(i)); + var isPayloadValid = payload !== false && (p.type === exports.ERROR || isArray(payload)); + if (isPayloadValid) { + p.data = payload; + } else { + return error('invalid payload'); + } + } + debug('decoded %s as %j', str, p); + return p; + } + function tryParse(str) { + try { + return JSON.parse(str); + } catch (e) { + return false; + } + } + Decoder.prototype.destroy = function () { + if (this.reconstructor) { + this.reconstructor.finishedReconstruction(); + } + }; + function BinaryReconstructor(packet) { + this.reconPack = packet; + this.buffers = []; + } + BinaryReconstructor.prototype.takeBinaryData = function (binData) { + this.buffers.push(binData); + if (this.buffers.length === this.reconPack.attachments) { + var packet = binary.reconstructPacket(this.reconPack, this.buffers); + this.finishedReconstruction(); + return packet; + } + return null; + }; + BinaryReconstructor.prototype.finishedReconstruction = function () { + this.reconPack = null; + this.buffers = []; + }; + function error(msg) { + return { + type: exports.ERROR, + data: 'parser error: ' + msg + }; + } +}); +/*has-cors@1.1.0#index*/ +define('has-cors@1.1.0#index', function (require, exports, module) { + try { + module.exports = typeof XMLHttpRequest !== 'undefined' && 'withCredentials' in new XMLHttpRequest(); + } catch (err) { + module.exports = false; + } +}); +/*engine.io-client@3.5.2#lib/globalThis.browser*/ +define('engine.io-client@3.5.2#lib/globalThis.browser', function (require, exports, module) { + module.exports = function () { + if (typeof self !== 'undefined') { + return self; + } else if (typeof window !== 'undefined') { + return window; + } else { + return Function('return this')(); + } + }(); +}); +/*engine.io-client@3.5.2#lib/xmlhttprequest*/ +define('engine.io-client@3.5.2#lib/xmlhttprequest', [ + 'require', + 'exports', + 'module', + 'has-cors', + './globalThis' +], function (require, exports, module) { + (function (global, require, exports, module) { + var hasCORS = require('has-cors'); + var globalThis = require('./globalThis'); + module.exports = function (opts) { + var xdomain = opts.xdomain; + var xscheme = opts.xscheme; + var enablesXDR = opts.enablesXDR; + try { + if ('undefined' !== typeof XMLHttpRequest && (!xdomain || hasCORS)) { + return new XMLHttpRequest(); + } + } catch (e) { + } + try { + if ('undefined' !== typeof XDomainRequest && !xscheme && enablesXDR) { + return new XDomainRequest(); + } + } catch (e) { + } + if (!xdomain) { + try { + return new globalThis[(['Active'].concat('Object').join('X'))]('Microsoft.XMLHTTP'); + } catch (e) { + } + } + }; + }(function () { + return this; + }(), require, exports, module)); +}); +/*engine.io-parser@2.2.1#lib/keys*/ +define('engine.io-parser@2.2.1#lib/keys', function (require, exports, module) { + module.exports = Object.keys || function keys(obj) { + var arr = []; + var has = Object.prototype.hasOwnProperty; + for (var i in obj) { + if (has.call(obj, i)) { + arr.push(i); + } + } + return arr; + }; +}); +/*has-binary2@1.0.3#index*/ +define('has-binary2@1.0.3#index', [ + 'require', + 'exports', + 'module', + 'isarray' +], function (require, exports, module) { + (function (global, require, exports, module) { + var isArray = require('isarray'); + var toString = Object.prototype.toString; + var withNativeBlob = typeof Blob === 'function' || typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]'; + var withNativeFile = typeof File === 'function' || typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]'; + module.exports = hasBinary; + function hasBinary(obj) { + if (!obj || typeof obj !== 'object') { + return false; + } + if (isArray(obj)) { + for (var i = 0, l = obj.length; i < l; i++) { + if (hasBinary(obj[i])) { + return true; + } + } + return false; + } + if (typeof Buffer === 'function' && Buffer.isBuffer && Buffer.isBuffer(obj) || typeof ArrayBuffer === 'function' && obj instanceof ArrayBuffer || withNativeBlob && obj instanceof Blob || withNativeFile && obj instanceof File) { + return true; + } + if (obj.toJSON && typeof obj.toJSON === 'function' && arguments.length === 1) { + return hasBinary(obj.toJSON(), true); + } + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) { + return true; + } + } + return false; + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*arraybuffer.slice@0.0.7#index*/ +define('arraybuffer.slice@0.0.7#index', function (require, exports, module) { + module.exports = function (arraybuffer, start, end) { + var bytes = arraybuffer.byteLength; + start = start || 0; + end = end || bytes; + if (arraybuffer.slice) { + return arraybuffer.slice(start, end); + } + if (start < 0) { + start += bytes; + } + if (end < 0) { + end += bytes; + } + if (end > bytes) { + end = bytes; + } + if (start >= bytes || start >= end || bytes === 0) { + return new ArrayBuffer(0); + } + var abv = new Uint8Array(arraybuffer); + var result = new Uint8Array(end - start); + for (var i = start, ii = 0; i < end; i++, ii++) { + result[ii] = abv[i]; + } + return result.buffer; + }; +}); +/*after@0.8.2#index*/ +define('after@0.8.2#index', function (require, exports, module) { + module.exports = after; + function after(count, callback, err_cb) { + var bail = false; + err_cb = err_cb || noop; + proxy.count = count; + return count === 0 ? callback() : proxy; + function proxy(err, result) { + if (proxy.count <= 0) { + throw new Error('after called too many times'); + } + --proxy.count; + if (err) { + bail = true; + callback(err); + callback = err_cb; + } else if (proxy.count === 0 && !bail) { + callback(null, result); + } + } + } + function noop() { + } +}); +/*engine.io-parser@2.2.1#lib/utf8*/ +define('engine.io-parser@2.2.1#lib/utf8', function (require, exports, module) { + var stringFromCharCode = String.fromCharCode; + function ucs2decode(string) { + var output = []; + var counter = 0; + var length = string.length; + var value; + var extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 55296 && value <= 56319 && counter < length) { + extra = string.charCodeAt(counter++); + if ((extra & 64512) == 56320) { + output.push(((value & 1023) << 10) + (extra & 1023) + 65536); + } else { + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + function ucs2encode(array) { + var length = array.length; + var index = -1; + var value; + var output = ''; + while (++index < length) { + value = array[index]; + if (value > 65535) { + value -= 65536; + output += stringFromCharCode(value >>> 10 & 1023 | 55296); + value = 56320 | value & 1023; + } + output += stringFromCharCode(value); + } + return output; + } + function checkScalarValue(codePoint, strict) { + if (codePoint >= 55296 && codePoint <= 57343) { + if (strict) { + throw Error('Lone surrogate U+' + codePoint.toString(16).toUpperCase() + ' is not a scalar value'); + } + return false; + } + return true; + } + function createByte(codePoint, shift) { + return stringFromCharCode(codePoint >> shift & 63 | 128); + } + function encodeCodePoint(codePoint, strict) { + if ((codePoint & 4294967168) == 0) { + return stringFromCharCode(codePoint); + } + var symbol = ''; + if ((codePoint & 4294965248) == 0) { + symbol = stringFromCharCode(codePoint >> 6 & 31 | 192); + } else if ((codePoint & 4294901760) == 0) { + if (!checkScalarValue(codePoint, strict)) { + codePoint = 65533; + } + symbol = stringFromCharCode(codePoint >> 12 & 15 | 224); + symbol += createByte(codePoint, 6); + } else if ((codePoint & 4292870144) == 0) { + symbol = stringFromCharCode(codePoint >> 18 & 7 | 240); + symbol += createByte(codePoint, 12); + symbol += createByte(codePoint, 6); + } + symbol += stringFromCharCode(codePoint & 63 | 128); + return symbol; + } + function utf8encode(string, opts) { + opts = opts || {}; + var strict = false !== opts.strict; + var codePoints = ucs2decode(string); + var length = codePoints.length; + var index = -1; + var codePoint; + var byteString = ''; + while (++index < length) { + codePoint = codePoints[index]; + byteString += encodeCodePoint(codePoint, strict); + } + return byteString; + } + function readContinuationByte() { + if (byteIndex >= byteCount) { + throw Error('Invalid byte index'); + } + var continuationByte = byteArray[byteIndex] & 255; + byteIndex++; + if ((continuationByte & 192) == 128) { + return continuationByte & 63; + } + throw Error('Invalid continuation byte'); + } + function decodeSymbol(strict) { + var byte1; + var byte2; + var byte3; + var byte4; + var codePoint; + if (byteIndex > byteCount) { + throw Error('Invalid byte index'); + } + if (byteIndex == byteCount) { + return false; + } + byte1 = byteArray[byteIndex] & 255; + byteIndex++; + if ((byte1 & 128) == 0) { + return byte1; + } + if ((byte1 & 224) == 192) { + byte2 = readContinuationByte(); + codePoint = (byte1 & 31) << 6 | byte2; + if (codePoint >= 128) { + return codePoint; + } else { + throw Error('Invalid continuation byte'); + } + } + if ((byte1 & 240) == 224) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + codePoint = (byte1 & 15) << 12 | byte2 << 6 | byte3; + if (codePoint >= 2048) { + return checkScalarValue(codePoint, strict) ? codePoint : 65533; + } else { + throw Error('Invalid continuation byte'); + } + } + if ((byte1 & 248) == 240) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + byte4 = readContinuationByte(); + codePoint = (byte1 & 7) << 18 | byte2 << 12 | byte3 << 6 | byte4; + if (codePoint >= 65536 && codePoint <= 1114111) { + return codePoint; + } + } + throw Error('Invalid UTF-8 detected'); + } + var byteArray; + var byteCount; + var byteIndex; + function utf8decode(byteString, opts) { + opts = opts || {}; + var strict = false !== opts.strict; + byteArray = ucs2decode(byteString); + byteCount = byteArray.length; + byteIndex = 0; + var codePoints = []; + var tmp; + while ((tmp = decodeSymbol(strict)) !== false) { + codePoints.push(tmp); + } + return ucs2encode(codePoints); + } + module.exports = { + version: '2.1.2', + encode: utf8encode, + decode: utf8decode + }; +}); +/*base64-arraybuffer@0.1.4#lib/base64-arraybuffer*/ +define('base64-arraybuffer@0.1.4#lib/base64-arraybuffer', function (require, exports, module) { + (function (chars) { + 'use strict'; + exports.encode = function (arraybuffer) { + var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = ''; + for (i = 0; i < len; i += 3) { + base64 += chars[bytes[i] >> 2]; + base64 += chars[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4]; + base64 += chars[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6]; + base64 += chars[bytes[i + 2] & 63]; + } + if (len % 3 === 2) { + base64 = base64.substring(0, base64.length - 1) + '='; + } else if (len % 3 === 1) { + base64 = base64.substring(0, base64.length - 2) + '=='; + } + return base64; + }; + exports.decode = function (base64) { + var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4; + if (base64[base64.length - 1] === '=') { + bufferLength--; + if (base64[base64.length - 2] === '=') { + bufferLength--; + } + } + var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer); + for (i = 0; i < len; i += 4) { + encoded1 = chars.indexOf(base64[i]); + encoded2 = chars.indexOf(base64[i + 1]); + encoded3 = chars.indexOf(base64[i + 2]); + encoded4 = chars.indexOf(base64[i + 3]); + bytes[p++] = encoded1 << 2 | encoded2 >> 4; + bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; + bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; + } + return arraybuffer; + }; + }('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')); +}); +/*blob@0.0.5#index*/ +define('blob@0.0.5#index', function (require, exports, module) { + var BlobBuilder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof WebKitBlobBuilder !== 'undefined' ? WebKitBlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : false; + var blobSupported = function () { + try { + var a = new Blob(['hi']); + return a.size === 2; + } catch (e) { + return false; + } + }(); + var blobSupportsArrayBufferView = blobSupported && function () { + try { + var b = new Blob([new Uint8Array([ + 1, + 2 + ])]); + return b.size === 2; + } catch (e) { + return false; + } + }(); + var blobBuilderSupported = BlobBuilder && BlobBuilder.prototype.append && BlobBuilder.prototype.getBlob; + function mapArrayBufferViews(ary) { + return ary.map(function (chunk) { + if (chunk.buffer instanceof ArrayBuffer) { + var buf = chunk.buffer; + if (chunk.byteLength !== buf.byteLength) { + var copy = new Uint8Array(chunk.byteLength); + copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength)); + buf = copy.buffer; + } + return buf; + } + return chunk; + }); + } + function BlobBuilderConstructor(ary, options) { + options = options || {}; + var bb = new BlobBuilder(); + mapArrayBufferViews(ary).forEach(function (part) { + bb.append(part); + }); + return options.type ? bb.getBlob(options.type) : bb.getBlob(); + } + ; + function BlobConstructor(ary, options) { + return new Blob(mapArrayBufferViews(ary), options || {}); + } + ; + if (typeof Blob !== 'undefined') { + BlobBuilderConstructor.prototype = Blob.prototype; + BlobConstructor.prototype = Blob.prototype; + } + module.exports = function () { + if (blobSupported) { + return blobSupportsArrayBufferView ? Blob : BlobConstructor; + } else if (blobBuilderSupported) { + return BlobBuilderConstructor; + } else { + return undefined; + } + }(); +}); +/*engine.io-parser@2.2.1#lib/browser*/ +define('engine.io-parser@2.2.1#lib/browser', [ + 'require', + 'exports', + 'module', + './keys', + 'has-binary2', + 'arraybuffer.slice', + 'after', + './utf8', + 'base64-arraybuffer', + 'blob' +], function (require, exports, module) { + var keys = require('./keys'); + var hasBinary = require('has-binary2'); + var sliceBuffer = require('arraybuffer.slice'); + var after = require('after'); + var utf8 = require('./utf8'); + var base64encoder; + if (typeof ArrayBuffer !== 'undefined') { + base64encoder = require('base64-arraybuffer'); + } + var isAndroid = typeof navigator !== 'undefined' && /Android/i.test(navigator.userAgent); + var isPhantomJS = typeof navigator !== 'undefined' && /PhantomJS/i.test(navigator.userAgent); + var dontSendBlobs = isAndroid || isPhantomJS; + exports.protocol = 3; + var packets = exports.packets = { + open: 0, + close: 1, + ping: 2, + pong: 3, + message: 4, + upgrade: 5, + noop: 6 + }; + var packetslist = keys(packets); + var err = { + type: 'error', + data: 'parser error' + }; + var Blob = require('blob'); + exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) { + if (typeof supportsBinary === 'function') { + callback = supportsBinary; + supportsBinary = false; + } + if (typeof utf8encode === 'function') { + callback = utf8encode; + utf8encode = null; + } + var data = packet.data === undefined ? undefined : packet.data.buffer || packet.data; + if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) { + return encodeArrayBuffer(packet, supportsBinary, callback); + } else if (typeof Blob !== 'undefined' && data instanceof Blob) { + return encodeBlob(packet, supportsBinary, callback); + } + if (data && data.base64) { + return encodeBase64Object(packet, callback); + } + var encoded = packets[packet.type]; + if (undefined !== packet.data) { + encoded += utf8encode ? utf8.encode(String(packet.data), { strict: false }) : String(packet.data); + } + return callback('' + encoded); + }; + function encodeBase64Object(packet, callback) { + var message = 'b' + exports.packets[packet.type] + packet.data.data; + return callback(message); + } + function encodeArrayBuffer(packet, supportsBinary, callback) { + if (!supportsBinary) { + return exports.encodeBase64Packet(packet, callback); + } + var data = packet.data; + var contentArray = new Uint8Array(data); + var resultBuffer = new Uint8Array(1 + data.byteLength); + resultBuffer[0] = packets[packet.type]; + for (var i = 0; i < contentArray.length; i++) { + resultBuffer[i + 1] = contentArray[i]; + } + return callback(resultBuffer.buffer); + } + function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) { + if (!supportsBinary) { + return exports.encodeBase64Packet(packet, callback); + } + var fr = new FileReader(); + fr.onload = function () { + exports.encodePacket({ + type: packet.type, + data: fr.result + }, supportsBinary, true, callback); + }; + return fr.readAsArrayBuffer(packet.data); + } + function encodeBlob(packet, supportsBinary, callback) { + if (!supportsBinary) { + return exports.encodeBase64Packet(packet, callback); + } + if (dontSendBlobs) { + return encodeBlobAsArrayBuffer(packet, supportsBinary, callback); + } + var length = new Uint8Array(1); + length[0] = packets[packet.type]; + var blob = new Blob([ + length.buffer, + packet.data + ]); + return callback(blob); + } + exports.encodeBase64Packet = function (packet, callback) { + var message = 'b' + exports.packets[packet.type]; + if (typeof Blob !== 'undefined' && packet.data instanceof Blob) { + var fr = new FileReader(); + fr.onload = function () { + var b64 = fr.result.split(',')[1]; + callback(message + b64); + }; + return fr.readAsDataURL(packet.data); + } + var b64data; + try { + b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data)); + } catch (e) { + var typed = new Uint8Array(packet.data); + var basic = new Array(typed.length); + for (var i = 0; i < typed.length; i++) { + basic[i] = typed[i]; + } + b64data = String.fromCharCode.apply(null, basic); + } + message += btoa(b64data); + return callback(message); + }; + exports.decodePacket = function (data, binaryType, utf8decode) { + if (data === undefined) { + return err; + } + if (typeof data === 'string') { + if (data.charAt(0) === 'b') { + return exports.decodeBase64Packet(data.substr(1), binaryType); + } + if (utf8decode) { + data = tryDecode(data); + if (data === false) { + return err; + } + } + var type = data.charAt(0); + if (Number(type) != type || !packetslist[type]) { + return err; + } + if (data.length > 1) { + return { + type: packetslist[type], + data: data.substring(1) + }; + } else { + return { type: packetslist[type] }; + } + } + var asArray = new Uint8Array(data); + var type = asArray[0]; + var rest = sliceBuffer(data, 1); + if (Blob && binaryType === 'blob') { + rest = new Blob([rest]); + } + return { + type: packetslist[type], + data: rest + }; + }; + function tryDecode(data) { + try { + data = utf8.decode(data, { strict: false }); + } catch (e) { + return false; + } + return data; + } + exports.decodeBase64Packet = function (msg, binaryType) { + var type = packetslist[msg.charAt(0)]; + if (!base64encoder) { + return { + type: type, + data: { + base64: true, + data: msg.substr(1) + } + }; + } + var data = base64encoder.decode(msg.substr(1)); + if (binaryType === 'blob' && Blob) { + data = new Blob([data]); + } + return { + type: type, + data: data + }; + }; + exports.encodePayload = function (packets, supportsBinary, callback) { + if (typeof supportsBinary === 'function') { + callback = supportsBinary; + supportsBinary = null; + } + var isBinary = hasBinary(packets); + if (supportsBinary && isBinary) { + if (Blob && !dontSendBlobs) { + return exports.encodePayloadAsBlob(packets, callback); + } + return exports.encodePayloadAsArrayBuffer(packets, callback); + } + if (!packets.length) { + return callback('0:'); + } + function setLengthHeader(message) { + return message.length + ':' + message; + } + function encodeOne(packet, doneCallback) { + exports.encodePacket(packet, !isBinary ? false : supportsBinary, false, function (message) { + doneCallback(null, setLengthHeader(message)); + }); + } + map(packets, encodeOne, function (err, results) { + return callback(results.join('')); + }); + }; + function map(ary, each, done) { + var result = new Array(ary.length); + var next = after(ary.length, done); + var eachWithIndex = function (i, el, cb) { + each(el, function (error, msg) { + result[i] = msg; + cb(error, result); + }); + }; + for (var i = 0; i < ary.length; i++) { + eachWithIndex(i, ary[i], next); + } + } + exports.decodePayload = function (data, binaryType, callback) { + if (typeof data !== 'string') { + return exports.decodePayloadAsBinary(data, binaryType, callback); + } + if (typeof binaryType === 'function') { + callback = binaryType; + binaryType = null; + } + var packet; + if (data === '') { + return callback(err, 0, 1); + } + var length = '', n, msg; + for (var i = 0, l = data.length; i < l; i++) { + var chr = data.charAt(i); + if (chr !== ':') { + length += chr; + continue; + } + if (length === '' || length != (n = Number(length))) { + return callback(err, 0, 1); + } + msg = data.substr(i + 1, n); + if (length != msg.length) { + return callback(err, 0, 1); + } + if (msg.length) { + packet = exports.decodePacket(msg, binaryType, false); + if (err.type === packet.type && err.data === packet.data) { + return callback(err, 0, 1); + } + var ret = callback(packet, i + n, l); + if (false === ret) + return; + } + i += n; + length = ''; + } + if (length !== '') { + return callback(err, 0, 1); + } + }; + exports.encodePayloadAsArrayBuffer = function (packets, callback) { + if (!packets.length) { + return callback(new ArrayBuffer(0)); + } + function encodeOne(packet, doneCallback) { + exports.encodePacket(packet, true, true, function (data) { + return doneCallback(null, data); + }); + } + map(packets, encodeOne, function (err, encodedPackets) { + var totalLength = encodedPackets.reduce(function (acc, p) { + var len; + if (typeof p === 'string') { + len = p.length; + } else { + len = p.byteLength; + } + return acc + len.toString().length + len + 2; + }, 0); + var resultArray = new Uint8Array(totalLength); + var bufferIndex = 0; + encodedPackets.forEach(function (p) { + var isString = typeof p === 'string'; + var ab = p; + if (isString) { + var view = new Uint8Array(p.length); + for (var i = 0; i < p.length; i++) { + view[i] = p.charCodeAt(i); + } + ab = view.buffer; + } + if (isString) { + resultArray[bufferIndex++] = 0; + } else { + resultArray[bufferIndex++] = 1; + } + var lenStr = ab.byteLength.toString(); + for (var i = 0; i < lenStr.length; i++) { + resultArray[bufferIndex++] = parseInt(lenStr[i]); + } + resultArray[bufferIndex++] = 255; + var view = new Uint8Array(ab); + for (var i = 0; i < view.length; i++) { + resultArray[bufferIndex++] = view[i]; + } + }); + return callback(resultArray.buffer); + }); + }; + exports.encodePayloadAsBlob = function (packets, callback) { + function encodeOne(packet, doneCallback) { + exports.encodePacket(packet, true, true, function (encoded) { + var binaryIdentifier = new Uint8Array(1); + binaryIdentifier[0] = 1; + if (typeof encoded === 'string') { + var view = new Uint8Array(encoded.length); + for (var i = 0; i < encoded.length; i++) { + view[i] = encoded.charCodeAt(i); + } + encoded = view.buffer; + binaryIdentifier[0] = 0; + } + var len = encoded instanceof ArrayBuffer ? encoded.byteLength : encoded.size; + var lenStr = len.toString(); + var lengthAry = new Uint8Array(lenStr.length + 1); + for (var i = 0; i < lenStr.length; i++) { + lengthAry[i] = parseInt(lenStr[i]); + } + lengthAry[lenStr.length] = 255; + if (Blob) { + var blob = new Blob([ + binaryIdentifier.buffer, + lengthAry.buffer, + encoded + ]); + doneCallback(null, blob); + } + }); + } + map(packets, encodeOne, function (err, results) { + return callback(new Blob(results)); + }); + }; + exports.decodePayloadAsBinary = function (data, binaryType, callback) { + if (typeof binaryType === 'function') { + callback = binaryType; + binaryType = null; + } + var bufferTail = data; + var buffers = []; + while (bufferTail.byteLength > 0) { + var tailArray = new Uint8Array(bufferTail); + var isString = tailArray[0] === 0; + var msgLength = ''; + for (var i = 1;; i++) { + if (tailArray[i] === 255) + break; + if (msgLength.length > 310) { + return callback(err, 0, 1); + } + msgLength += tailArray[i]; + } + bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length); + msgLength = parseInt(msgLength); + var msg = sliceBuffer(bufferTail, 0, msgLength); + if (isString) { + try { + msg = String.fromCharCode.apply(null, new Uint8Array(msg)); + } catch (e) { + var typed = new Uint8Array(msg); + msg = ''; + for (var i = 0; i < typed.length; i++) { + msg += String.fromCharCode(typed[i]); + } + } + } + buffers.push(msg); + bufferTail = sliceBuffer(bufferTail, msgLength); + } + var total = buffers.length; + buffers.forEach(function (buffer, i) { + callback(exports.decodePacket(buffer, binaryType, true), i, total); + }); + }; +}); +/*engine.io-client@3.5.2#lib/transport*/ +define('engine.io-client@3.5.2#lib/transport', [ + 'require', + 'exports', + 'module', + 'engine.io-parser', + 'component-emitter' +], function (require, exports, module) { + var parser = require('engine.io-parser'); + var Emitter = require('component-emitter'); + module.exports = Transport; + function Transport(opts) { + this.path = opts.path; + this.hostname = opts.hostname; + this.port = opts.port; + this.secure = opts.secure; + this.query = opts.query; + this.timestampParam = opts.timestampParam; + this.timestampRequests = opts.timestampRequests; + this.readyState = ''; + this.agent = opts.agent || false; + this.socket = opts.socket; + this.enablesXDR = opts.enablesXDR; + this.withCredentials = opts.withCredentials; + this.pfx = opts.pfx; + this.key = opts.key; + this.passphrase = opts.passphrase; + this.cert = opts.cert; + this.ca = opts.ca; + this.ciphers = opts.ciphers; + this.rejectUnauthorized = opts.rejectUnauthorized; + this.forceNode = opts.forceNode; + this.isReactNative = opts.isReactNative; + this.extraHeaders = opts.extraHeaders; + this.localAddress = opts.localAddress; + } + Emitter(Transport.prototype); + Transport.prototype.onError = function (msg, desc) { + var err = new Error(msg); + err.type = 'TransportError'; + err.description = desc; + this.emit('error', err); + return this; + }; + Transport.prototype.open = function () { + if ('closed' === this.readyState || '' === this.readyState) { + this.readyState = 'opening'; + this.doOpen(); + } + return this; + }; + Transport.prototype.close = function () { + if ('opening' === this.readyState || 'open' === this.readyState) { + this.doClose(); + this.onClose(); + } + return this; + }; + Transport.prototype.send = function (packets) { + if ('open' === this.readyState) { + this.write(packets); + } else { + throw new Error('Transport not open'); + } + }; + Transport.prototype.onOpen = function () { + this.readyState = 'open'; + this.writable = true; + this.emit('open'); + }; + Transport.prototype.onData = function (data) { + var packet = parser.decodePacket(data, this.socket.binaryType); + this.onPacket(packet); + }; + Transport.prototype.onPacket = function (packet) { + this.emit('packet', packet); + }; + Transport.prototype.onClose = function () { + this.readyState = 'closed'; + this.emit('close'); + }; +}); +/*parseqs@0.0.6#index*/ +define('parseqs@0.0.6#index', function (require, exports, module) { + exports.encode = function (obj) { + var str = ''; + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + if (str.length) + str += '&'; + str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]); + } + } + return str; + }; + exports.decode = function (qs) { + var qry = {}; + var pairs = qs.split('&'); + for (var i = 0, l = pairs.length; i < l; i++) { + var pair = pairs[i].split('='); + qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); + } + return qry; + }; +}); +/*component-inherit@0.0.3#index*/ +define('component-inherit@0.0.3#index', function (require, exports, module) { + module.exports = function (a, b) { + var fn = function () { + }; + fn.prototype = b.prototype; + a.prototype = new fn(); + a.prototype.constructor = a; + }; +}); +/*yeast@0.1.2#index*/ +define('yeast@0.1.2#index', function (require, exports, module) { + 'use strict'; + var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''), length = 64, map = {}, seed = 0, i = 0, prev; + function encode(num) { + var encoded = ''; + do { + encoded = alphabet[num % length] + encoded; + num = Math.floor(num / length); + } while (num > 0); + return encoded; + } + function decode(str) { + var decoded = 0; + for (i = 0; i < str.length; i++) { + decoded = decoded * length + map[str.charAt(i)]; + } + return decoded; + } + function yeast() { + var now = encode(+new Date()); + if (now !== prev) + return seed = 0, prev = now; + return now + '.' + encode(seed++); + } + for (; i < length; i++) + map[alphabet[i]] = i; + yeast.encode = encode; + yeast.decode = decode; + module.exports = yeast; +}); +/*engine.io-client@3.5.2#lib/transports/polling*/ +define('engine.io-client@3.5.2#lib/transports/polling', [ + 'require', + 'exports', + 'module', + '../transport', + 'parseqs', + 'engine.io-parser', + 'component-inherit', + 'yeast', + 'debug', + 'xmlhttprequest-ssl' +], function (require, exports, module) { + var Transport = require('../transport'); + var parseqs = require('parseqs'); + var parser = require('engine.io-parser'); + var inherit = require('component-inherit'); + var yeast = require('yeast'); + var debug = require('debug')('engine.io-client:polling'); + module.exports = Polling; + var hasXHR2 = function () { + var XMLHttpRequest = require('xmlhttprequest-ssl'); + var xhr = new XMLHttpRequest({ xdomain: false }); + return null != xhr.responseType; + }(); + function Polling(opts) { + var forceBase64 = opts && opts.forceBase64; + if (!hasXHR2 || forceBase64) { + this.supportsBinary = false; + } + Transport.call(this, opts); + } + inherit(Polling, Transport); + Polling.prototype.name = 'polling'; + Polling.prototype.doOpen = function () { + this.poll(); + }; + Polling.prototype.pause = function (onPause) { + var self = this; + this.readyState = 'pausing'; + function pause() { + debug('paused'); + self.readyState = 'paused'; + onPause(); + } + if (this.polling || !this.writable) { + var total = 0; + if (this.polling) { + debug('we are currently polling - waiting to pause'); + total++; + this.once('pollComplete', function () { + debug('pre-pause polling complete'); + --total || pause(); + }); + } + if (!this.writable) { + debug('we are currently writing - waiting to pause'); + total++; + this.once('drain', function () { + debug('pre-pause writing complete'); + --total || pause(); + }); + } + } else { + pause(); + } + }; + Polling.prototype.poll = function () { + debug('polling'); + this.polling = true; + this.doPoll(); + this.emit('poll'); + }; + Polling.prototype.onData = function (data) { + var self = this; + debug('polling got data %s', data); + var callback = function (packet, index, total) { + if ('opening' === self.readyState && packet.type === 'open') { + self.onOpen(); + } + if ('close' === packet.type) { + self.onClose(); + return false; + } + self.onPacket(packet); + }; + parser.decodePayload(data, this.socket.binaryType, callback); + if ('closed' !== this.readyState) { + this.polling = false; + this.emit('pollComplete'); + if ('open' === this.readyState) { + this.poll(); + } else { + debug('ignoring poll - transport state "%s"', this.readyState); + } + } + }; + Polling.prototype.doClose = function () { + var self = this; + function close() { + debug('writing close packet'); + self.write([{ type: 'close' }]); + } + if ('open' === this.readyState) { + debug('transport open - closing'); + close(); + } else { + debug('transport not open - deferring close'); + this.once('open', close); + } + }; + Polling.prototype.write = function (packets) { + var self = this; + this.writable = false; + var callbackfn = function () { + self.writable = true; + self.emit('drain'); + }; + parser.encodePayload(packets, this.supportsBinary, function (data) { + self.doWrite(data, callbackfn); + }); + }; + Polling.prototype.uri = function () { + var query = this.query || {}; + var schema = this.secure ? 'https' : 'http'; + var port = ''; + if (false !== this.timestampRequests) { + query[this.timestampParam] = yeast(); + } + if (!this.supportsBinary && !query.sid) { + query.b64 = 1; + } + query = parseqs.encode(query); + if (this.port && ('https' === schema && Number(this.port) !== 443 || 'http' === schema && Number(this.port) !== 80)) { + port = ':' + this.port; + } + if (query.length) { + query = '?' + query; + } + var ipv6 = this.hostname.indexOf(':') !== -1; + return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query; + }; +}); +/*engine.io-client@3.5.2#lib/transports/polling-xhr*/ +define('engine.io-client@3.5.2#lib/transports/polling-xhr', [ + 'require', + 'exports', + 'module', + 'xmlhttprequest-ssl', + './polling', + 'component-emitter', + 'component-inherit', + 'debug', + '../globalThis' +], function (require, exports, module) { + (function (global, require, exports, module) { + var XMLHttpRequest = require('xmlhttprequest-ssl'); + var Polling = require('./polling'); + var Emitter = require('component-emitter'); + var inherit = require('component-inherit'); + var debug = require('debug')('engine.io-client:polling-xhr'); + var globalThis = require('../globalThis'); + module.exports = XHR; + module.exports.Request = Request; + function empty() { + } + function XHR(opts) { + Polling.call(this, opts); + this.requestTimeout = opts.requestTimeout; + this.extraHeaders = opts.extraHeaders; + if (typeof location !== 'undefined') { + var isSSL = 'https:' === location.protocol; + var port = location.port; + if (!port) { + port = isSSL ? 443 : 80; + } + this.xd = typeof location !== 'undefined' && opts.hostname !== location.hostname || port !== opts.port; + this.xs = opts.secure !== isSSL; + } + } + inherit(XHR, Polling); + XHR.prototype.supportsBinary = true; + XHR.prototype.request = function (opts) { + opts = opts || {}; + opts.uri = this.uri(); + opts.xd = this.xd; + opts.xs = this.xs; + opts.agent = this.agent || false; + opts.supportsBinary = this.supportsBinary; + opts.enablesXDR = this.enablesXDR; + opts.withCredentials = this.withCredentials; + opts.pfx = this.pfx; + opts.key = this.key; + opts.passphrase = this.passphrase; + opts.cert = this.cert; + opts.ca = this.ca; + opts.ciphers = this.ciphers; + opts.rejectUnauthorized = this.rejectUnauthorized; + opts.requestTimeout = this.requestTimeout; + opts.extraHeaders = this.extraHeaders; + return new Request(opts); + }; + XHR.prototype.doWrite = function (data, fn) { + var isBinary = typeof data !== 'string' && data !== undefined; + var req = this.request({ + method: 'POST', + data: data, + isBinary: isBinary + }); + var self = this; + req.on('success', fn); + req.on('error', function (err) { + self.onError('xhr post error', err); + }); + this.sendXhr = req; + }; + XHR.prototype.doPoll = function () { + debug('xhr poll'); + var req = this.request(); + var self = this; + req.on('data', function (data) { + self.onData(data); + }); + req.on('error', function (err) { + self.onError('xhr poll error', err); + }); + this.pollXhr = req; + }; + function Request(opts) { + this.method = opts.method || 'GET'; + this.uri = opts.uri; + this.xd = !!opts.xd; + this.xs = !!opts.xs; + this.async = false !== opts.async; + this.data = undefined !== opts.data ? opts.data : null; + this.agent = opts.agent; + this.isBinary = opts.isBinary; + this.supportsBinary = opts.supportsBinary; + this.enablesXDR = opts.enablesXDR; + this.withCredentials = opts.withCredentials; + this.requestTimeout = opts.requestTimeout; + this.pfx = opts.pfx; + this.key = opts.key; + this.passphrase = opts.passphrase; + this.cert = opts.cert; + this.ca = opts.ca; + this.ciphers = opts.ciphers; + this.rejectUnauthorized = opts.rejectUnauthorized; + this.extraHeaders = opts.extraHeaders; + this.create(); + } + Emitter(Request.prototype); + Request.prototype.create = function () { + var opts = { + agent: this.agent, + xdomain: this.xd, + xscheme: this.xs, + enablesXDR: this.enablesXDR + }; + opts.pfx = this.pfx; + opts.key = this.key; + opts.passphrase = this.passphrase; + opts.cert = this.cert; + opts.ca = this.ca; + opts.ciphers = this.ciphers; + opts.rejectUnauthorized = this.rejectUnauthorized; + var xhr = this.xhr = new XMLHttpRequest(opts); + var self = this; + try { + debug('xhr open %s: %s', this.method, this.uri); + xhr.open(this.method, this.uri, this.async); + try { + if (this.extraHeaders) { + xhr.setDisableHeaderCheck && xhr.setDisableHeaderCheck(true); + for (var i in this.extraHeaders) { + if (this.extraHeaders.hasOwnProperty(i)) { + xhr.setRequestHeader(i, this.extraHeaders[i]); + } + } + } + } catch (e) { + } + if ('POST' === this.method) { + try { + if (this.isBinary) { + xhr.setRequestHeader('Content-type', 'application/octet-stream'); + } else { + xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8'); + } + } catch (e) { + } + } + try { + xhr.setRequestHeader('Accept', '*/*'); + } catch (e) { + } + if ('withCredentials' in xhr) { + xhr.withCredentials = this.withCredentials; + } + if (this.requestTimeout) { + xhr.timeout = this.requestTimeout; + } + if (this.hasXDR()) { + xhr.onload = function () { + self.onLoad(); + }; + xhr.onerror = function () { + self.onError(xhr.responseText); + }; + } else { + xhr.onreadystatechange = function () { + if (xhr.readyState === 2) { + try { + var contentType = xhr.getResponseHeader('Content-Type'); + if (self.supportsBinary && contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') { + xhr.responseType = 'arraybuffer'; + } + } catch (e) { + } + } + if (4 !== xhr.readyState) + return; + if (200 === xhr.status || 1223 === xhr.status) { + self.onLoad(); + } else { + setTimeout(function () { + self.onError(typeof xhr.status === 'number' ? xhr.status : 0); + }, 0); + } + }; + } + debug('xhr data %s', this.data); + xhr.send(this.data); + } catch (e) { + setTimeout(function () { + self.onError(e); + }, 0); + return; + } + if (typeof document !== 'undefined') { + this.index = Request.requestsCount++; + Request.requests[this.index] = this; + } + }; + Request.prototype.onSuccess = function () { + this.emit('success'); + this.cleanup(); + }; + Request.prototype.onData = function (data) { + this.emit('data', data); + this.onSuccess(); + }; + Request.prototype.onError = function (err) { + this.emit('error', err); + this.cleanup(true); + }; + Request.prototype.cleanup = function (fromError) { + if ('undefined' === typeof this.xhr || null === this.xhr) { + return; + } + if (this.hasXDR()) { + this.xhr.onload = this.xhr.onerror = empty; + } else { + this.xhr.onreadystatechange = empty; + } + if (fromError) { + try { + this.xhr.abort(); + } catch (e) { + } + } + if (typeof document !== 'undefined') { + delete Request.requests[this.index]; + } + this.xhr = null; + }; + Request.prototype.onLoad = function () { + var data; + try { + var contentType; + try { + contentType = this.xhr.getResponseHeader('Content-Type'); + } catch (e) { + } + if (contentType === 'application/octet-stream' || contentType === 'application/octet-stream; charset=UTF-8') { + data = this.xhr.response || this.xhr.responseText; + } else { + data = this.xhr.responseText; + } + } catch (e) { + this.onError(e); + } + if (null != data) { + this.onData(data); + } + }; + Request.prototype.hasXDR = function () { + return typeof XDomainRequest !== 'undefined' && !this.xs && this.enablesXDR; + }; + Request.prototype.abort = function () { + this.cleanup(); + }; + Request.requestsCount = 0; + Request.requests = {}; + if (typeof document !== 'undefined') { + if (typeof attachEvent === 'function') { + attachEvent('onunload', unloadHandler); + } else if (typeof addEventListener === 'function') { + var terminationEvent = 'onpagehide' in globalThis ? 'pagehide' : 'unload'; + addEventListener(terminationEvent, unloadHandler, false); + } + } + function unloadHandler() { + for (var i in Request.requests) { + if (Request.requests.hasOwnProperty(i)) { + Request.requests[i].abort(); + } + } + } + }(function () { + return this; + }(), require, exports, module)); +}); +/*engine.io-client@3.5.2#lib/transports/polling-jsonp*/ +define('engine.io-client@3.5.2#lib/transports/polling-jsonp', [ + 'require', + 'exports', + 'module', + './polling', + 'component-inherit', + '../globalThis' +], function (require, exports, module) { + (function (global, require, exports, module) { + var Polling = require('./polling'); + var inherit = require('component-inherit'); + var globalThis = require('../globalThis'); + module.exports = JSONPPolling; + var rNewline = /\n/g; + var rEscapedNewline = /\\n/g; + var callbacks; + function empty() { + } + function JSONPPolling(opts) { + Polling.call(this, opts); + this.query = this.query || {}; + if (!callbacks) { + callbacks = globalThis.___eio = globalThis.___eio || []; + } + this.index = callbacks.length; + var self = this; + callbacks.push(function (msg) { + self.onData(msg); + }); + this.query.j = this.index; + if (typeof addEventListener === 'function') { + addEventListener('beforeunload', function () { + if (self.script) + self.script.onerror = empty; + }, false); + } + } + inherit(JSONPPolling, Polling); + JSONPPolling.prototype.supportsBinary = false; + JSONPPolling.prototype.doClose = function () { + if (this.script) { + this.script.parentNode.removeChild(this.script); + this.script = null; + } + if (this.form) { + this.form.parentNode.removeChild(this.form); + this.form = null; + this.iframe = null; + } + Polling.prototype.doClose.call(this); + }; + JSONPPolling.prototype.doPoll = function () { + var self = this; + var script = document.createElement('script'); + if (this.script) { + this.script.parentNode.removeChild(this.script); + this.script = null; + } + script.async = true; + script.src = this.uri(); + script.onerror = function (e) { + self.onError('jsonp poll error', e); + }; + var insertAt = document.getElementsByTagName('script')[0]; + if (insertAt) { + insertAt.parentNode.insertBefore(script, insertAt); + } else { + (document.head || document.body).appendChild(script); + } + this.script = script; + var isUAgecko = 'undefined' !== typeof navigator && /gecko/i.test(navigator.userAgent); + if (isUAgecko) { + setTimeout(function () { + var iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + document.body.removeChild(iframe); + }, 100); + } + }; + JSONPPolling.prototype.doWrite = function (data, fn) { + var self = this; + if (!this.form) { + var form = document.createElement('form'); + var area = document.createElement('textarea'); + var id = this.iframeId = 'eio_iframe_' + this.index; + var iframe; + form.className = 'socketio'; + form.style.position = 'absolute'; + form.style.top = '-1000px'; + form.style.left = '-1000px'; + form.target = id; + form.method = 'POST'; + form.setAttribute('accept-charset', 'utf-8'); + area.name = 'd'; + form.appendChild(area); + document.body.appendChild(form); + this.form = form; + this.area = area; + } + this.form.action = this.uri(); + function complete() { + initIframe(); + fn(); + } + function initIframe() { + if (self.iframe) { + try { + self.form.removeChild(self.iframe); + } catch (e) { + self.onError('jsonp polling iframe removal error', e); + } + } + try { + var html = '