From c6e40415c63ae8d007e979255e0aeb0205aa2514 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Fri, 22 Jan 2021 12:33:36 +0900 Subject: [PATCH 01/16] Don't use rpm command in spec file The use of rpm command will block OBS build process. This replace it with cat command to read chromium-efl version. Change-Id: I30e738eeb69a4d205fab5b9f73ac2f66b77d165e Signed-off-by: Youngsoo Choi --- packaging/wrtjs.spec | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/packaging/wrtjs.spec b/packaging/wrtjs.spec index 842226c..f962ec8 100755 --- a/packaging/wrtjs.spec +++ b/packaging/wrtjs.spec @@ -130,6 +130,8 @@ install -d %{buildroot}%{_datadir}/aul install -d %{buildroot}%{_resourcedir} install -d %{buildroot}%{WRTJS_APP_DIR} +mkdir -p %{buildroot}%{_datadir}/wrtjs +echo %{version} > %{buildroot}%{_datadir}/wrtjs/version %if 0%{?_use_tpk} %if 0%{?__package_signing} install -m 0644 tizen/downloadable/vd_sign/author-signature.xml %{buildroot}%{WRTJS_APP_DIR} @@ -186,19 +188,13 @@ cp -r %{app_dir}/* %{buildroot}%{_resourcedir}/ %endif %pre -if (( $(rpm -q chromium-efl | wc -l) > 1 )); then - echo -e "\033[31m*****************************************************" - echo -e "Please remove chromium-efl rpm(s) except for one:\n" - rpm -q chromium-efl - echo -e "*****************************************************\033[m" - exit 1 -fi - -export CHROMIUM_REVISION=$(rpm -q chromium-efl | awk -F. '{print $2}') -export WRTJS_REVISION=$(echo %{version} | awk -F. '{print $2}') -if [[ "${CHROMIUM_REVISION}" == "" ]]; then +export CHROMIUM_REVISION= +if [ -f "%{_datadir}/chromium-efl/version" ]; then + CHROMIUM_REVISION=$(cat %{_datadir}/chromium-efl/version | awk -F. '{print $2}') +else CHROMIUM_REVISION="not installed" fi +export WRTJS_REVISION=$(echo %{version} | awk -F. '{print $2}') echo -e "\033[32m*****************************************************" echo -e "* chromium-efl revision : ${CHROMIUM_REVISION}" @@ -243,6 +239,7 @@ rm -fr %{buildroot} %if "%{_vd_cfg_product_type}" != "LFD" %{_datadir}/aul/wrt.loader %endif +%{_datadir}/wrtjs/version %{_libdir}/%{crosswalk_extensions_service}/plugins.json %{_resourcedir}/* %if 0%{?__package_signing} -- 2.7.4 From 51a7882ab7ea3f5fedc35e0f1ec4267f854509a5 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Thu, 12 Nov 2020 17:17:18 +0900 Subject: [PATCH 02/16] [Service][Builtin] Introduce Appmanifest installer This built-in service introduces to support W3C AppManifest installation, which is written JSON manifest file. The overall goal of this feature is that 1) Convert JSON manifest to config.xml - download proper icon 2) Archive .wgt and request to install .wgt - tizen.archive is newly necessary to load To support installation of archived wgt file from this feature, there are 2 consideration to be solved. a) there is no signature file b) at least, public level certification is necessary Change-Id: Iaf09bdfb3e6c5d6e8471ef91ea13fda863641db0 Signed-off-by: DongHyun Song --- packaging/plugins.json | 5 + wrt_app/common/service_manager.ts | 1 + wrt_app/service/builtins/appmanifest_loader.ts | 203 +++++++++++++++++++++++++ wrt_app/service/builtins/wasm_builder.ts | 16 +- 4 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 wrt_app/service/builtins/appmanifest_loader.ts diff --git a/packaging/plugins.json b/packaging/plugins.json index 7838bf7..ed9a833 100644 --- a/packaging/plugins.json +++ b/packaging/plugins.json @@ -79,5 +79,10 @@ "name":"tizen.notification", "lib":"/usr/lib/tizen-extensions-crosswalk/libtizen_notification.so", "entry_points": ["tizen.StatusNotification","tizen.UserNotification", "tizen.NotificationDetailInfo"] + }, + { + "name":"tizen.archive", + "lib":"/usr/lib/tizen-extensions-crosswalk/libtizen_archive.so", + "entry_points": [] } ] diff --git a/wrt_app/common/service_manager.ts b/wrt_app/common/service_manager.ts index face443..544aec7 100644 --- a/wrt_app/common/service_manager.ts +++ b/wrt_app/common/service_manager.ts @@ -60,6 +60,7 @@ export function handleBuiltinService(serviceId: string, serviceName: string) { } let need_stop = (serviceName.substr(0, 5) === 'stop_'); if (need_stop) { + console.log(`${serviceName} will be terminated.`); workers[serviceId].terminate(); } else { console.log(`Builtin service is ${serviceName}`); diff --git a/wrt_app/service/builtins/appmanifest_loader.ts b/wrt_app/service/builtins/appmanifest_loader.ts new file mode 100644 index 0000000..2c8597b --- /dev/null +++ b/wrt_app/service/builtins/appmanifest_loader.ts @@ -0,0 +1,203 @@ +import '../../common/init'; +import { isMainThread, workerData } from 'worker_threads'; +import { wrt } from '../../browser/wrt'; +import * as fs from 'fs'; +import * as https from 'https'; +import * as XWalkExtension from '../../common/wrt_xwalk_extension'; + +function getManifestFile(manifestUrl: string) { + console.log('manifestUrl : '+manifestUrl); + return new Promise((resolve, reject) => { + const req = https.request(manifestUrl, (res) => { + res.setEncoding('utf8'); + let responseBody = ''; + res.on('data', (data) => { + responseBody += data; + }); + res.on('end', () => { + resolve(JSON.parse(responseBody)); + }); + }).on('error', (err) => { + console.log(`error : ${err}`); + reject(err); + }); + req.end(); + }); +} + +async function downloadIcon(iconSrc: string, iconFile: string) { + console.log('iconSrc : ' + iconSrc); + return new Promise((resolve, reject) => { + const req = https.request(iconSrc, (res) => { + const Stream = require('stream').Transform; + let data = new Stream(); + res.on('data', (chunk) => { + data.push(chunk); + }); + res.on('end', () => { + fs.writeFileSync(iconFile, data.read()); + resolve('done'); + }); + }).on('error', (err) => { + console.log(`error : ${err}`); + reject(err); + }); + req.end(); + }); +} + +function copyManifest(filePath: string, manifestData: string) { + fs.writeFileSync(filePath, manifestData); +} + +function concatWithBaseUrl(url: string, baseUrl: string) { + if (url.indexOf('http:') == -1 && url.indexOf('https:') == -1) { + return baseUrl.substr(0, baseUrl.lastIndexOf('/') + 1) + url; + } + return url; +} + +let baseWorkingDir = '/home/owner/content/Downloads/AppManifest'; +let downloadVirtualDir = 'downloads/AppManifest'; +let iconFile: string = ''; +let iconName: string = ''; +let manifestFile: string = ''; +let convertedConfigXml: string = ''; +let refCount: number = 0; + +function getAppName(appName: string) { + appName = appName.replace(/ /g, ''); + console.log('appName : ' + appName); + return appName; +} + +function makeWorkingFolder(appName: string) { + let workingDir = `${baseWorkingDir}/${appName}`; + fs.rmdirSync(workingDir, { recursive: true }); + fs.mkdir(workingDir, { recursive: true }, (err) => { + if (err) + console.log(`mkdir error : ${err}`) + }); +} + +async function handleIcon(appName: string, manifestUrl: string, manifest: any) { + let lengthOfIcons = manifest['icons'].length; + let lastIcon = manifest['icons'][lengthOfIcons - 1]; + let iconSrc = concatWithBaseUrl(lastIcon['src'], manifestUrl); + iconName = iconSrc.substr(iconSrc.lastIndexOf('/') + 1); + iconFile = `${baseWorkingDir}/${appName}/${iconName}`; + await downloadIcon(iconSrc, iconFile); + iconFile = `${downloadVirtualDir}/${appName}/${iconName}`; + refCount++; +} + +function handleStartUrl(appName: string, manifestUrl: string, manifest: any) { + let startUrl = concatWithBaseUrl(manifest['start_url'], manifestUrl); + manifest['start_url'] = startUrl; + manifestFile = `${baseWorkingDir}/${appName}/appmanifest.json`; + copyManifest(manifestFile, JSON.stringify(manifest)); + manifestFile = `${downloadVirtualDir}/${appName}/appmanifest.json`; + refCount++; + return startUrl; +} + +function makeRandomId() { + return Math.random().toString(36).substring(2, 12); +} + +function convertConfigXml(appName: string, startUrl: string) { + convertedConfigXml = `${baseWorkingDir}/${appName}/config.xml`; + let id = makeRandomId(); + let configXml = ``; + configXml += ``; + configXml += ``; + configXml += `` + configXml += ``; + configXml += `${appName}`; + configXml += ``; + configXml += ``; + copyManifest(convertedConfigXml, configXml); + convertedConfigXml = `${downloadVirtualDir}/${appName}/config.xml`; + refCount++; +} + +function cleanUpAndQuit(appName: string) { + let workingDir = `${baseWorkingDir}/${appName}`; + fs.rmdirSync(workingDir, { recursive: true }); + process.exit(); +} + +function installWgt(appName: string) { + let onInstallation = { + onprogress: (packageId: string, percentage: string) => { + console.log("On installation(" + packageId + ") : progress(" + percentage + ")"); + }, + oncomplete: (packageId: string) => { + console.log("Installation(" + packageId + ") Complete"); + wrt.postPlainNotification(appName, 'Install Success', 5); + cleanUpAndQuit(appName); + } + }; + let wgtPath = `${baseWorkingDir}/${appName}/${appName}.wgt`; + console.log(`wgtPath: ${wgtPath}`); + global.tizen.package.install(wgtPath, onInstallation, (err: any) => { + console.log("Error occurred on installation : " + err.name); + cleanUpAndQuit(appName); + }); +} + +function makeWgt(appName: string) { + let wgtPath = `${downloadVirtualDir}/${appName}/${appName}.wgt`; + let onArchive = (archive: any) => { + function progressCallback(opId: string, val: number, name: any) { + console.log('opId: ' + opId + ' with progress val: ' + (val * 100).toFixed(0) + '%'); + } + function successCallback() { + console.log(`File added : ${refCount}`); + refCount--; + if (!refCount) { + installWgt(appName); + } + } + console.log(`convertedConfigXml : ${convertedConfigXml}`); + console.log(`manifestFile : ${manifestFile}`); + console.log(`iconFile : ${iconFile}`); + let defaultArchiveFileEntryOption = { destination:'', stripSourceDirectory: true}; + archive.add(convertedConfigXml, successCallback, null, progressCallback, defaultArchiveFileEntryOption); + archive.add(manifestFile, successCallback, null, progressCallback, defaultArchiveFileEntryOption); + if (iconFile) + archive.add(iconFile, successCallback, null, progressCallback, defaultArchiveFileEntryOption); + } + global.tizen.archive.open(wgtPath, 'w', onArchive, () => { }, { overwrite: true }); +} + +async function parseAndHandleManifest(manifestUrl: string) { + let manifest: any = await getManifestFile(manifestUrl); + let appName = getAppName(manifest['name']); + try { + makeWorkingFolder(appName); + if (manifest['icons']) { + await handleIcon(appName, manifestUrl, manifest); + } + if (manifest['start_url']) { + let startUrl = handleStartUrl(appName, manifestUrl, manifest); + convertConfigXml(appName, startUrl); + } + makeWgt(appName); + } catch (e) { + console.log(`Exception: ${e}`); + cleanUpAndQuit(appName); + } +} + +export function run(manifestUrl: string) { + console.log(`Appmanifest parser starts for ${manifestUrl}`); + setInterval(() => { }, 500); + wrt.tv?.delayShutdown(); + XWalkExtension.initialize(); + parseAndHandleManifest(manifestUrl); +} + +if (!isMainThread) { + run(decodeURIComponent(workerData.id)); +} diff --git a/wrt_app/service/builtins/wasm_builder.ts b/wrt_app/service/builtins/wasm_builder.ts index 54177d0..e23ac17 100644 --- a/wrt_app/service/builtins/wasm_builder.ts +++ b/wrt_app/service/builtins/wasm_builder.ts @@ -1,13 +1,13 @@ import '../../common/init'; -import { isMainThread, parentPort, workerData } from 'worker_threads'; +import { isMainThread, workerData } from 'worker_threads'; import { wrt } from '../../browser/wrt'; import * as fs from 'fs'; function compileWasmForCaching(files: string[]) { try { - files.forEach(async file_path => { - console.log(`Requesting WASM compilation for building a cache, file_path:(${file_path})`); - let source = fs.readFileSync(file_path); + files.forEach(async filePath => { + console.log(`Requesting WASM compilation for building a cache, file_path:(${filePath})`); + let source = fs.readFileSync(filePath); let file = new Uint8Array(source); await WebAssembly.compile(file); }); @@ -16,12 +16,12 @@ function compileWasmForCaching(files: string[]) { } } -export function run(app_id: string) { - console.log(`wasm_builder.js starts, app_id:(${app_id})`); +export function run(appId: string) { + console.log(`wasm_builder.js starts, app_id:(${appId})`); let tv = wrt.tv as NativeWRTjs.TVExtension; tv.setWasmFlags(); - tv.setDiskCache(app_id); - let files = tv.getWasmFiles(app_id); + tv.setDiskCache(appId); + let files = tv.getWasmFiles(appId); console.log(files); tv.delayShutdown(); compileWasmForCaching(files); -- 2.7.4 From 81b700da16e52295da22da13b22568384313044e Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Thu, 28 Jan 2021 11:51:40 +0900 Subject: [PATCH 03/16] [M85][MDE] Support MDE interfaces This supports MDE interfaces. Reference: https://review.tizen.org/gerrit/248308 Together with: https://review.tizen.org/gerrit/252383 Change-Id: Ifa6f5d96606979918d4b134abcd48405e5e4654b Signed-off-by: Youngsoo Choi --- wrt_app/service/device_api_router.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index 735eb57..9e2495b 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -64,9 +64,38 @@ export class DeviceAPIRouter { getServiceId: { writable: false, enumerable: true }, postPlainNotification: { writable: false, enumerable: true }, }); + this.initMDEWebapis(); this.initProductWebapis(); } + initMDEWebapis() { + if (wrt['mde'] && !global.webapis.mde) { + let mde = wrt.mde as NativeWRTjs.MDEExtension; + global.webapis.mde = {}; + if (wrt.tv) { + global.webapis.mde.deInitVirtualEventGenerator = (type: number) => { + return mde.deInitVirtualEventGenerator(type); + } + global.webapis.mde.generateVirtualKeyEvent = (keycode: number, state: number) => { + return mde.generateVirtualKeyEvent(keycode, state); + } + global.webapis.mde.generateVirtualMouseButtonEvent = (button: number, status: number) => { + return mde.generateVirtualMouseButtonEvent(button, status); + } + global.webapis.mde.generateVirtualMouseMoveEvent = (x: number, y: number, move_count: number) => { + return mde.generateVirtualMouseMoveEvent(x, y, move_count); + } + global.webapis.mde.initVirtualEventGenerator = (type: number) => { + return mde.initVirtualEventGenerator(type); + } + } + global.webapis.mde.launchBrowserFromUrl = (url: string) => { + return mde.launchBrowserFromUrl(url); + } + Object.defineProperty(global.webapis, 'mde', { writable: false, enumerable: true }); + } + } + initProductWebapis() { // for TV profile if (wrt.tv && !global.webapis.productinfo) { -- 2.7.4 From 73bfef03506dee58ff00e5b2a116ba0662f4cc26 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Mon, 1 Feb 2021 11:21:48 +0900 Subject: [PATCH 04/16] Set DEFAULT_TIZEN_VERSION to 6.5 This sets DEFAULT_TIZEN_VERSION to 6.5 as per current tizen branch version. Change-Id: I9d5d20edef1a89f5865909bb5eff691c49f7b264 Signed-off-by: Youngsoo Choi --- tizen/build/common.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tizen/build/common.sh b/tizen/build/common.sh index 98325fe..e2bcb49 100755 --- a/tizen/build/common.sh +++ b/tizen/build/common.sh @@ -4,7 +4,7 @@ export SCRIPTDIR=$(readlink -e $(dirname $0)) export TOPDIR=$(readlink -f "${SCRIPTDIR}/../..") export CHROME_SRC="${TOPDIR}" -export LATEST_TIZEN_VERSION=6.0 +export LATEST_TIZEN_VERSION=6.5 export DEFAULT_TIZEN_VERSION=$LATEST_TIZEN_VERSION if [ "$(echo "$@" | grep -e "--tizen")" != "" ]; then @@ -82,9 +82,13 @@ function setupAndExecuteTargetBuild() { if [ "$PROFILE" == "" ]; then if [[ $platform == "tv" ]]; then - PROFILE=tztv_${DEFAULT_TIZEN_VERSION}_arm-nikem + #TODO: Once 6.5 tv repo is ready, uncomment following line + #PROFILE=tztv_${DEFAULT_TIZEN_VERSION}_arm-nikem + PROFILE=tztv_6.0_arm-nikem elif [[ $platform == "da" ]]; then - PROFILE=tzda_${DEFAULT_TIZEN_VERSION}_arm-kantm + #TODO: Once 6.5 fhub repo is ready, uncomment following line + #PROFILE=tzda_${DEFAULT_TIZEN_VERSION}_arm-kantm + PROFILE=tzda_6.0_arm-kantm elif [[ $platform == "wearable" ]]; then PROFILE=tzwr_5.5_arm-spin else -- 2.7.4 From c5579c01ee9b8cd8ea20aba220dbf5f7c8c73fd5 Mon Sep 17 00:00:00 2001 From: SangYong Park Date: Mon, 8 Feb 2021 14:51:30 +0900 Subject: [PATCH 05/16] Fix addon api and support chrome extension addon app Related: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/253273/ Change-Id: Icc2c0533199bb075d1ecf64bc7d22ed39be4513b Signed-off-by: SangYong Park --- wrt_app/src/addon_manager.ts | 113 ++++++++++++++++++++++++++----------------- wrt_app/src/runtime.ts | 29 ++--------- 2 files changed, 72 insertions(+), 70 deletions(-) diff --git a/wrt_app/src/addon_manager.ts b/wrt_app/src/addon_manager.ts index 4d25a33..aeb6943 100644 --- a/wrt_app/src/addon_manager.ts +++ b/wrt_app/src/addon_manager.ts @@ -20,17 +20,18 @@ import * as fs from 'fs'; import * as os from 'os'; import * as path from 'path'; import { EventEmitter } from 'events'; -import { ipcMain } from 'electron'; +import { ipcMain, session } from 'electron'; import { wrt } from '../browser/wrt'; interface AddonModule { - activate: () => void; - deactivate: () => void; + activate?: () => void; + deactivate?: () => void; + id?: string; } interface AddonInfo { name: string; - version: string; + isChromeExtension: boolean; path: string; pkgid: string; activate: boolean; @@ -126,15 +127,13 @@ class AddonManager { constructor() { ipcMain.on(InternalEvent.installed, (sender, name) => { console.log('Addon event : INSTALLED ' + name); - this.build(); + this.loadJsonDB(); return this.activateByName(name); }); ipcMain.on(InternalEvent.uninstalled, (sender, name, pkgid) => { console.log('Addon event : UNINSTALLED ' + name); this.deactivateByName(name); - /* FIXME: will uncheck after chromium-efl released */ - if (wrt.getPlatformType() !== "product_tv") - wrt.reqUninstallPkg(pkgid); + wrt.requestUninstallAddon(pkgid); return true; }); ipcMain.on(InternalEvent.activate, (sender, name) => { @@ -147,9 +146,8 @@ class AddonManager { }); } - private loadJsonDB(dbPath?: string): void { - if (!dbPath) - dbPath = path.join(ADN_PATH, ADDONS_DB_FILE); + private loadJsonDB(): void { + const dbPath = path.join(ADN_PATH, ADDONS_DB_FILE); let list; try { list = JSON.parse(fs.readFileSync(dbPath, 'utf-8')); @@ -160,47 +158,73 @@ class AddonManager { this.addonList = list; } - build(): boolean { - this.loadJsonDB(); - for (let addon of this.addonList) { - if (addon.activate == false) - continue; - console.log('addon ' + addon.name + '(' + addon.path + ') registered'); - } + initialize(): boolean { + wrt.on('addon-installed', (event: any, pathList: string[]) => { + for (let path of pathList) { + console.log('addon-installed at ' + path); + this.checkAddon(path); + } + this.updateDB(); + }); + + wrt.on('addon-uninstalled', (event: any, id: string) => { + console.log('addon-unistalled named ' + id); + }); + + wrt.requestAddonList(); return this.isAddonAvailable(); } - private getModule(addon: AddonInfo): AddonModule | undefined { + private activate(addon: AddonInfo) { + console.log('activate: ' + addon.path + ' name:' + addon.name); + if (!addon.activate) + return; if (addon.module) - return addon.module; + return; + try { - const addonModule = require(addon.path); - let addonInstance = new addonModule(this.eventManager.createBinder(addon)); - addon.module = addonInstance; + if (addon.isChromeExtension) { + session.defaultSession.loadExtension(addon.path).then((extension: Electron.Extension) => { + if (addon.module) + addon.module.id = extension.id; + else { + console.log('addon was deactivated') + session.defaultSession.removeExtension(extension.id); + } + }); + addon.module = {}; + } else { + const addonModule = require(addon.path); + let addonInstance = new addonModule(this.eventManager.createBinder(addon)); + addon.module = addonInstance; + if (addonInstance.activate) + addonInstance.activate(); + else + console.log('addon.activate not defined!'); + } } catch (e) { console.error('error on creating addon instance : ' + e); } - return addon.module; - } - - private activate(addon: AddonInfo) { - console.log('activate: ' + addon.path + ' name:' + addon.name); - if (!addon.activate) - return; - let addonInstance = this.getModule(addon); - if (addonInstance && addonInstance.activate) - addonInstance.activate(); - else - console.log('addon.activate not defined!'); } private deactivate(addon: AddonInfo) { console.log('deactivate: ' + addon.path + ' name:' + addon.name); - let addonInstance = this.getModule(addon); - if (addonInstance && addonInstance.deactivate) - addonInstance.deactivate(); - else - console.log('addon.deactivate not defined!'); + let addonInstance = addon.module; + if (!addonInstance) { + console.log('addon is not loaded'); + return; + } + + if (addon.isChromeExtension) { + if (addonInstance.id) + session.defaultSession.removeExtension(addonInstance.id); + } else { + if (addonInstance.deactivate) + addonInstance.deactivate(); + else + console.log('addon.deactivate not defined!'); + } + addon.module = undefined; } private getAddonInfo(name: string): AddonInfo | undefined { @@ -249,7 +273,7 @@ class AddonManager { this.eventManager.emit(eventName, ...args); } - checkAddon(appPath: string) { + private checkAddon(appPath: string) { let manifest; try { let manifestPath = path.join(appPath, MANIFEST_FILE); @@ -268,16 +292,17 @@ class AddonManager { } } + const isChromeExtension = ('manifest_version' in manifest); this.addonList.push({ name: manifest.name, - version: manifest.version, - path: path.join(appPath, manifest.main), + isChromeExtension, + path: isChromeExtension ? appPath : path.join(appPath, manifest.main), pkgid: arr[index], activate: true }); } - updateDB() { + private updateDB() { let dbPath = path.join(ADN_PATH, ADDONS_DB_FILE); let currentAddonList; try { diff --git a/wrt_app/src/runtime.ts b/wrt_app/src/runtime.ts index a729356..925a2e5 100644 --- a/wrt_app/src/runtime.ts +++ b/wrt_app/src/runtime.ts @@ -23,7 +23,6 @@ import { WebApplication } from './web_application'; class Runtime { webApplication?: WebApplication = undefined; - isLaunched = false; constructor() { app.on('before-quit', (event: any) => { @@ -46,10 +45,6 @@ class Runtime { app.on('browser-window-created', () => { console.log('browser-window-created'); - if (!this.isLaunched) { - addonManager.activateAll(); - this.isLaunched = true; - } }); app.on('window-all-closed', () => { @@ -60,14 +55,13 @@ class Runtime { app.on('web-contents-created', (event: any, webContents: any) => { console.log('web-contents-created'); webContents.on('before-input-event', (event: any, input: any) => { - if (this.isLaunched && this.webApplication) - this.handleKeyEvents(input.key); + this.handleKeyEvents(input.key); }); }); app.once('ready', (event: any) => { console.log('ready'); - let addonAvailable = addonManager.build(); + let addonAvailable = addonManager.initialize(); console.log("addonBuild : " + addonAvailable); if (addonAvailable) { const XWalkExtension = require('../common/wrt_xwalk_extension'); @@ -127,24 +121,6 @@ class Runtime { console.log('ambient-changed , ambient_mode:' + ambient_mode); this.webApplication?.ambientChanged(ambient_mode); }); - - wrt.on('addon-installed', (event: any, path: string) => { - console.log('addon-installed at ' + path); - addonManager.checkAddon(path); - }); - - wrt.on('addon-uninstalled', (event: any, id: string) => { - console.log('addon-unistalled named ' + id); - }); - - wrt.on('wgt-checking-done', (event: any) => { - console.log('wgt-checking-done'); - addonManager.updateDB(); - }); - - /* FIXME: will uncheck after chromium-efl released */ - if (wrt.getPlatformType() !== "product_tv") - wrt.getInstalledPkg(); } private handleAppControlForElectronApp(appControl: any) { @@ -165,6 +141,7 @@ class Runtime { private createWebApplicationAndLoadUrl(appControl: any) { console.log('Creating WebApplication'); + addonManager.activateAll(); let launchMode = appControl.getData('http://samsung.com/appcontrol/data/launch_mode'); let options: RuntimeOption = { isAddonAvailable: addonManager.isAddonAvailable(), -- 2.7.4 From 8fdbbe55276275c63760ebc6bd48a830c1410e29 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Tue, 19 Jan 2021 11:53:31 +0900 Subject: [PATCH 06/16] [M85][Service] Drop thread privilege of service app This drops the privilege of service app and sets it to User::Pkg::{PKG_ID}. With this changes, the service app is under control of kernel smack rule. Reference: https://review.tizen.org/gerrit/249081 Together with: https://review.tizen.org/gerrit/251775 Change-Id: I0cd14f159b61b17dc395fd938144a0646529a2d9 Signed-off-by: Youngsoo Choi --- wrt_app/service/access_control_manager.ts | 4 +++- wrt_app/service/device_api_router.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/wrt_app/service/access_control_manager.ts b/wrt_app/service/access_control_manager.ts index 87afb7a..b3d804c 100644 --- a/wrt_app/service/access_control_manager.ts +++ b/wrt_app/service/access_control_manager.ts @@ -1,3 +1,4 @@ +import { wrt } from '../browser/wrt'; function checkSystemInfoApiPrivilege(func: any, permissions: string[]) { let override_func = func; @@ -10,7 +11,8 @@ function checkSystemInfoApiPrivilege(func: any, permissions: string[]) { } } -export function initialize(permissions: string[]) { +export function initialize(packageId: string, appId: string, permissions: string[]) { + wrt.security?.dropThreadPrivilege(packageId, appId); let tizen = global.tizen; if (!permissions.includes("http://tizen.org/privilege/alarm")) { tizen.alarm.add = diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index 9e2495b..c083c11 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -154,7 +154,7 @@ export class DeviceAPIRouter { initAccessControlManager() { console.log(`permissions : ${this.permissions}`); const AccessControlManager = require('./access_control_manager'); - AccessControlManager.initialize(this.permissions); + AccessControlManager.initialize(this.packageId, this.serviceId, this.permissions); } getServiceId() { -- 2.7.4 From 8d93875633c43a9be7156f997e3a34ba4928fb37 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Thu, 18 Feb 2021 18:50:38 +0900 Subject: [PATCH 07/16] [Service][VD] move mount/umount to JS side Explicitly handles mount/umount on JS side to simplify logic of WRTServiceManager. Related chromium-efl patch: https://review.tizen.org/gerrit/253835/ Change-Id: I89874f752d8113d6582a238acce9b0b328b635ab Signed-off-by: DongHyun Song --- wrt_app/common/service_runner.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wrt_app/common/service_runner.ts b/wrt_app/common/service_runner.ts index 3522d75..13baa02 100644 --- a/wrt_app/common/service_runner.ts +++ b/wrt_app/common/service_runner.ts @@ -108,6 +108,9 @@ export function stop(id: string) { function run() { let id = workerData.id; + // FIXME: this should be 'wrt.tv?.serviceMount(id)' after Tizen 6.5 release + (wrt.tv as any)?.serviceMount(id); + let filename = workerData.filename; start(id, filename); @@ -120,6 +123,7 @@ function run() { setTimeout(() => { XWalkExtension.cleanup(); parentPort?.postMessage("will-terminate"); + (wrt.tv as any)?.serviceUmount(id); }, message.delay); } }); -- 2.7.4 From fb1486338c019c8d3ea4803f4252f76ff8189c62 Mon Sep 17 00:00:00 2001 From: liwei Date: Fri, 5 Mar 2021 11:09:41 +0800 Subject: [PATCH 08/16] [VD] Remove timeout when app is quit in non-multitasking scenario In TV, visibility change callback is moved earlier,so this timeout is unncessary. Timeout logic is added in https://review.tizen.org/gerrit/208100/ Change-Id: I5467b688987a23f7b72cb0984b38671538da5f40 Signed-off-by: liwei --- wrt_app/src/web_application.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/wrt_app/src/web_application.ts b/wrt_app/src/web_application.ts index e6cc16c..6afc4ac 100644 --- a/wrt_app/src/web_application.ts +++ b/wrt_app/src/web_application.ts @@ -413,11 +413,8 @@ Then you can get profile log from the initial loading.`; this.flushData(); if (!this.backgroundRunnable()) { if (!this.multitaskingSupport) { - // FIXME : terminate app after visibilitychange event handling - setTimeout(() => { - console.log('multitasking is not supported; quitting app') - app.quit(); - }, 1000); + console.log('multitasking is not supported; quitting app') + app.quit(); } else { this.windowList.forEach((window) => window.setEnabled(false)); } -- 2.7.4 From a47b04acbef17108bfc13c0cf3ca0331b95181c5 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Thu, 11 Mar 2021 13:45:26 +0900 Subject: [PATCH 09/16] [Service] Move dropThreadPrivilege() before app starting If applying app smack label before of webapis related works, there are fails of loading webapis due to smack deny. Of course, at first time, before loading webapis, app label should be applied on the node worker thread. But kind of modules are checking the privileges with 'pid', not 'tid' So, webapis loading are not loaded all successfully. This patch makes to defer privilege drop after webapis related works. (access_control_manager, device_api_router) Change-Id: I89849e4271cddde2e22a6bca77f77b503ee30cd8 Signed-off-by: DongHyun Song --- wrt_app/common/service_runner.ts | 6 ++++++ wrt_app/service/access_control_manager.ts | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/wrt_app/common/service_runner.ts b/wrt_app/common/service_runner.ts index 13baa02..f372d96 100644 --- a/wrt_app/common/service_runner.ts +++ b/wrt_app/common/service_runner.ts @@ -75,7 +75,13 @@ export function start(id: string, filename: string) { // uv loop is sleeping for a few second with tizen webapis's aync callback fakeTimer = setInterval(() => {}, 100); printAppControlData(id); + try { + let ids = id.split(':'); + let serviceId = ids[0]; + let packageId = serviceId.split('.')[0]; + wrt.security?.dropThreadPrivilege(packageId, serviceId); + app = require(filename); if (app.onStart !== undefined) { app.onStart(); diff --git a/wrt_app/service/access_control_manager.ts b/wrt_app/service/access_control_manager.ts index b3d804c..49b063e 100644 --- a/wrt_app/service/access_control_manager.ts +++ b/wrt_app/service/access_control_manager.ts @@ -12,7 +12,6 @@ function checkSystemInfoApiPrivilege(func: any, permissions: string[]) { } export function initialize(packageId: string, appId: string, permissions: string[]) { - wrt.security?.dropThreadPrivilege(packageId, appId); let tizen = global.tizen; if (!permissions.includes("http://tizen.org/privilege/alarm")) { tizen.alarm.add = -- 2.7.4 From 96a245880b341f10c494eff565165349223d05fc Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Fri, 22 Jan 2021 12:33:49 +0900 Subject: [PATCH 10/16] [Service] Add MDE webapis This adds following MDE APIs to get device name and login id. >> webapis.mde.getCurrentLoginId() >> webapis.mde.getDeviceName() Together with: https://review.tizen.org/gerrit/252719 Change-Id: I070ca304e3b95c07c9426ad6f32b012c5c1f01ca Signed-off-by: Youngsoo Choi --- wrt_app/service/device_api_router.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wrt_app/service/device_api_router.ts b/wrt_app/service/device_api_router.ts index c083c11..4278274 100644 --- a/wrt_app/service/device_api_router.ts +++ b/wrt_app/service/device_api_router.ts @@ -89,6 +89,12 @@ export class DeviceAPIRouter { return mde.initVirtualEventGenerator(type); } } + global.webapis.mde.getCurrentLoginId = () => { + return mde.getCurrentLoginId(); + } + global.webapis.mde.getDeviceName = () => { + return mde.getDeviceName(); + } global.webapis.mde.launchBrowserFromUrl = (url: string) => { return mde.launchBrowserFromUrl(url); } -- 2.7.4 From 24de13c3de708d154cb24fd043fd59d60d7d8bc8 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Mon, 15 Mar 2021 22:54:38 -0700 Subject: [PATCH 11/16] [VD] Add tizen 6.5 repository This adds tizen 6.5 repository. * Build Command for tizen 6.5: $ ./tizen/build/build_tv.sh * Build Command for tizen 6.0: $ ./tizen/build/build_tv.sh -P tztv_6.0_arm-nikem Together with: https://review.tizen.org/gerrit/255261 Change-Id: I6af8b4afa460a5bea155e2e4ef1fbea9aff72a8e Signed-off-by: Youngsoo Choi --- tizen/build/common.sh | 4 +--- tizen/build/gbs.conf.in | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/tizen/build/common.sh b/tizen/build/common.sh index e2bcb49..c62935a 100755 --- a/tizen/build/common.sh +++ b/tizen/build/common.sh @@ -82,9 +82,7 @@ function setupAndExecuteTargetBuild() { if [ "$PROFILE" == "" ]; then if [[ $platform == "tv" ]]; then - #TODO: Once 6.5 tv repo is ready, uncomment following line - #PROFILE=tztv_${DEFAULT_TIZEN_VERSION}_arm-nikem - PROFILE=tztv_6.0_arm-nikem + PROFILE=tztv_${DEFAULT_TIZEN_VERSION}_arm-nikem elif [[ $platform == "da" ]]; then #TODO: Once 6.5 fhub repo is ready, uncomment following line #PROFILE=tzda_${DEFAULT_TIZEN_VERSION}_arm-kantm diff --git a/tizen/build/gbs.conf.in b/tizen/build/gbs.conf.in index 034aedf..149de31 100644 --- a/tizen/build/gbs.conf.in +++ b/tizen/build/gbs.conf.in @@ -104,6 +104,25 @@ passwdx = QlpoOTFBWSZTWd0JOhUAAACBAABgIAAhAIIjF3JFOFCQ3Qk6FQ== [obs.tizen_product_tv] url = https://168.219.243.64/api +############################################### +# +# Tizen v6.5 for product tv (NikeM armv7l) +# +[profile.tztv_6.5_arm-nikem] +obs = obs.tizen_product_tv +repos = repo.tv_product_6.5_nikem, repo.tv_product_6.5_base +buildroot = ~/GBS-ROOT-TZTV_6.5_ARM-NIKEM + +[repo.tv_product_6.5_base] +url = http://168.219.244.109/tizen-rsa/tizen-6.5-base/standard/latest/ +user = blinkbot +passwdx = QlpoOTFBWSZTWd0JOhUAAACBAABgIAAhAIIjF3JFOFCQ3Qk6FQ== + +[repo.tv_product_6.5_nikem] +url = http://168.219.244.109/products/tv/development/PRECEDENCE/Tizen_Integration/NikeM/latest/ +user = blinkbot +passwdx = QlpoOTFBWSZTWd0JOhUAAACBAABgIAAhAIIjF3JFOFCQ3Qk6FQ== + ############################################ # # Tizen v6.0 for product tv (NikeM armv7l) -- 2.7.4 From ff7ca9f52cacf773256a714d884848dde9e0641a Mon Sep 17 00:00:00 2001 From: liwei Date: Mon, 15 Mar 2021 13:58:07 +0800 Subject: [PATCH 12/16] Minor refactor logic of quit for non-multitasking app 1.If app run in background and not support multitasking, app will quit immediatly, window will be desotried, then exception will happen, so ahead timing of addon event to avid window is null, ahead timing of addon event contentDidFinishLoad. 2.Set timeout to 0 for app.quit(), then it will be a little delay, it can avoid crash. Change-Id: I8c0cc11f13c48384e5a3e1965a1fc27353e81a3a Signed-off-by: liwei --- wrt_app/src/web_application.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/wrt_app/src/web_application.ts b/wrt_app/src/web_application.ts index 6afc4ac..9d782c7 100644 --- a/wrt_app/src/web_application.ts +++ b/wrt_app/src/web_application.ts @@ -278,6 +278,7 @@ export class WebApplication { console.log('webContents did-finish-load'); this.loadFinished = true; wrt.hideSplashScreen(1); + addonManager.emit('contentDidFinishLoad', this.mainWindow.id); if (wrt.isIMEWebApp()) { this.activateIMEWebHelperClient(); } else if (wrt.tv) { @@ -286,7 +287,6 @@ export class WebApplication { else this.suspendByStatus(); } - addonManager.emit('contentDidFinishLoad', this.mainWindow.id); }); } @@ -411,13 +411,12 @@ Then you can get profile log from the initial loading.`; this.suspended = true; this.windowList[this.windowList.length - 1].hide(); this.flushData(); - if (!this.backgroundRunnable()) { - if (!this.multitaskingSupport) { + this.windowList.forEach((window) => window.setEnabled(false)); + if (!this.backgroundRunnable() && !this.multitaskingSupport) { + setTimeout(() => { console.log('multitasking is not supported; quitting app') app.quit(); - } else { - this.windowList.forEach((window) => window.setEnabled(false)); - } + }, 0); } } -- 2.7.4 From d9ab1bd27d32160de1580393b1be67060b0a17f7 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Wed, 10 Mar 2021 18:09:59 +0900 Subject: [PATCH 13/16] [Service] Check launcher process Check launcher process if it is alive, otherwise stop the service. Related chromium-efl patch: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/247802/ Change-Id: Iac686bcf5ecc5acaec69599f11571a00f137de22 Signed-off-by: DongHyun Song --- wrt_app/common/service_runner.ts | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/wrt_app/common/service_runner.ts b/wrt_app/common/service_runner.ts index f372d96..4c62afb 100644 --- a/wrt_app/common/service_runner.ts +++ b/wrt_app/common/service_runner.ts @@ -51,7 +51,20 @@ let requestStopService = (id: string) => { } let app: any = null; -let fakeTimer: any; +let dummyTimer: any; +let periodLauncherAlive = 20; // 2s + +let checkLauncherAlive = (id: string) => { + periodLauncherAlive--; + if (!periodLauncherAlive) { + periodLauncherAlive = 20; + if (!wrt.checkLauncherAlive(id)) { + console.log(`${id} launcher was killed.`) + requestStopService(id); + checkLauncherAlive = () => {}; + } + } +} export function start(id: string, filename: string) { XWalkExtension.initialize(); @@ -71,9 +84,10 @@ export function start(id: string, filename: string) { console.log(`start global service file: ${filename}`); } - // FIXME: this is for awaking up uv loop. - // uv loop is sleeping for a few second with tizen webapis's aync callback - fakeTimer = setInterval(() => {}, 100); + // This is for awaking up uv loop. + dummyTimer = setInterval(() => { + checkLauncherAlive(id); + }, 100); printAppControlData(id); try { @@ -99,8 +113,8 @@ export function start(id: string, filename: string) { } export function stop(id: string) { - if (fakeTimer) - clearInterval(fakeTimer); + if (dummyTimer) + clearInterval(dummyTimer); try { if (app.onStop !== undefined) { app.onStop(); -- 2.7.4 From 93f8a4ffa77df1b6fc850f57eb143b10ed3f575c Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Thu, 18 Mar 2021 18:48:26 -0700 Subject: [PATCH 14/16] [Public][Service] Upgrade d2d app version as v1.0.1 This upgrades d2d app version as v1.0.1. Change-Id: I6c305c011537e026779634993a56fcaec1d02425 Signed-off-by: Youngsoo Choi --- d2d_app/about.html | 15 + d2d_app/client/client.html | 121 +- d2d_app/client/control.html | 196 + d2d_app/client/css/app-remote-control-basic.css | 478 + d2d_app/client/css/pincode.css | 302 + d2d_app/client/css/style.css | 141 +- d2d_app/client/images/Hamburger_icon.svg | 1 + d2d_app/client/images/control/btn_down.png | Bin 0 -> 9767 bytes d2d_app/client/images/control/btn_minus.png | Bin 0 -> 9477 bytes d2d_app/client/images/control/btn_plus.png | Bin 0 -> 9507 bytes d2d_app/client/images/control/btn_up.png | Bin 0 -> 9766 bytes d2d_app/client/images/control/control1_bg .png | Bin 0 -> 10420 bytes d2d_app/client/images/control/control2_bg .png | Bin 0 -> 7809 bytes d2d_app/client/images/control/cta/oval/default.png | Bin 0 -> 4606 bytes d2d_app/client/images/control/default.png | Bin 0 -> 4606 bytes .../client/images/control/ic_control1_bottom.png | Bin 0 -> 458 bytes d2d_app/client/images/control/ic_control1_left.png | Bin 0 -> 603 bytes .../client/images/control/ic_control1_right.png | Bin 0 -> 606 bytes d2d_app/client/images/control/ic_control1_top.png | Bin 0 -> 489 bytes .../images/control/ic_function_media_next.svg | 15 + .../images/control/ic_function_media_prev.svg | 15 + .../images/control/ic_function_media_stop.svg | 10 + d2d_app/client/images/control/ic_home.png | Bin 0 -> 483 bytes d2d_app/client/images/control/ic_source.png | Bin 0 -> 418 bytes d2d_app/client/images/control/squarcle_bg.png | Bin 0 -> 2503 bytes .../images/control/tw_list_icon_connections.svg | 17 + d2d_app/client/images/folder.png | Bin 743 -> 0 bytes d2d_app/client/images/ic_back.png | Bin 0 -> 804 bytes d2d_app/client/images/icon.png | Bin 0 -> 57662 bytes d2d_app/client/images/tw_list_icon_wallpaper.svg | 17 + d2d_app/client/invited.html | 31 + d2d_app/client/js/actions.js | 58 + d2d_app/client/js/app.js | 513 + d2d_app/client/js/client.js | 136 +- d2d_app/client/js/clipping-storage.js | 24 + d2d_app/client/js/control.js | 211 + d2d_app/client/js/invited.js | 131 + d2d_app/client/js/jsencrypt.js | 5371 ++ d2d_app/client/js/myApps.js | 146 + d2d_app/client/js/pincode.js | 99 + d2d_app/client/lib/tau/LICENSE.Flora | 206 + d2d_app/client/lib/tau/VERSION | 1 + d2d_app/client/lib/tau/animation/tau.animation.js | 4077 ++ .../client/lib/tau/animation/tau.animation.min.js | 2 + d2d_app/client/lib/tau/mobile/js/jquery.js | 9190 +++ d2d_app/client/lib/tau/mobile/js/jquery.min.js | 4 + d2d_app/client/lib/tau/mobile/js/tau.js | 61260 +++++++++++++++++++ d2d_app/client/lib/tau/mobile/js/tau.min.js | 32 + .../mobile/theme/changeable/fonts/Roboto-Light.ttf | Bin 0 -> 321820 bytes .../theme/changeable/fonts/Roboto-Medium.ttf | Bin 0 -> 320932 bytes .../theme/changeable/fonts/Roboto-Regular.ttf | Bin 0 -> 319960 bytes .../images/0_Round_corner/bottom_left.svg | 7 + .../images/0_Round_corner/bottom_right.svg | 7 + .../changeable/images/0_Round_corner/top_left.svg | 7 + .../changeable/images/0_Round_corner/top_right.svg | 7 + .../tw_action_bar_icon_current_location_mtrl.svg | 12 + .../images/10_Search/tw_ic_ab_back_mtrl.svg | 10 + .../images/10_Search/tw_ic_ab_more_mtrl.svg | 9 + .../10_Search/tw_ic_clear_search_api_mtrl.svg | 10 + .../tw_ic_voice_search_api_mtrl_alpha.svg | 10 + .../images/13_View_controls/tw_spinner_mtrl.svg | 1 + .../tw_copypaste_cursor_handler_bottom.svg | 1 + .../tw_copypaste_cursor_handler_top.svg | 1 + .../tw_copypaste_select_handler_left.svg | 1 + .../tw_copypaste_select_handler_right.svg | 1 + .../images/17_Copy_paste/tw_ic_ab_back_mtrl.svg | 10 + .../images/17_Copy_paste/tw_ic_ab_more_mtrl.svg | 9 + .../images/1_App_bar/tw_ic_ab_add_mtrl.svg | 8 + .../images/1_App_bar/tw_ic_ab_back_mtrl.svg | 10 + .../images/1_App_bar/tw_ic_ab_more_mtrl.svg | 9 + .../images/1_App_bar/tw_ic_ab_search_mtrl.svg | 10 + .../images/1_App_bar/tw_ic_bb_delete_mtrl.svg | 9 + .../images/1_App_bar/tw_ic_bb_move_mtrl.svg | 13 + .../images/1_App_bar/tw_ic_bb_share_mtrl.svg | 12 + .../images/2_Buttons/tw_ic_ab_add_mtrl.svg | 8 + .../sem_checkedtextview_check_to_on_mtrl_000.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_001.svg | 22 + .../sem_checkedtextview_check_to_on_mtrl_002.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_003.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_004.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_005.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_006.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_007.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_008.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_009.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_010.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_011.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_012.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_013.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_014.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_015.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_016.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_017.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_018.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_019.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_020.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_021.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_022.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_023.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_024.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_025.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_026.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_000.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_001.svg | 22 + .../sem_checkedtextview_check_to_on_mtrl_002.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_003.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_004.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_005.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_006.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_007.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_008.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_009.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_010.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_011.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_012.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_013.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_014.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_015.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_016.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_017.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_018.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_019.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_020.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_021.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_022.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_023.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_024.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_025.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_026.svg | 11 + ...em_checkedtextview_check_to_on_mtrl_sprites.svg | 1 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_000.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_001.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_002.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_003.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_004.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_005.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_006.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_007.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_008.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_009.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_010.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_011.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_012.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_013.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_014.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_015.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_016.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_017.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_018.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_019.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_020.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_021.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_022.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_023.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_024.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_025.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_026.svg | 15 + .../sprites/sem_btn_radio_to_on_mtrl_sprites.svg | 1 + .../3_Controllers/gallery_btn_check_bg_mtrl.svg | 13 + .../3_Controllers/gallery_btn_uncheck_bg_mtrl.svg | 14 + .../3_Controllers/tw_chips_icon_add_mtrl.svg | 9 + .../3_Controllers/tw_chips_icon_delete_mtrl.svg | 8 + .../3_Controllers/tw_expander_close_mtrl.svg | 1 + .../images/3_Controllers/tw_expander_open_mtrl.svg | 1 + .../images/3_Controllers/tw_list_icon_add_mtrl.svg | 8 + .../3_Controllers/tw_list_icon_delete_mtrl.svg | 7 + .../images/3_Controllers/tw_list_icon_reorder.svg | 8 + .../images/4_Dialogs/tw_numberpicker_next_mtrl.svg | 9 + .../images/4_Dialogs/tw_numberpicker_prev_mtrl.svg | 9 + .../images/6_Lists/tw_expander_close_mtrl.svg | 1 + .../images/6_Lists/tw_expander_open_mtrl.svg | 1 + .../images/6_Lists/tw_list_icon_connections.svg | 17 + .../images/6_Lists/tw_list_icon_display.svg | 15 + .../images/6_Lists/tw_list_icon_notifications.svg | 16 + .../images/6_Lists/tw_list_icon_sound.svg | 15 + .../images/6_Lists/tw_list_icon_wallpaper.svg | 17 + .../images/6_Lists/tw_list_subheader_dot.svg | 9 + .../9_Progress/tw_ic_progress_download_mtrl.svg | 1 + .../9_Progress/tw_ic_progress_refresh_mtrl.svg | 1 + .../changeable/images/Thumbnail/thumbnail_001.jpg | Bin 0 -> 310337 bytes .../changeable/images/Thumbnail/thumbnail_002.jpg | Bin 0 -> 164362 bytes .../changeable/images/Thumbnail/thumbnail_003.jpg | Bin 0 -> 306954 bytes .../changeable/images/Thumbnail/thumbnail_004.jpg | Bin 0 -> 189814 bytes .../changeable/images/Thumbnail/thumbnail_005.jpg | Bin 0 -> 298598 bytes .../changeable/images/Thumbnail/thumbnail_006.jpg | Bin 0 -> 143929 bytes .../changeable/images/Thumbnail/thumbnail_007.jpg | Bin 0 -> 376861 bytes .../changeable/images/Thumbnail/thumbnail_008.jpg | Bin 0 -> 192700 bytes .../changeable/images/Thumbnail/thumbnail_009.jpg | Bin 0 -> 204721 bytes .../changeable/images/Thumbnail/thumbnail_010.jpg | Bin 0 -> 144377 bytes .../changeable/images/Thumbnail/thumbnail_011.jpg | Bin 0 -> 201768 bytes .../changeable/images/Thumbnail/thumbnail_012.jpg | Bin 0 -> 94148 bytes .../changeable/images/controls/00_button_pause.png | Bin 0 -> 3376 bytes .../client/lib/tau/mobile/theme/changeable/tau.css | 11672 ++++ .../lib/tau/mobile/theme/changeable/tau.min.css | 17 + .../mobile/theme/default/fonts/Roboto-Light.ttf | Bin 0 -> 321820 bytes .../mobile/theme/default/fonts/Roboto-Medium.ttf | Bin 0 -> 320932 bytes .../mobile/theme/default/fonts/Roboto-Regular.ttf | Bin 0 -> 319960 bytes .../default/images/0_Round_corner/bottom_left.svg | 7 + .../default/images/0_Round_corner/bottom_right.svg | 7 + .../default/images/0_Round_corner/top_left.svg | 7 + .../default/images/0_Round_corner/top_right.svg | 7 + .../tw_action_bar_icon_current_location_mtrl.svg | 12 + .../images/10_Search/tw_ic_ab_back_mtrl.svg | 10 + .../images/10_Search/tw_ic_ab_more_mtrl.svg | 9 + .../10_Search/tw_ic_clear_search_api_mtrl.svg | 10 + .../tw_ic_voice_search_api_mtrl_alpha.svg | 10 + .../images/13_View_controls/tw_spinner_mtrl.svg | 1 + .../tw_copypaste_cursor_handler_bottom.svg | 1 + .../tw_copypaste_cursor_handler_top.svg | 1 + .../tw_copypaste_select_handler_left.svg | 1 + .../tw_copypaste_select_handler_right.svg | 1 + .../images/17_Copy_paste/tw_ic_ab_back_mtrl.svg | 10 + .../images/17_Copy_paste/tw_ic_ab_more_mtrl.svg | 9 + .../default/images/1_App_bar/tw_ic_ab_add_mtrl.svg | 8 + .../images/1_App_bar/tw_ic_ab_back_mtrl.svg | 10 + .../images/1_App_bar/tw_ic_ab_more_mtrl.svg | 9 + .../images/1_App_bar/tw_ic_ab_search_mtrl.svg | 10 + .../images/1_App_bar/tw_ic_bb_delete_mtrl.svg | 9 + .../images/1_App_bar/tw_ic_bb_move_mtrl.svg | 13 + .../images/1_App_bar/tw_ic_bb_share_mtrl.svg | 12 + .../default/images/2_Buttons/tw_ic_ab_add_mtrl.svg | 8 + .../sem_checkedtextview_check_to_on_mtrl_000.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_001.svg | 22 + .../sem_checkedtextview_check_to_on_mtrl_002.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_003.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_004.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_005.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_006.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_007.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_008.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_009.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_010.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_011.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_012.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_013.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_014.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_015.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_016.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_017.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_018.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_019.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_020.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_021.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_022.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_023.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_024.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_025.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_026.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_000.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_001.svg | 22 + .../sem_checkedtextview_check_to_on_mtrl_002.svg | 16 + .../sem_checkedtextview_check_to_on_mtrl_003.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_004.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_005.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_006.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_007.svg | 18 + .../sem_checkedtextview_check_to_on_mtrl_008.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_009.svg | 17 + .../sem_checkedtextview_check_to_on_mtrl_010.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_011.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_012.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_013.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_014.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_015.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_016.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_017.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_018.svg | 11 + .../sem_checkedtextview_check_to_on_mtrl_019.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_020.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_021.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_022.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_023.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_024.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_025.svg | 10 + .../sem_checkedtextview_check_to_on_mtrl_026.svg | 11 + ...em_checkedtextview_check_to_on_mtrl_sprites.svg | 1 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg | 12 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg | 15 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg | 16 + .../Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_000.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_001.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_002.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_003.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_004.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_005.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_006.svg | 12 + .../Radio/sem_btn_radio_to_on_mtrl_007.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_008.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_009.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_010.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_011.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_012.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_013.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_014.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_015.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_016.svg | 15 + .../Radio/sem_btn_radio_to_on_mtrl_017.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_018.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_019.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_020.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_021.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_022.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_023.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_024.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_025.svg | 16 + .../Radio/sem_btn_radio_to_on_mtrl_026.svg | 15 + .../sprites/sem_btn_radio_to_on_mtrl_sprites.svg | 1 + .../3_Controllers/gallery_btn_check_bg_mtrl.svg | 13 + .../3_Controllers/gallery_btn_uncheck_bg_mtrl.svg | 14 + .../3_Controllers/tw_chips_icon_add_mtrl.svg | 9 + .../3_Controllers/tw_chips_icon_delete_mtrl.svg | 8 + .../3_Controllers/tw_expander_close_mtrl.svg | 1 + .../images/3_Controllers/tw_expander_open_mtrl.svg | 1 + .../images/3_Controllers/tw_list_icon_add_mtrl.svg | 8 + .../3_Controllers/tw_list_icon_delete_mtrl.svg | 7 + .../images/3_Controllers/tw_list_icon_reorder.svg | 8 + .../images/4_Dialogs/tw_numberpicker_next_mtrl.svg | 9 + .../images/4_Dialogs/tw_numberpicker_prev_mtrl.svg | 9 + .../images/6_Lists/tw_expander_close_mtrl.svg | 1 + .../images/6_Lists/tw_expander_open_mtrl.svg | 1 + .../images/6_Lists/tw_list_icon_connections.svg | 17 + .../images/6_Lists/tw_list_icon_display.svg | 15 + .../images/6_Lists/tw_list_icon_notifications.svg | 16 + .../default/images/6_Lists/tw_list_icon_sound.svg | 15 + .../images/6_Lists/tw_list_icon_wallpaper.svg | 17 + .../images/6_Lists/tw_list_subheader_dot.svg | 9 + .../9_Progress/tw_ic_progress_download_mtrl.svg | 1 + .../9_Progress/tw_ic_progress_refresh_mtrl.svg | 1 + .../default/images/Thumbnail/thumbnail_001.jpg | Bin 0 -> 310337 bytes .../default/images/Thumbnail/thumbnail_002.jpg | Bin 0 -> 164362 bytes .../default/images/Thumbnail/thumbnail_003.jpg | Bin 0 -> 306954 bytes .../default/images/Thumbnail/thumbnail_004.jpg | Bin 0 -> 189814 bytes .../default/images/Thumbnail/thumbnail_005.jpg | Bin 0 -> 298598 bytes .../default/images/Thumbnail/thumbnail_006.jpg | Bin 0 -> 143929 bytes .../default/images/Thumbnail/thumbnail_007.jpg | Bin 0 -> 376861 bytes .../default/images/Thumbnail/thumbnail_008.jpg | Bin 0 -> 192700 bytes .../default/images/Thumbnail/thumbnail_009.jpg | Bin 0 -> 204721 bytes .../default/images/Thumbnail/thumbnail_010.jpg | Bin 0 -> 144377 bytes .../default/images/Thumbnail/thumbnail_011.jpg | Bin 0 -> 201768 bytes .../default/images/Thumbnail/thumbnail_012.jpg | Bin 0 -> 94148 bytes .../default/images/controls/00_button_pause.png | Bin 0 -> 3376 bytes .../client/lib/tau/mobile/theme/default/tau.css | 11672 ++++ .../lib/tau/mobile/theme/default/tau.min.css | 17 + d2d_app/client/manifest.webmanifest | 13 + d2d_app/client/pincode.html | 42 + d2d_app/config.xml | 15 +- d2d_app/icon.png | Bin d2d_app/node_modules/.bin/ejs | 1 + d2d_app/node_modules/.bin/jake | 1 + d2d_app/node_modules/ansi-styles/index.js | 165 + d2d_app/node_modules/ansi-styles/license | 9 + d2d_app/node_modules/ansi-styles/package.json | 88 + d2d_app/node_modules/ansi-styles/readme.md | 147 + d2d_app/node_modules/async/.travis.yml | 5 + .../node_modules/ms/license.md => async/LICENSE} | 12 +- d2d_app/node_modules/async/README.md | 1647 + d2d_app/node_modules/async/bower.json | 38 + d2d_app/node_modules/async/component.json | 16 + d2d_app/node_modules/async/lib/async.js | 1123 + d2d_app/node_modules/async/package.json | 82 + .../async/support/sync-package-managers.js | 53 + d2d_app/node_modules/balanced-match/.npmignore | 5 + d2d_app/node_modules/balanced-match/LICENSE.md | 21 + d2d_app/node_modules/balanced-match/README.md | 91 + d2d_app/node_modules/balanced-match/index.js | 59 + d2d_app/node_modules/balanced-match/package.json | 77 + .../ms/license.md => brace-expansion/LICENSE} | 4 +- d2d_app/node_modules/brace-expansion/README.md | 129 + d2d_app/node_modules/brace-expansion/index.js | 201 + d2d_app/node_modules/brace-expansion/package.json | 75 + d2d_app/node_modules/chalk/index.js | 228 + d2d_app/node_modules/chalk/index.js.flow | 93 + d2d_app/node_modules/chalk/license | 9 + d2d_app/node_modules/chalk/package.json | 103 + d2d_app/node_modules/chalk/readme.md | 314 + d2d_app/node_modules/chalk/templates.js | 128 + d2d_app/node_modules/chalk/types/index.d.ts | 97 + d2d_app/node_modules/color-convert/CHANGELOG.md | 54 + d2d_app/node_modules/color-convert/LICENSE | 21 + d2d_app/node_modules/color-convert/README.md | 68 + d2d_app/node_modules/color-convert/conversions.js | 868 + d2d_app/node_modules/color-convert/index.js | 78 + d2d_app/node_modules/color-convert/package.json | 81 + d2d_app/node_modules/color-convert/route.js | 97 + d2d_app/node_modules/color-name/.eslintrc.json | 43 + d2d_app/node_modules/color-name/.npmignore | 107 + d2d_app/node_modules/color-name/LICENSE | 8 + d2d_app/node_modules/color-name/README.md | 11 + d2d_app/node_modules/color-name/index.js | 152 + d2d_app/node_modules/color-name/package.json | 53 + d2d_app/node_modules/color-name/test.js | 7 + d2d_app/node_modules/concat-map/.travis.yml | 4 + d2d_app/node_modules/concat-map/LICENSE | 18 + d2d_app/node_modules/concat-map/README.markdown | 62 + d2d_app/node_modules/concat-map/example/map.js | 6 + d2d_app/node_modules/concat-map/index.js | 13 + d2d_app/node_modules/concat-map/package.json | 88 + d2d_app/node_modules/concat-map/test/map.js | 39 + .../node_modules => }/cookie-signature/.npmignore | 0 .../node_modules => }/cookie-signature/History.md | 0 .../node_modules => }/cookie-signature/Readme.md | 0 .../node_modules => }/cookie-signature/index.js | 0 .../cookie-signature/package.json | 4 +- .../{express/node_modules => }/cookie/HISTORY.md | 0 .../{express/node_modules => }/cookie/LICENSE | 0 .../{express/node_modules => }/cookie/README.md | 0 .../{express/node_modules => }/cookie/index.js | 0 .../{express/node_modules => }/cookie/package.json | 4 +- .../send/node_modules => }/debug/.coveralls.yml | 0 .../send/node_modules => }/debug/.eslintrc | 0 .../send/node_modules => }/debug/.npmignore | 0 .../send/node_modules => }/debug/.travis.yml | 0 .../send/node_modules => }/debug/CHANGELOG.md | 0 .../send/node_modules => }/debug/LICENSE | 0 .../send/node_modules => }/debug/Makefile | 0 .../send/node_modules => }/debug/README.md | 0 .../send/node_modules => }/debug/component.json | 0 .../send/node_modules => }/debug/karma.conf.js | 0 .../send/node_modules => }/debug/node.js | 0 .../{express/node_modules => }/debug/package.json | 6 +- .../send/node_modules => }/debug/src/browser.js | 0 .../send/node_modules => }/debug/src/debug.js | 0 .../send/node_modules => }/debug/src/index.js | 0 .../node_modules => }/debug/src/inspector-log.js | 0 .../send/node_modules => }/debug/src/node.js | 0 .../{express/node_modules => }/depd/History.md | 7 + .../{express/node_modules => }/depd/LICENSE | 2 +- .../{express/node_modules => }/depd/Readme.md | 16 +- .../{express/node_modules => }/depd/index.js | 42 +- .../node_modules => }/depd/lib/browser/index.js | 0 .../{express/node_modules => }/depd/package.json | 47 +- d2d_app/node_modules/ejs/LICENSE | 202 + d2d_app/node_modules/ejs/README.md | 341 + d2d_app/node_modules/ejs/bin/cli.js | 212 + d2d_app/node_modules/ejs/ejs.js | 1662 + d2d_app/node_modules/ejs/ejs.min.js | 1 + d2d_app/node_modules/ejs/jakefile.js | 81 + d2d_app/node_modules/ejs/lib/ejs.js | 939 + d2d_app/node_modules/ejs/lib/utils.js | 179 + d2d_app/node_modules/ejs/package.json | 74 + d2d_app/node_modules/ejs/usage.txt | 24 + d2d_app/node_modules/escape-string-regexp/index.js | 11 + d2d_app/node_modules/escape-string-regexp/license | 21 + .../node_modules/escape-string-regexp/package.json | 81 + .../node_modules/escape-string-regexp/readme.md | 27 + d2d_app/node_modules/express-session/HISTORY.md | 429 + d2d_app/node_modules/express-session/LICENSE | 24 + d2d_app/node_modules/express-session/README.md | 862 + d2d_app/node_modules/express-session/index.js | 681 + d2d_app/node_modules/express-session/package.json | 91 + .../node_modules/express-session/session/cookie.js | 150 + .../node_modules/express-session/session/memory.js | 187 + .../express-session/session/session.js | 143 + .../node_modules/express-session/session/store.js | 102 + .../body-parser/node_modules/debug/.coveralls.yml | 1 - .../body-parser/node_modules/debug/.eslintrc | 11 - .../body-parser/node_modules/debug/.npmignore | 9 - .../body-parser/node_modules/debug/.travis.yml | 14 - .../body-parser/node_modules/debug/CHANGELOG.md | 362 - .../body-parser/node_modules/debug/LICENSE | 19 - .../body-parser/node_modules/debug/Makefile | 50 - .../body-parser/node_modules/debug/README.md | 312 - .../body-parser/node_modules/debug/component.json | 19 - .../body-parser/node_modules/debug/karma.conf.js | 70 - .../body-parser/node_modules/debug/node.js | 1 - .../body-parser/node_modules/debug/package.json | 88 - .../body-parser/node_modules/debug/src/browser.js | 185 - .../body-parser/node_modules/debug/src/debug.js | 202 - .../body-parser/node_modules/debug/src/index.js | 10 - .../node_modules/debug/src/inspector-log.js | 15 - .../body-parser/node_modules/debug/src/node.js | 248 - .../express/node_modules/debug/.coveralls.yml | 1 - .../express/node_modules/debug/.eslintrc | 11 - .../express/node_modules/debug/.npmignore | 9 - .../express/node_modules/debug/.travis.yml | 14 - .../express/node_modules/debug/CHANGELOG.md | 362 - .../express/node_modules/debug/LICENSE | 19 - .../express/node_modules/debug/Makefile | 50 - .../express/node_modules/debug/README.md | 312 - .../express/node_modules/debug/component.json | 19 - .../express/node_modules/debug/karma.conf.js | 70 - .../express/node_modules/debug/node.js | 1 - .../express/node_modules/debug/src/browser.js | 185 - .../express/node_modules/debug/src/debug.js | 202 - .../express/node_modules/debug/src/index.js | 10 - .../node_modules/debug/src/inspector-log.js | 15 - .../express/node_modules/debug/src/node.js | 248 - .../depd/lib/compat/callsite-tostring.js | 103 - .../depd/lib/compat/event-listener-count.js | 22 - .../express/node_modules/depd/lib/compat/index.js | 79 - .../finalhandler/node_modules/debug/.coveralls.yml | 1 - .../finalhandler/node_modules/debug/.eslintrc | 11 - .../finalhandler/node_modules/debug/.npmignore | 9 - .../finalhandler/node_modules/debug/.travis.yml | 14 - .../finalhandler/node_modules/debug/CHANGELOG.md | 362 - .../finalhandler/node_modules/debug/LICENSE | 19 - .../finalhandler/node_modules/debug/Makefile | 50 - .../finalhandler/node_modules/debug/README.md | 312 - .../finalhandler/node_modules/debug/component.json | 19 - .../finalhandler/node_modules/debug/karma.conf.js | 70 - .../finalhandler/node_modules/debug/node.js | 1 - .../finalhandler/node_modules/debug/package.json | 88 - .../finalhandler/node_modules/debug/src/browser.js | 185 - .../finalhandler/node_modules/debug/src/debug.js | 202 - .../finalhandler/node_modules/debug/src/index.js | 10 - .../node_modules/debug/src/inspector-log.js | 15 - .../finalhandler/node_modules/debug/src/node.js | 248 - .../node_modules/express/node_modules/ms/index.js | 152 - .../express/node_modules/ms/package.json | 82 - .../node_modules/express/node_modules/ms/readme.md | 51 - .../send/node_modules/debug/package.json | 88 - .../node_modules/send/node_modules/mime/.npmignore | 0 .../send/node_modules/mime/CHANGELOG.md | 164 - .../node_modules/send/node_modules/mime/README.md | 90 - .../node_modules/send/node_modules/mime/cli.js | 8 - .../node_modules/send/node_modules/mime/mime.js | 108 - .../send/node_modules/mime/package.json | 73 - .../send/node_modules/mime/src/build.js | 53 - .../send/node_modules/mime/src/test.js | 60 - .../node_modules/send/node_modules/mime/types.json | 1 - .../node_modules/send/node_modules/ms/index.js | 162 - .../node_modules/send/node_modules/ms/package.json | 69 - .../node_modules/send/node_modules/ms/readme.md | 60 - d2d_app/node_modules/has-flag/index.js | 8 + d2d_app/node_modules/has-flag/license | 9 + d2d_app/node_modules/has-flag/package.json | 76 + d2d_app/node_modules/has-flag/readme.md | 70 + d2d_app/node_modules/jake/Makefile | 44 + d2d_app/node_modules/jake/README.md | 17 + d2d_app/node_modules/jake/bin/bash_completion.sh | 41 + d2d_app/node_modules/jake/bin/cli.js | 31 + d2d_app/node_modules/jake/jakefile.js | 105 + d2d_app/node_modules/jake/lib/api.js | 409 + d2d_app/node_modules/jake/lib/jake.js | 319 + d2d_app/node_modules/jake/lib/loader.js | 165 + d2d_app/node_modules/jake/lib/namespace.js | 115 + d2d_app/node_modules/jake/lib/package_task.js | 406 + d2d_app/node_modules/jake/lib/parseargs.js | 134 + d2d_app/node_modules/jake/lib/program.js | 282 + d2d_app/node_modules/jake/lib/publish_task.js | 290 + d2d_app/node_modules/jake/lib/rule.js | 311 + .../node_modules/jake/lib/task/directory_task.js | 30 + d2d_app/node_modules/jake/lib/task/file_task.js | 124 + d2d_app/node_modules/jake/lib/task/index.js | 9 + d2d_app/node_modules/jake/lib/task/task.js | 439 + d2d_app/node_modules/jake/lib/test_task.js | 270 + d2d_app/node_modules/jake/lib/utils/file.js | 286 + d2d_app/node_modules/jake/lib/utils/index.js | 297 + d2d_app/node_modules/jake/lib/utils/logger.js | 24 + d2d_app/node_modules/jake/package.json | 75 + .../jake/test/integration/concurrent.js | 42 + d2d_app/node_modules/jake/test/integration/file.js | 228 + .../jake/test/integration/file_task.js | 125 + .../node_modules/jake/test/integration/helpers.js | 80 + .../node_modules/jake/test/integration/jakefile.js | 337 + .../test/integration/jakelib/concurrent.jake.js | 113 + .../jake/test/integration/jakelib/publish.jake.js | 49 + .../integration/jakelib/required_module.jake.js | 10 + .../jake/test/integration/jakelib/rule.jake.js | 222 + .../jake/test/integration/publish_task.js | 24 + d2d_app/node_modules/jake/test/integration/rule.js | 216 + .../node_modules/jake/test/integration/selfdep.js | 39 + .../jake/test/integration/task_base.js | 164 + d2d_app/node_modules/jake/test/unit/jakefile.js | 36 + d2d_app/node_modules/jake/test/unit/namespace.js | 77 + d2d_app/node_modules/jake/test/unit/parseargs.js | 169 + d2d_app/node_modules/jake/usage.txt | 16 + d2d_app/node_modules/minimatch/LICENSE | 15 + d2d_app/node_modules/minimatch/README.md | 209 + d2d_app/node_modules/minimatch/minimatch.js | 923 + d2d_app/node_modules/minimatch/package.json | 64 + .../debug/node_modules => }/ms/index.js | 0 .../send/node_modules => }/ms/license.md | 0 .../debug/node_modules => }/ms/package.json | 6 +- .../debug/node_modules => }/ms/readme.md | 0 d2d_app/node_modules/on-headers/HISTORY.md | 21 + d2d_app/node_modules/on-headers/LICENSE | 22 + d2d_app/node_modules/on-headers/README.md | 81 + d2d_app/node_modules/on-headers/index.js | 132 + d2d_app/node_modules/on-headers/package.json | 77 + .../{express/node_modules => }/parseurl/HISTORY.md | 0 .../{express/node_modules => }/parseurl/LICENSE | 0 .../{express/node_modules => }/parseurl/README.md | 0 .../{express/node_modules => }/parseurl/index.js | 0 .../node_modules => }/parseurl/package.json | 6 +- d2d_app/node_modules/random-bytes/HISTORY.md | 4 + .../node_modules/mime => random-bytes}/LICENSE | 2 +- d2d_app/node_modules/random-bytes/README.md | 77 + d2d_app/node_modules/random-bytes/index.js | 101 + d2d_app/node_modules/random-bytes/package.json | 71 + .../{express/node_modules => }/safe-buffer/LICENSE | 0 .../node_modules => }/safe-buffer/README.md | 2 + .../node_modules => }/safe-buffer/index.d.ts | 0 .../node_modules => }/safe-buffer/index.js | 2 + .../node_modules => }/safe-buffer/package.json | 42 +- d2d_app/node_modules/supports-color/browser.js | 5 + d2d_app/node_modules/supports-color/index.js | 131 + d2d_app/node_modules/supports-color/license | 9 + d2d_app/node_modules/supports-color/package.json | 85 + d2d_app/node_modules/supports-color/readme.md | 66 + d2d_app/node_modules/uid-safe/HISTORY.md | 61 + d2d_app/node_modules/uid-safe/LICENSE | 22 + d2d_app/node_modules/uid-safe/README.md | 77 + d2d_app/node_modules/uid-safe/index.js | 107 + d2d_app/node_modules/uid-safe/package.json | 85 + d2d_app/node_modules/xmlhttprequest/.jshintrc | 26 + d2d_app/node_modules/xmlhttprequest/.npmignore | 4 + d2d_app/node_modules/xmlhttprequest/LICENSE | 22 + d2d_app/node_modules/xmlhttprequest/README.md | 55 + .../xmlhttprequest/lib/XMLHttpRequest.js | 620 + d2d_app/node_modules/xmlhttprequest/package.json | 56 + d2d_app/package-lock.json | 696 + d2d_app/service/app_proxy.js | 80 +- d2d_app/service/app_router.js | 19 +- d2d_app/service/jsencrypt.js | 5371 ++ d2d_app/service/private.key | 15 + d2d_app/service/public.key | 6 + d2d_app/service/relay-server.js | 9 +- d2d_app/service/service.js | 503 +- 670 files changed, 139425 insertions(+), 6641 deletions(-) create mode 100644 d2d_app/about.html create mode 100644 d2d_app/client/control.html create mode 100644 d2d_app/client/css/app-remote-control-basic.css create mode 100644 d2d_app/client/css/pincode.css create mode 100644 d2d_app/client/images/Hamburger_icon.svg create mode 100644 d2d_app/client/images/control/btn_down.png create mode 100644 d2d_app/client/images/control/btn_minus.png create mode 100644 d2d_app/client/images/control/btn_plus.png create mode 100644 d2d_app/client/images/control/btn_up.png create mode 100644 d2d_app/client/images/control/control1_bg .png create mode 100644 d2d_app/client/images/control/control2_bg .png create mode 100644 d2d_app/client/images/control/cta/oval/default.png create mode 100644 d2d_app/client/images/control/default.png create mode 100644 d2d_app/client/images/control/ic_control1_bottom.png create mode 100644 d2d_app/client/images/control/ic_control1_left.png create mode 100644 d2d_app/client/images/control/ic_control1_right.png create mode 100644 d2d_app/client/images/control/ic_control1_top.png create mode 100644 d2d_app/client/images/control/ic_function_media_next.svg create mode 100644 d2d_app/client/images/control/ic_function_media_prev.svg create mode 100644 d2d_app/client/images/control/ic_function_media_stop.svg create mode 100644 d2d_app/client/images/control/ic_home.png create mode 100644 d2d_app/client/images/control/ic_source.png create mode 100644 d2d_app/client/images/control/squarcle_bg.png create mode 100644 d2d_app/client/images/control/tw_list_icon_connections.svg delete mode 100755 d2d_app/client/images/folder.png create mode 100644 d2d_app/client/images/ic_back.png create mode 100755 d2d_app/client/images/icon.png create mode 100644 d2d_app/client/images/tw_list_icon_wallpaper.svg create mode 100644 d2d_app/client/invited.html create mode 100644 d2d_app/client/js/actions.js create mode 100644 d2d_app/client/js/app.js create mode 100644 d2d_app/client/js/clipping-storage.js create mode 100644 d2d_app/client/js/control.js create mode 100755 d2d_app/client/js/invited.js create mode 100644 d2d_app/client/js/jsencrypt.js create mode 100755 d2d_app/client/js/myApps.js create mode 100755 d2d_app/client/js/pincode.js create mode 100644 d2d_app/client/lib/tau/LICENSE.Flora create mode 100644 d2d_app/client/lib/tau/VERSION create mode 100644 d2d_app/client/lib/tau/animation/tau.animation.js create mode 100644 d2d_app/client/lib/tau/animation/tau.animation.min.js create mode 100644 d2d_app/client/lib/tau/mobile/js/jquery.js create mode 100644 d2d_app/client/lib/tau/mobile/js/jquery.min.js create mode 100644 d2d_app/client/lib/tau/mobile/js/tau.js create mode 100644 d2d_app/client/lib/tau/mobile/js/tau.min.js create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Light.ttf create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Medium.ttf create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Regular.ttf create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/bottom_left.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/bottom_right.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/top_left.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/top_right.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_action_bar_icon_current_location_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_ab_back_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_ab_more_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_clear_search_api_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_voice_search_api_mtrl_alpha.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/13_View_controls/tw_spinner_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_cursor_handler_bottom.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_cursor_handler_top.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_select_handler_left.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_select_handler_right.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_ic_ab_back_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_ic_ab_more_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_add_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_back_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_more_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_search_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_delete_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_move_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_share_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/2_Buttons/tw_ic_ab_add_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_000.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_001.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_002.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_003.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_004.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_005.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_006.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_007.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_008.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_009.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_010.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_011.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_012.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_013.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_014.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_015.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_016.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_017.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_018.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_019.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_020.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_021.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_022.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_023.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_024.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_025.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_026.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_000.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_001.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_002.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_003.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_004.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_005.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_006.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_007.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_008.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_009.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_010.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_011.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_012.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_013.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_014.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_015.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_016.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_017.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_018.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_019.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_020.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_021.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_022.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_023.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_024.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_025.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_026.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_000.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_001.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_002.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_003.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_004.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_005.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_006.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_007.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_008.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_009.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_010.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_011.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_012.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_013.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_014.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_015.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_016.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_017.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_018.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_019.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_020.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_021.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_022.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_023.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_024.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_025.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_026.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/gallery_btn_check_bg_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_chips_icon_add_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_chips_icon_delete_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_expander_close_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_expander_open_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_add_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_delete_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_reorder.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/4_Dialogs/tw_numberpicker_next_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/4_Dialogs/tw_numberpicker_prev_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_expander_close_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_expander_open_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_connections.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_display.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_notifications.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_sound.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_wallpaper.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_subheader_dot.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/9_Progress/tw_ic_progress_download_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/9_Progress/tw_ic_progress_refresh_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_001.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_002.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_003.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_004.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_005.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_006.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_007.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_008.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_009.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_010.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_011.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_012.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/images/controls/00_button_pause.png create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/tau.css create mode 100644 d2d_app/client/lib/tau/mobile/theme/changeable/tau.min.css create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Light.ttf create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Medium.ttf create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Regular.ttf create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/bottom_left.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/bottom_right.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/top_left.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/top_right.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_action_bar_icon_current_location_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_ab_back_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_ab_more_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_clear_search_api_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_voice_search_api_mtrl_alpha.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/13_View_controls/tw_spinner_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_cursor_handler_bottom.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_cursor_handler_top.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_select_handler_left.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_select_handler_right.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_ic_ab_back_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_ic_ab_more_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_add_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_back_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_more_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_search_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_delete_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_move_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_share_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/2_Buttons/tw_ic_ab_add_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_000.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_001.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_002.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_003.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_004.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_005.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_006.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_007.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_008.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_009.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_010.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_011.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_012.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_013.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_014.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_015.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_016.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_017.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_018.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_019.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_020.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_021.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_022.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_023.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_024.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_025.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_026.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_000.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_001.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_002.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_003.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_004.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_005.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_006.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_007.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_008.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_009.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_010.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_011.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_012.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_013.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_014.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_015.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_016.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_017.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_018.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_019.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_020.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_021.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_022.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_023.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_024.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_025.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_026.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_000.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_001.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_002.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_003.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_004.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_005.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_006.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_007.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_008.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_009.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_010.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_011.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_012.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_013.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_014.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_015.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_016.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_017.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_018.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_019.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_020.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_021.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_022.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_023.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_024.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_025.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_026.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/gallery_btn_check_bg_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_chips_icon_add_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_chips_icon_delete_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_expander_close_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_expander_open_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_add_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_delete_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_reorder.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/4_Dialogs/tw_numberpicker_next_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/4_Dialogs/tw_numberpicker_prev_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_expander_close_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_expander_open_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_connections.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_display.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_notifications.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_sound.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_wallpaper.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_subheader_dot.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/9_Progress/tw_ic_progress_download_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/9_Progress/tw_ic_progress_refresh_mtrl.svg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_001.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_002.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_003.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_004.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_005.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_006.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_007.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_008.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_009.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_010.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_011.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_012.jpg create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/images/controls/00_button_pause.png create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/tau.css create mode 100644 d2d_app/client/lib/tau/mobile/theme/default/tau.min.css create mode 100644 d2d_app/client/manifest.webmanifest create mode 100755 d2d_app/client/pincode.html mode change 100755 => 100644 d2d_app/icon.png create mode 120000 d2d_app/node_modules/.bin/ejs create mode 120000 d2d_app/node_modules/.bin/jake create mode 100644 d2d_app/node_modules/ansi-styles/index.js create mode 100644 d2d_app/node_modules/ansi-styles/license create mode 100644 d2d_app/node_modules/ansi-styles/package.json create mode 100644 d2d_app/node_modules/ansi-styles/readme.md create mode 100644 d2d_app/node_modules/async/.travis.yml rename d2d_app/node_modules/{express/node_modules/ms/license.md => async/LICENSE} (87%) create mode 100644 d2d_app/node_modules/async/README.md create mode 100644 d2d_app/node_modules/async/bower.json create mode 100644 d2d_app/node_modules/async/component.json create mode 100644 d2d_app/node_modules/async/lib/async.js create mode 100644 d2d_app/node_modules/async/package.json create mode 100755 d2d_app/node_modules/async/support/sync-package-managers.js create mode 100644 d2d_app/node_modules/balanced-match/.npmignore create mode 100644 d2d_app/node_modules/balanced-match/LICENSE.md create mode 100644 d2d_app/node_modules/balanced-match/README.md create mode 100644 d2d_app/node_modules/balanced-match/index.js create mode 100644 d2d_app/node_modules/balanced-match/package.json rename d2d_app/node_modules/{express/node_modules/send/node_modules/debug/node_modules/ms/license.md => brace-expansion/LICENSE} (93%) create mode 100644 d2d_app/node_modules/brace-expansion/README.md create mode 100644 d2d_app/node_modules/brace-expansion/index.js create mode 100644 d2d_app/node_modules/brace-expansion/package.json create mode 100644 d2d_app/node_modules/chalk/index.js create mode 100644 d2d_app/node_modules/chalk/index.js.flow create mode 100644 d2d_app/node_modules/chalk/license create mode 100644 d2d_app/node_modules/chalk/package.json create mode 100644 d2d_app/node_modules/chalk/readme.md create mode 100644 d2d_app/node_modules/chalk/templates.js create mode 100644 d2d_app/node_modules/chalk/types/index.d.ts create mode 100644 d2d_app/node_modules/color-convert/CHANGELOG.md create mode 100644 d2d_app/node_modules/color-convert/LICENSE create mode 100644 d2d_app/node_modules/color-convert/README.md create mode 100644 d2d_app/node_modules/color-convert/conversions.js create mode 100644 d2d_app/node_modules/color-convert/index.js create mode 100644 d2d_app/node_modules/color-convert/package.json create mode 100644 d2d_app/node_modules/color-convert/route.js create mode 100644 d2d_app/node_modules/color-name/.eslintrc.json create mode 100644 d2d_app/node_modules/color-name/.npmignore create mode 100644 d2d_app/node_modules/color-name/LICENSE create mode 100644 d2d_app/node_modules/color-name/README.md create mode 100644 d2d_app/node_modules/color-name/index.js create mode 100644 d2d_app/node_modules/color-name/package.json create mode 100644 d2d_app/node_modules/color-name/test.js create mode 100644 d2d_app/node_modules/concat-map/.travis.yml create mode 100644 d2d_app/node_modules/concat-map/LICENSE create mode 100644 d2d_app/node_modules/concat-map/README.markdown create mode 100644 d2d_app/node_modules/concat-map/example/map.js create mode 100644 d2d_app/node_modules/concat-map/index.js create mode 100644 d2d_app/node_modules/concat-map/package.json create mode 100644 d2d_app/node_modules/concat-map/test/map.js rename d2d_app/node_modules/{express/node_modules => }/cookie-signature/.npmignore (100%) rename d2d_app/node_modules/{express/node_modules => }/cookie-signature/History.md (100%) rename d2d_app/node_modules/{express/node_modules => }/cookie-signature/Readme.md (100%) rename d2d_app/node_modules/{express/node_modules => }/cookie-signature/index.js (100%) rename d2d_app/node_modules/{express/node_modules => }/cookie-signature/package.json (90%) rename d2d_app/node_modules/{express/node_modules => }/cookie/HISTORY.md (100%) rename d2d_app/node_modules/{express/node_modules => }/cookie/LICENSE (100%) rename d2d_app/node_modules/{express/node_modules => }/cookie/README.md (100%) rename d2d_app/node_modules/{express/node_modules => }/cookie/index.js (100%) rename d2d_app/node_modules/{express/node_modules => }/cookie/package.json (92%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/.coveralls.yml (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/.eslintrc (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/.npmignore (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/.travis.yml (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/CHANGELOG.md (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/LICENSE (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/Makefile (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/README.md (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/component.json (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/karma.conf.js (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/node.js (100%) rename d2d_app/node_modules/{express/node_modules => }/debug/package.json (91%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/src/browser.js (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/src/debug.js (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/src/index.js (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/src/inspector-log.js (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/debug/src/node.js (100%) rename d2d_app/node_modules/{express/node_modules => }/depd/History.md (91%) rename d2d_app/node_modules/{express/node_modules => }/depd/LICENSE (95%) rename d2d_app/node_modules/{express/node_modules => }/depd/Readme.md (95%) rename d2d_app/node_modules/{express/node_modules => }/depd/index.js (90%) rename d2d_app/node_modules/{express/node_modules => }/depd/lib/browser/index.js (100%) rename d2d_app/node_modules/{express/node_modules => }/depd/package.json (52%) create mode 100644 d2d_app/node_modules/ejs/LICENSE create mode 100644 d2d_app/node_modules/ejs/README.md create mode 100755 d2d_app/node_modules/ejs/bin/cli.js create mode 100644 d2d_app/node_modules/ejs/ejs.js create mode 100644 d2d_app/node_modules/ejs/ejs.min.js create mode 100644 d2d_app/node_modules/ejs/jakefile.js create mode 100755 d2d_app/node_modules/ejs/lib/ejs.js create mode 100644 d2d_app/node_modules/ejs/lib/utils.js create mode 100644 d2d_app/node_modules/ejs/package.json create mode 100644 d2d_app/node_modules/ejs/usage.txt create mode 100644 d2d_app/node_modules/escape-string-regexp/index.js create mode 100644 d2d_app/node_modules/escape-string-regexp/license create mode 100644 d2d_app/node_modules/escape-string-regexp/package.json create mode 100644 d2d_app/node_modules/escape-string-regexp/readme.md create mode 100644 d2d_app/node_modules/express-session/HISTORY.md create mode 100644 d2d_app/node_modules/express-session/LICENSE create mode 100644 d2d_app/node_modules/express-session/README.md create mode 100644 d2d_app/node_modules/express-session/index.js create mode 100644 d2d_app/node_modules/express-session/package.json create mode 100644 d2d_app/node_modules/express-session/session/cookie.js create mode 100644 d2d_app/node_modules/express-session/session/memory.js create mode 100644 d2d_app/node_modules/express-session/session/session.js create mode 100644 d2d_app/node_modules/express-session/session/store.js delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.coveralls.yml delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.eslintrc delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.npmignore delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.travis.yml delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/CHANGELOG.md delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/LICENSE delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/Makefile delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/README.md delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/component.json delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/karma.conf.js delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/node.js delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/package.json delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/browser.js delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/debug.js delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/index.js delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/inspector-log.js delete mode 100644 d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/node.js delete mode 100644 d2d_app/node_modules/express/node_modules/debug/.coveralls.yml delete mode 100644 d2d_app/node_modules/express/node_modules/debug/.eslintrc delete mode 100644 d2d_app/node_modules/express/node_modules/debug/.npmignore delete mode 100644 d2d_app/node_modules/express/node_modules/debug/.travis.yml delete mode 100644 d2d_app/node_modules/express/node_modules/debug/CHANGELOG.md delete mode 100644 d2d_app/node_modules/express/node_modules/debug/LICENSE delete mode 100644 d2d_app/node_modules/express/node_modules/debug/Makefile delete mode 100644 d2d_app/node_modules/express/node_modules/debug/README.md delete mode 100644 d2d_app/node_modules/express/node_modules/debug/component.json delete mode 100644 d2d_app/node_modules/express/node_modules/debug/karma.conf.js delete mode 100644 d2d_app/node_modules/express/node_modules/debug/node.js delete mode 100644 d2d_app/node_modules/express/node_modules/debug/src/browser.js delete mode 100644 d2d_app/node_modules/express/node_modules/debug/src/debug.js delete mode 100644 d2d_app/node_modules/express/node_modules/debug/src/index.js delete mode 100644 d2d_app/node_modules/express/node_modules/debug/src/inspector-log.js delete mode 100644 d2d_app/node_modules/express/node_modules/debug/src/node.js delete mode 100644 d2d_app/node_modules/express/node_modules/depd/lib/compat/callsite-tostring.js delete mode 100644 d2d_app/node_modules/express/node_modules/depd/lib/compat/event-listener-count.js delete mode 100644 d2d_app/node_modules/express/node_modules/depd/lib/compat/index.js delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.coveralls.yml delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.eslintrc delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.npmignore delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.travis.yml delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/CHANGELOG.md delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/LICENSE delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/Makefile delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/README.md delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/component.json delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/karma.conf.js delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/node.js delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/package.json delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/browser.js delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/debug.js delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/index.js delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/inspector-log.js delete mode 100644 d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/node.js delete mode 100644 d2d_app/node_modules/express/node_modules/ms/index.js delete mode 100644 d2d_app/node_modules/express/node_modules/ms/package.json delete mode 100644 d2d_app/node_modules/express/node_modules/ms/readme.md delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/debug/package.json delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/mime/.npmignore delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/mime/CHANGELOG.md delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/mime/README.md delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/mime/cli.js delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/mime/mime.js delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/mime/package.json delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/mime/src/build.js delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/mime/src/test.js delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/mime/types.json delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/ms/index.js delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/ms/package.json delete mode 100644 d2d_app/node_modules/express/node_modules/send/node_modules/ms/readme.md create mode 100644 d2d_app/node_modules/has-flag/index.js create mode 100644 d2d_app/node_modules/has-flag/license create mode 100644 d2d_app/node_modules/has-flag/package.json create mode 100644 d2d_app/node_modules/has-flag/readme.md create mode 100644 d2d_app/node_modules/jake/Makefile create mode 100644 d2d_app/node_modules/jake/README.md create mode 100755 d2d_app/node_modules/jake/bin/bash_completion.sh create mode 100755 d2d_app/node_modules/jake/bin/cli.js create mode 100644 d2d_app/node_modules/jake/jakefile.js create mode 100644 d2d_app/node_modules/jake/lib/api.js create mode 100644 d2d_app/node_modules/jake/lib/jake.js create mode 100644 d2d_app/node_modules/jake/lib/loader.js create mode 100644 d2d_app/node_modules/jake/lib/namespace.js create mode 100644 d2d_app/node_modules/jake/lib/package_task.js create mode 100644 d2d_app/node_modules/jake/lib/parseargs.js create mode 100644 d2d_app/node_modules/jake/lib/program.js create mode 100644 d2d_app/node_modules/jake/lib/publish_task.js create mode 100644 d2d_app/node_modules/jake/lib/rule.js create mode 100644 d2d_app/node_modules/jake/lib/task/directory_task.js create mode 100644 d2d_app/node_modules/jake/lib/task/file_task.js create mode 100644 d2d_app/node_modules/jake/lib/task/index.js create mode 100644 d2d_app/node_modules/jake/lib/task/task.js create mode 100644 d2d_app/node_modules/jake/lib/test_task.js create mode 100644 d2d_app/node_modules/jake/lib/utils/file.js create mode 100644 d2d_app/node_modules/jake/lib/utils/index.js create mode 100644 d2d_app/node_modules/jake/lib/utils/logger.js create mode 100644 d2d_app/node_modules/jake/package.json create mode 100644 d2d_app/node_modules/jake/test/integration/concurrent.js create mode 100644 d2d_app/node_modules/jake/test/integration/file.js create mode 100644 d2d_app/node_modules/jake/test/integration/file_task.js create mode 100644 d2d_app/node_modules/jake/test/integration/helpers.js create mode 100644 d2d_app/node_modules/jake/test/integration/jakefile.js create mode 100644 d2d_app/node_modules/jake/test/integration/jakelib/concurrent.jake.js create mode 100644 d2d_app/node_modules/jake/test/integration/jakelib/publish.jake.js create mode 100644 d2d_app/node_modules/jake/test/integration/jakelib/required_module.jake.js create mode 100644 d2d_app/node_modules/jake/test/integration/jakelib/rule.jake.js create mode 100644 d2d_app/node_modules/jake/test/integration/publish_task.js create mode 100644 d2d_app/node_modules/jake/test/integration/rule.js create mode 100644 d2d_app/node_modules/jake/test/integration/selfdep.js create mode 100644 d2d_app/node_modules/jake/test/integration/task_base.js create mode 100644 d2d_app/node_modules/jake/test/unit/jakefile.js create mode 100644 d2d_app/node_modules/jake/test/unit/namespace.js create mode 100644 d2d_app/node_modules/jake/test/unit/parseargs.js create mode 100644 d2d_app/node_modules/jake/usage.txt create mode 100644 d2d_app/node_modules/minimatch/LICENSE create mode 100644 d2d_app/node_modules/minimatch/README.md create mode 100644 d2d_app/node_modules/minimatch/minimatch.js create mode 100644 d2d_app/node_modules/minimatch/package.json rename d2d_app/node_modules/{express/node_modules/send/node_modules/debug/node_modules => }/ms/index.js (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules => }/ms/license.md (100%) rename d2d_app/node_modules/{express/node_modules/send/node_modules/debug/node_modules => }/ms/package.json (89%) rename d2d_app/node_modules/{express/node_modules/send/node_modules/debug/node_modules => }/ms/readme.md (100%) create mode 100644 d2d_app/node_modules/on-headers/HISTORY.md create mode 100644 d2d_app/node_modules/on-headers/LICENSE create mode 100644 d2d_app/node_modules/on-headers/README.md create mode 100644 d2d_app/node_modules/on-headers/index.js create mode 100644 d2d_app/node_modules/on-headers/package.json rename d2d_app/node_modules/{express/node_modules => }/parseurl/HISTORY.md (100%) rename d2d_app/node_modules/{express/node_modules => }/parseurl/LICENSE (100%) rename d2d_app/node_modules/{express/node_modules => }/parseurl/README.md (100%) rename d2d_app/node_modules/{express/node_modules => }/parseurl/index.js (100%) rename d2d_app/node_modules/{express/node_modules => }/parseurl/package.json (93%) create mode 100644 d2d_app/node_modules/random-bytes/HISTORY.md rename d2d_app/node_modules/{express/node_modules/send/node_modules/mime => random-bytes}/LICENSE (93%) create mode 100644 d2d_app/node_modules/random-bytes/README.md create mode 100644 d2d_app/node_modules/random-bytes/index.js create mode 100644 d2d_app/node_modules/random-bytes/package.json rename d2d_app/node_modules/{express/node_modules => }/safe-buffer/LICENSE (100%) rename d2d_app/node_modules/{express/node_modules => }/safe-buffer/README.md (99%) rename d2d_app/node_modules/{express/node_modules => }/safe-buffer/index.d.ts (100%) rename d2d_app/node_modules/{express/node_modules => }/safe-buffer/index.js (96%) rename d2d_app/node_modules/{express/node_modules => }/safe-buffer/package.json (50%) create mode 100644 d2d_app/node_modules/supports-color/browser.js create mode 100644 d2d_app/node_modules/supports-color/index.js create mode 100644 d2d_app/node_modules/supports-color/license create mode 100644 d2d_app/node_modules/supports-color/package.json create mode 100644 d2d_app/node_modules/supports-color/readme.md create mode 100644 d2d_app/node_modules/uid-safe/HISTORY.md create mode 100644 d2d_app/node_modules/uid-safe/LICENSE create mode 100644 d2d_app/node_modules/uid-safe/README.md create mode 100644 d2d_app/node_modules/uid-safe/index.js create mode 100644 d2d_app/node_modules/uid-safe/package.json create mode 100644 d2d_app/node_modules/xmlhttprequest/.jshintrc create mode 100644 d2d_app/node_modules/xmlhttprequest/.npmignore create mode 100644 d2d_app/node_modules/xmlhttprequest/LICENSE create mode 100644 d2d_app/node_modules/xmlhttprequest/README.md create mode 100644 d2d_app/node_modules/xmlhttprequest/lib/XMLHttpRequest.js create mode 100644 d2d_app/node_modules/xmlhttprequest/package.json create mode 100644 d2d_app/package-lock.json mode change 100644 => 100755 d2d_app/service/app_proxy.js mode change 100644 => 100755 d2d_app/service/app_router.js create mode 100644 d2d_app/service/jsencrypt.js create mode 100644 d2d_app/service/private.key create mode 100644 d2d_app/service/public.key diff --git a/d2d_app/about.html b/d2d_app/about.html new file mode 100644 index 0000000..4360646 --- /dev/null +++ b/d2d_app/about.html @@ -0,0 +1,15 @@ + + + + + + + + + +
+

Global Device Web Server v.0.1

+
+ + + diff --git a/d2d_app/client/client.html b/d2d_app/client/client.html index 1cad15a..59c8298 100755 --- a/d2d_app/client/client.html +++ b/d2d_app/client/client.html @@ -1,27 +1,106 @@ - + - - - - Client + + + My Device App + + + + + + + + + -
-
-
-
- App List -
-
-
-
-
-
-
-
-
-
-
+
+
+
+ My Device App +
+
+ +
+
+ + + +
+
+
+ +
+ Instant Control + +
+
+
+
+ +
+ D2D on My Device +
+
+
+
+
+
+
+
My Device App
+
+ +
+
+
+ Customize widgets +
+
+ +
+ +
+
+
diff --git a/d2d_app/client/control.html b/d2d_app/client/control.html new file mode 100644 index 0000000..9fa5c96 --- /dev/null +++ b/d2d_app/client/control.html @@ -0,0 +1,196 @@ + + + + + + Home Tv App + + + + + +
+ +
+
+ Instant Control +
+
+ +
+
+ +
+ +
+
+
+
+
+
Remote Control
+
+
+
+ +
+ + + +
+
+
+
+ + VOL + +
+
+ + CH + +
+
+
+ + +
+ + +
+
+
+
+
+
+
+
+
Remote Control
+
+
+
+ +
+ + + +
+
+
+
+ + VOL + +
+
+ + CH + +
+
+
+ + + + + + + + + + + + +
+
+
+
+
+
+
+
+
Typing Control
+
+
+
+ +
+ + +
+
+
+
+
+
+
+
Media Control
+
+
+
+
+ +
+
+ -10s + + + + +10s +
+
+
+
+
+
+
+
Game
+
+
+
+
+
+ + + + +
+
+ + + + +
+
+
+
+
+
+
+
+ +
+ + diff --git a/d2d_app/client/css/app-remote-control-basic.css b/d2d_app/client/css/app-remote-control-basic.css new file mode 100644 index 0000000..f7d49c8 --- /dev/null +++ b/d2d_app/client/css/app-remote-control-basic.css @@ -0,0 +1,478 @@ +.app-remote-control { + display: flex; + align-items: center; + justify-content: center; + text-align: center; + padding: 5px 0; + flex-direction: column; +} + +@media (max-height:641px) { + .app-home-buttons { + display: flex; + justify-content: space-between; + height: 28px; + padding: 0 20px; + } +} +@media (min-height:642px) { + .app-home-buttons { + display: flex; + justify-content: space-between; + height: 38px; + padding: 0 20px; + } +} + +.ui-icon-home::after { + mask-image: url(../images/control/ic_home.png); + -webkit-mask-image: url(../images/control/ic_home.png); + mask-size: 24px !important; + -webkit-mask-size: 24px !important; +} +.ui-icon-enter::after { + mask-size: 26px 18px; + mask-image: url(../images/control/ic_source.png); + -webkit-mask-size: 26px 18px !important; + -webkit-mask-image: url(../images/control/ic_source.png); +} +.ui-icon-backward::after { + mask-size: 25px 23px !important; + -webkit-mask-size: 25px 23px !important; + mask-image: url(../images/ic_back.png); + -webkit-mask-image: url(../images/ic_back.png); +} + +.app-volume-channel { + flex-direction: row; + width: calc(100% - 148px); + display: flex; + justify-content: space-between; +} +@media (max-height:641px) { + .app-volume-control { + display: flex; + flex-direction: column; + font-size: 16px; + background-image: linear-gradient(180deg, + transparent, transparent 25px, #ebebeb 25px, + #ebebeb 100px, transparent 100%); + width: 53px; + align-items: center; + height: 125px; + justify-content: space-between; + } +} +@media (min-height:642px) { + .app-volume-control { + display: flex; + flex-direction: column; + font-size: 16px; + background-image: linear-gradient(180deg, + transparent, transparent 25px, #ebebeb 25px, + #ebebeb 125px, transparent 100%); + width: 53px; + align-items: center; + height: 173px; + justify-content: space-between; + } +} +.app-btn-icon-volume-up { + background-image: url(../images/control/btn_plus.png); + background-size: 100%; + background-position-y: 2px; +} +.app-btn-icon-volume-up::after { + display: none; +} +.app-btn-icon-volume-down { + background-image: url(../images/control/btn_minus.png); + background-size: 100%; + background-position-y: 2px; +} +.app-btn-icon-volume-down::after { + display: none; +} +@media (max-height:641px) { + .app-channel-control { + display: flex; + flex-direction: column; + font-size: 16px; + background-image: linear-gradient(180deg, + transparent, transparent 25px, #ebebeb 25px, + #ebebeb 100px, transparent 100%); + width: 53px; + align-items: center; + height: 125px; + justify-content: space-between; + } +} +@media (min-height:642px) { + .app-channel-control { + display: flex; + flex-direction: column; + font-size: 16px; + background-image: linear-gradient(180deg, + transparent, transparent 25px, #ebebeb 25px, + #ebebeb 125px, transparent 100%); + width: 53px; + align-items: center; + height: 173px; + justify-content: space-between; + } +} + +.app-btn-icon-channel-up { + background-image: url(../images/control/btn_up.png); + background-size: 100%; + background-position-y: 2px; +} +.app-btn-icon-channel-up::after { + display: none; +} +.app-btn-icon-channel-down { + background-image: url(../images/control/btn_down.png); + background-size: 100%; + background-position-y: 2px; +} +.app-btn-icon-channel-down::after { + display: none; +} +@media (max-height:641px) { + .app-4way-direction { + display: grid; + grid-template-columns: 25px 1fr 25px; + grid-template-rows: 25px 1fr 25px; + grid-gap: 5px; + width: 100%; + height: 130px; + justify-items: center; + background-color: #ebebeb; + border-radius: 32px; + margin-top: 10px; + } +} +@media (min-height:642px) { + .app-4way-direction { + display: grid; + grid-template-columns: 25px 1fr 25px; + grid-template-rows: 25px 1fr 25px; + grid-gap: 5px; + width: 100%; + height: 210px; + justify-items: center; + background-color: #ebebeb; + border-radius: 32px; + margin-top: 10px; + } +} +.app-remote-control .app-4way-direction .ui-btn.ui-btn-flat.ui-btn-icon { + max-width: 100%; + width: 100%; + height: 100%; + min-width: 32px; +} + +.app-remote-control-icon { + background-color: var(--primary-color); + border-radius: 6px; + position: relative; +} + +.app-remote-control-icon::after{ + content: ""; + width: 100%; + height: 100%; + position: absolute; + background-color: var(--color-white); + mask-size: 100%; + mask-image: url(../images/control/tw_list_icon_connections.svg); + -webkit-mask-size: 100%; + -webkit-mask-image: url(../images/control/tw_list_icon_connections.svg); +} + +.app-4way-btn-up { + grid-column: 2 / 2; + grid-row: 1; + align-self: center; +} + +.app-4way-btn-left { + grid-column: 1 / 1; + grid-row: 2; + align-self: center; +} + +.app-4way-btn-right { + grid-column: 3 / 3; + grid-row: 2; + align-self: center; +} + +.app-4way-btn-down { + grid-column: 2 / 2; + grid-row: 3; + align-self: center; +} + +.app-4way-touchpad { + grid-column: 2 / 2; + grid-row: 2 / 2; + width: 100%; + border-radius: 28px; + background-color: #f4f4f4; +} + +.app-remote-num-pad { + display: grid; + grid-gap: 5px; + width: 100%; + justify-items: center; + border-radius: 28px; + margin-top: 10px; + overflow: hidden; + grid-template-columns: 1fr 1fr 1fr; +} +.app-remote-num-pad .ui-btn { + display: flex; + align-items: center; + justify-content: center; + color: var(--text-color); + width: 100% !important; + height: 100%; + background-color: #ebebeb; + border-radius: 0; +} +.app-num-pad-1 { + grid-column: 1 / 1; + grid-row: 1; +} +.app-num-pad-2 { + grid-column: 2 / 2; + grid-row: 1; +} +.app-num-pad-3 { + grid-column: 3 / 3; + grid-row: 1; +} +.app-num-pad-4 { + grid-column: 1 / 1; + grid-row: 2; +} +.app-num-pad-5 { + grid-column: 2 / 2; + grid-row: 2; +} +.app-num-pad-6 { + grid-column: 3 / 3; + grid-row: 2; +} + +.app-remote-control .ui-btn.ui-btn-flat.ui-btn-icon { + width: 58px; + height: 58px; + min-width: 58px; +} +.ui-btn.ui-icon-right::after { + -webkit-transform: translate(-50%, -50%) rotateZ(-90deg); + -ms-transform: translate(-50%, -50%) rotate(-90deg); + transform: translate(-50%, -50%) rotateZ(-90deg); +} +.ui-btn.ui-icon-left::after { + -webkit-transform: translate(-50%, -50%) rotateZ(90deg); + -ms-transform: translate(-50%, -50%) rotate(90deg); + transform: translate(-50%, -50%) rotateZ(90deg); +} +.ui-btn.ui-btn-flat.ui-btn-icon::before { + width: 48px; + height: 48px; +} + +.app-border { + box-shadow: 0 0 0 0.25px var(--content-area-line-color) inset; +} + +/* Typing control */ +.app-typing-control-icon { + background-image: url(../images/control/squarcle_bg.png); + background-size: 100%; +} +.app-voice-button { + background-image: url(../images/control/default.png); + background-size: 100%; + width: 43px !important; + height: 43px !important; + display: inline-block; + max-width: 43px; + max-height: 43px; + background-repeat: no-repeat; + background-position: center; +} +.app-input-with-button { + display: flex; +} + +/* media control */ +.app-media-buttons { + display: flex; + align-items: center; + justify-content: space-between; + height: 51px; + color: var(--color-black); +} +.app-media-buttons .ui-icon-prev::after { + mask-image: url(../images/control/ic_function_media_prev.svg); + -webkit-mask-image: url(../images/control/ic_function_media_prev.svg); +} +.app-media-buttons .ui-icon-next::after { + mask-image: url(../images/control/ic_function_media_next.svg); + -webkit-mask-image: url(../images/control/ic_function_media_next.svg); + transform: translate(-50%, -50%); +} +.app-media-buttons .ui-icon-pause::after { + mask-image: url(../images/control/ic_function_media_stop.svg); + -webkit-mask-image: url(../images/control/ic_function_media_stop.svg); +} +.app-media-buttons .ui-icon-play::after { + mask-image: url(../images/control/ic_control1_right.png); + -webkit-mask-image: url(../images/control/ic_control1_right.png); + mask-size: 20px !important; + -webkit-mask-size: 20px !important; +} +.app-media-buttons .ui-btn:not(.ui-btn-icon) { + width: 50px !important; + line-height: 32px; + color: var(--color-black); + font-size: 17px; +} +.app-media-progress .ui-slider-handler::after { + content: attr(data-value); + position: absolute; + left: -20%; + bottom: -18px; + font-size: 12px; + color: #999999; +} +.app-media-control-icon { + background-image: url(../images/control/squarcle_bg.png); + background-size: 100%; +} + +/** game pad **/ +.app-game-4way-direction { + background-image: url("../images/control/control1_bg .png"); + width: 157px; + height: 157px; + background-position: center; + background-size: 100%; + display: inline-grid; + grid-template-columns: 48px 1fr 48px; + grid-template-rows: 48px 1fr 48px; +} +.app-game-4way-direction .ui-icon-up { + grid-column: 2; + grid-row: 1; +} +.app-game-4way-direction .ui-icon-left { + grid-column: 1 / 1; + grid-row: 2; +} +.app-game-4way-direction .ui-icon-right { + grid-column: 3 / 3; + grid-row: 2; +} +.app-game-4way-direction .ui-icon-down { + grid-column: 2; + grid-row: 3; +} +.app-game-4way-direction .ui-btn { + justify-self: center; +} +.app-game-4way-direction .ui-btn::after { + justify-self: center; + mask-size: 12px !important; + -webkit-mask-size: 12px !important; + transform: translate(-50%, -50%); +} + +.app-game-4way-direction .ui-icon-up::after { + mask-image: url(../images/control/ic_control1_top.png); + -webkit-mask-image: url(../images/control/ic_control1_top.png); +} +.app-game-4way-direction .ui-icon-down::after { + mask-image: url(../images/control/ic_control1_bottom.png); + -webkit-mask-image: url(../images/control/ic_control1_bottom.png); +} +.app-game-4way-direction .ui-icon-left::after { + mask-image: url(../images/control/ic_control1_left.png); + -webkit-mask-image: url(../images/control/ic_control1_left.png); +} +.app-game-4way-direction .ui-icon-right::after { + mask-image: url(../images/control/ic_control1_right.png); + -webkit-mask-image: url(../images/control/ic_control1_right.png); +} +.app-game-4buttons { + width: 157px; + height: 157px; + background-position: center; + background-size: 100%; + display: inline-grid; + grid-template-columns: 58px 35px 58px; + grid-template-rows: 58px 35px 58px; +} +.app-game-4buttons .ui-btn.ui-btn-icon { + background-image: url(../images/control/control2_bg\ .png); + background-size: 100%; + background-position-y: 2px; + min-width: 58px; + min-height: 58px; +} +.app-game-4buttons-Y { + grid-column: 2; + grid-row: 1; + justify-self: center; +} +.app-game-4buttons-X { + grid-column: 1; + grid-row: 2; + align-self: center; +} +.app-game-4buttons-B { + grid-column: 3; + grid-row: 2; + align-self: center; +} +.app-game-4buttons-A { + grid-column: 2; + grid-row: 3; + justify-self: center; +} + +.app-game-4buttons .ui-btn.ui-btn-icon::after { + mask-image: none; + -webkit-mask-image: none; + background-color: transparent; + font-size: 16px; + text-align: center; + height: auto; +} +.app-game-4buttons-Y::after { + content: "Y"; + color: #ffb100; +} +.app-game-4buttons-X::after { + content: "X"; + color: #18a3ff; +} +.app-game-4buttons-B::after { + content: "B"; + color: #ed3c36; +} +.app-game-4buttons-A::after { + content: "A"; + color: #67ce2b; +} +.app-game-control-icon { + background-image: url(../images/control/squarcle_bg.png); + background-size: 100%; +} \ No newline at end of file diff --git a/d2d_app/client/css/pincode.css b/d2d_app/client/css/pincode.css new file mode 100644 index 0000000..7b5dbf8 --- /dev/null +++ b/d2d_app/client/css/pincode.css @@ -0,0 +1,302 @@ +body { + height: 100%; + background: white; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + font-family: Open Sans; +} + +body.wrong { + -webkit-animation: bg-red 1s ease-in; + animation: bg-red 1s ease-in; +} + +body.correct { + -webkit-animation: bg-green 1s ease-in; + animation: bg-green 1s ease-in; +} + +#pin { + background: #212121; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + padding: 1em; + border-radius: .3em; + box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3); + margin-top: 12px; + color: rgba(255, 255, 255, 1.0); +} + +.dots { + width: 50%; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-justify-content: space-around; + -ms-flex-pack: distribute; + justify-content: space-around; + padding: 1em; + padding-top: 3em; +} + +.dot { + position: relative; + background: rgba(255, 255, 255, 0.2); + border-radius: 0.8em; + width: 0.8em; + height: 0.8em; + -webkit-transform: scale3d(0.7, 0.7, 0.7); + transform: scale3d(0.7, 0.7, 0.7); +} + +.dot.active { + -webkit-animation: growDot .5s ease; + animation: growDot .5s ease; + -webkit-animation-fill-mode: forwards; + animation-fill-mode: forwards; +} + +.dot.wrong { + -webkit-animation: wrong .9s ease; + animation: wrong .9s ease; +} + +.dot.correct { + -webkit-animation: correct .9s ease; + animation: correct .9s ease; +} + +#pin p { font-size: 1.0em; } + +.numbers { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-flow: row wrap; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-justify-content: space-around; + -ms-flex-pack: distribute; + justify-content: space-around; + -webkit-align-content: flex-end; + -ms-flex-line-pack: end; + align-content: flex-end; + margin: 2em 0; +} + +.number { + position: relative; + width: 2.5em; + height: 2.5em; + margin: 0.3em; + border-radius: 2.5em; + border: 2px solid rgba(255, 255, 255, 0); + text-align: center; + line-height: 2.5em; + font-weight: 400; + font-size: 1.8em; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-transition: all .5s ease; + transition: all .5s ease; +} + +.number:hover { color: rgba(255, 255, 255, 0.5); } + +.number:hover:before { border: 2px solid rgba(255, 255, 255, 0.5); } + +.number:before { + content: ""; + position: absolute; + left: -2px; + width: 2.5em; + height: 2.5em; + border: 2px solid rgba(255, 255, 255, 0.1); + border-radius: 2.5em; + -webkit-transition: all .5s ease; + transition: all .5s ease; +} + +.number.grow:before { + -webkit-animation: grow .4s ease; + animation: grow .4s ease; +} + +@-webkit-keyframes +growDot { + 100% { + background: white; + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } +} + +@keyframes +growDot { + 100% { + background: white; + -webkit-transform: scale3d(0.9, 0.9, 0.9); + transform: scale3d(0.9, 0.9, 0.9); + } +} + +@-webkit-keyframes +grow { + 50% { + -webkit-transform: scale3d(1.5, 1.5, 1.5); + transform: scale3d(1.5, 1.5, 1.5); + } + 100% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@keyframes +grow { + 50% { + -webkit-transform: scale3d(1.5, 1.5, 1.5); + transform: scale3d(1.5, 1.5, 1.5); + } + 100% { + -webkit-transform: scale3d(1, 1, 1); + transform: scale3d(1, 1, 1); + } +} + +@-webkit-keyframes +wrong { + 20% { + background: crimson; + } + 40% { + -webkit-transform: translate(-15px, 0); + transform: translate(-15px, 0); + } + 60% { + -webkit-transform: translate(10px, 0); + transform: translate(10px, 0); + } + 80% { + -webkit-transform: translate(-5px, 0); + transform: translate(-5px, 0); + } +} + +@keyframes +wrong { + 20% { + background: crimson; + } + 40% { + -webkit-transform: translate(-15px, 0); + transform: translate(-15px, 0); + } + 60% { + -webkit-transform: translate(10px, 0); + transform: translate(10px, 0); + } + 80% { + -webkit-transform: translate(-5px, 0); + transform: translate(-5px, 0); + } +} + +@-webkit-keyframes +correct { + 20% { + background: #1c72ad; + } + 40% { + -webkit-transform: translate(0, -15px); + transform: translate(0, -15px); + } + 60% { + -webkit-transform: translate(0, 10px); + transform: translate(0, 10px); + } + 80% { + -webkit-transform: translate(0, -5px); + transform: translate(0, -5px); + } +} + +@keyframes +correct { + 20% { + background: #1c72ad; + } + 40% { + -webkit-transform: translate(0, -15px); + transform: translate(0, -15px); + } + 60% { + -webkit-transform: translate(0, 10px); + transform: translate(0, 10px); + } + 80% { + -webkit-transform: translate(0, -5px); + transform: translate(0, -5px); + } +} + +@-webkit-keyframes +bg-red { + 50% { + background: crimson; + } +} + +@keyframes +bg-red { + 50% { + background: crimson; + } +} + +@-webkit-keyframes +bg-green { + 50% { + background: #1c72ad; + } +} + +@keyframes +bg-green { + 50% { + background: #1c72ad; + } +} diff --git a/d2d_app/client/css/style.css b/d2d_app/client/css/style.css index 583efde..c9c1750 100755 --- a/d2d_app/client/css/style.css +++ b/d2d_app/client/css/style.css @@ -1,116 +1,65 @@ -html, body { - width: 100%; - height: 100%; - margin: 0 auto; - padding: 0; +.app-image-grid { + margin: auto; + display: grid; + grid-template-columns: repeat(3, 100px [col-start]); + grid-template-rows: auto; + gap: 10px; + justify-items: center; + justify-content: center; + padding: 20px; } -#container { - width: 100%; - height: 100%; - display: table; +.app-image-big-grid { + margin: auto; + display: grid; + grid-template-columns: repeat(1, 100px [col-start]); + grid-template-rows: auto; + gap: 10px; + justify-items: center; + justify-content: center; + padding: 20px; } -.page { - width: 100%; - height: 100%; - padding-top: 50px; - display: block; +.app-icon-img { + width: 100px; + height: 100px; } -.header { - position: relative; - width: 100%; - height: 50px; - margin-top: -50px; - background-color: rgba(0, 80, 179, 1); - z-index: 999; - display: table; +.app-icon-big-img { + width: 150px; + height: 150px; } -.text-header { - color: #ffffff; - font-size: 1.5em; - vertical-align: middle; - text-align: center; - display: table-cell; +.app-btn-icon-burger { + margin-left: 20px; + margin-right: 12px; } -.contents { - width: 100%; - height: 100%; -} - -.contents-name-detail { - font-size: 1.5em; - padding: 10px; -} - -.icon-folder { - vertical-align: middle; -} - -.detail { - width: 100%; - height: 100%; +.app-btn-icon-burger::after { + -webkit-mask-image: url(../images/Hamburger_icon.svg); + mask-image: url(../images/Hamburger_icon.svg); } -.result-table { - display: table; - text-align: center; - width: 100%; - height: 100%; - vertical-align: middle; -} - -.result-table-row { - display: table; +.app-dummy-payment input { + display: block; + font-size: 18px; + padding: 8px; + margin: 4px 0; + border-radius: 8px; + border: 1px solid #ddd; + box-sizing: border-box; width: 100%; - height: 60px; - vertical-align: middle; - border-bottom: 1px solid black; -} - -.result-table-error { - display: table-cell; - font-size: 1.8em; - vertical-align: middle; - text-align: center; } - -.d2dApp-detail { - display: table-cell; - font-size: 1.2em; - vertical-align: middle; - text-align: left; - padding-left: 10px; - width: 100%; +.app-dummy-payment input.ui-inline { + width: auto; + display: inline; } -.text-error { - text-align: center; - color: rgba(0, 0, 0, 1); - font-size: 1.5em; +body { + /*disable-pull-to-refresh-effect*/ + overscroll-behavior: contain; } -.spinner { - position:absolute; - top:50%; - left:50%; - transform:translate(-50%, -50%); +.app-display-none { display: none; } - -.spinner-img { - border: 16px solid #f3f3f3; - border-top: 16px solid #3498db; - border-radius: 50%; - width: 120px; - height: 120px; - animation: spin 2s linear infinite; -} - -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} diff --git a/d2d_app/client/images/Hamburger_icon.svg b/d2d_app/client/images/Hamburger_icon.svg new file mode 100644 index 0000000..233bf21 --- /dev/null +++ b/d2d_app/client/images/Hamburger_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/d2d_app/client/images/control/btn_down.png b/d2d_app/client/images/control/btn_down.png new file mode 100644 index 0000000000000000000000000000000000000000..d00eaefd9e3337125449bcf7411fb5765c7e172b GIT binary patch literal 9767 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 literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/btn_minus.png b/d2d_app/client/images/control/btn_minus.png new file mode 100644 index 0000000000000000000000000000000000000000..69e5b88eaa1c9cd55eedf82637754361eb638524 GIT binary patch literal 9477 zcmYj%bzGEB)GsWZQVL3UH-dCY3X+o2u^=T&E-bMs2-4jpB7$^EEhVsYxAZQZOQ(1J zz4!Cp`^W4&JI|T(%*;7+;yV+m`&x~J@EIWn1_p_S`b&Lu-TSZL4ZTW!zecPLl z_5Ys#5jyAu+G1d^d1$;;H1x+jupp|kcmsxQEoVt+Fk@0gvMEq7=~MA>RTBb8nazr% zy6}Y~-1_Tymf(Lb#R_G9q{MJ} z@z?jF@ifn8W+5npg)O0rS>UMK9Pu?z0_Tt5_#>PuB$?uxK zHh5D8u96Qicj;IzT*vxWS65ZxN|g5<9Uadk8CHIIZhR?vl~y5j`NzvILN>XTxy_s4 z0y;d4>P21q)eF>BTeNZM9G_Q+BCHDA51aQ?b0Mhy5aEEc?fIafAiP)Wj31P3U#Q0h z>+qEux}|mICVvIf^~KUl8@bNcAji!;+RiVFb9@(!Mqd^nNOxqF*-8WMl{eCZBghn3 z`WV{Q_ZWh{POAM~?}<`_T`ahGHMlKau!E5gj2dulP;$AOl4}HcHH)Ju-WS74oYodg zc(wm@tGfD%&1CrAy6r6T)XOKu*bNROCu=u zW7{qk_G}_of~Nf(_{NJ*`DJHDXB(5HBnUL0+S4ocRP>$yOt6BS^kA_;H!m+QL*8!Y znW_;ltu}*hFAn6BK3Fv$!EWXFF28OtiRg>~O>>&LfTb`^i=YU-CT5l@D_O1H;il3Eq3v2% z7%L+D{9_{1tj2oVayViymDvgpw*!#w6#ePahUR12GVg|TsKU_qUs)NCKmMK-j5AQ{ z=S6a|yD;vh4jou$$6?Z1W0xVu=9+%>?yKPGcYTkT$8Q4%7~Fa^?|iSW*~v>~3oQK@ zIa6*Ri&GYAstEnPAL-zpMHYc6Z$j37f8fCh-xwTy75-3SUh9p&@jzLH6>h}jHgJgh znV*Nyf@~F>x}7Gm+6(_4te3cpWY#KM6FGm?L6I(nv%YRsXGQW|ajV$|)4^Tkq{(-H zAO(2A8A~g1Xk`!e=Ugz`BlCw$e%IdW50q{!Qbq~$a|1yRyBbmZXL~PHiqh(Z`;||e zrTqs|p1aJnYAg?#@u+zI+%D%*!WXZQ$DRY&S(jHE%cySUhF;dQv{dS-c{}hC=OE&GN@!#T0(7`ZtbtzA}s=Qd%t^W7B6P{ z3_jb$ul{v85T%oh{F9Bo5aUgMm)|m*69L!^3spAVKn|_+Dn9zmG>vb%F3Z%42}`rZ z{LLac!s*)uVeh1`zqCGmlVDsH^^NN=Io61Z`D~#wg!cj?5GtFnQzNTyU{GxM#x~)MYYPhB98M z9PIZ&CTnl;Nk-&MY9}k+aFimtw^-2nnL&mf2qCjMV~TAV&uN^;`K~C{$3T$TUL!k6ljpWz9#E}!&DUdQW6~x2eew&!Kn`Yyz#mPGu8#m9XP?<59l0j!&7q9ZV$oyQ)d^jU zGopF(3gCJ@WHlS}baP4^MPSk5dr*+Xsq;`2EzJ*f6-}Xr0FJ4Z-9wOlo51DXyPr*Qu z)BpO*kLQm}8)dRCTr!Ukvbaf0)O8IBI$xCBS6?T7y|UV|S6Nf8Xz@;}N}Dqvke*)= zgB(h}94_9BM$C&88wus`M7QEN(}Kqa_A1+hZ|17)LYVJ<8S%~Za^V0rs*2~#BRS@` z#CQ&6|F@H4#%n6oWu>|p87Gy8qh2ko!O42)!%Ck0@*E3@nY$+&Nhuu^3C`I}am#2j9g z6IRo(8HqZsy(u4j!>UU-Ch)J1fRm-5(6?DRpVI@bXx)4>9frCZw52LU3NP1pEynmR znZIzAidGEBf%XU+zhw}~x+tjNUfAu5Ac&XCPnrH{%qZo#{`)W0GDE+3eM6sokLTgiPjKkKHDZ%4B zg{CQ-2w!7Heo>o3X@5FpJ11Fx2HCyY%8)!r(hGqCGjK2JlVhoXnzaHf;l2_9+c4gd z`U8MU8DcXBQL*Ky50x>Ijdwqimr?n$&e`Q_d&osLR8oh3#$p^V%F|T}(Z5Np8Rp>p zaQ1vxW6dB#!o%{&<}sw&J zI!&n}5AIG!kFvy^CyH3ar1CsSCl4&~&ooIb!r$r-Rt$(1&ARGUyjzL(_>pvWabEb^ z;P~qIeiP_f>x-;u8s&UNYy=3B0I47pthp(Jj{7?@O^aT6FIaXJpX z0M&u@XrEK%|!yC)21poF`E2z@Me*|Lb4!2N_ZSJ;#+JM9yZ4A*;`g0w|h?rK&GA=R0 z-bMf>f(k?=naV(yDygn1`$MPr;7uzmp+p25du4SB>e%-$h8W3_zEr&iiQR@;V`v#j z#D@L>((yN)Z%7}tQUYUAB{+PBI^?W&#c)=5R{$qqf`>g}tgJZZF?;|@cT4HIvfV?& z%2NLX)L#_fzfe~ZUU{is>WERKpvcxYQS_=$Q!l&Hwf7l-UrhnDUkiW!^u=JCk@g2n zyUfuzDcms6j!XCD)@zv(1pEK6B?f>TKv0Oz<6vL{kc9YiEnt-R+gR$yRrjkH{?b!JN=N`0l*~C*s5U!9#t}w!U zDKm-fHN9b8WZTD6L;>;LRrpDIU9*g%-(+0+fSwPUV};>JDr0GrD#s*{2o=%k7k<2x z=uazYm(Lo-`V>0^?F}Y*({!Um!i2*W@W>Sonek)|W)P))#j0u6IO-*o#XRPY zJwaE->!B=+d>p>`nbIhS`*#Vbn?yn@{*g~m$ANVX^Oy#9{71M-MlFZh1ZBY4ANb>4I(6;eyiV;E9|YeUBn*H zbRwzD8zX@oPKepxbG`Ft$TVCjBRN1YhM#!pDc0#Wc)Q>;X?z@J`zvW04}9Xs0JsXm zUP}H{tdz!k2-by9vc8+70UXW@s||CR^g@$(Q$W8AXh;ZJWOz<*yHKs~>~ei7$$+rc2+1xU1-4C(TR8 zV1Ou^xKB|kZHHvGMBO<|37k5)5Xh3K8J==J7QVVWOd_W@t3`$RS6G4szN?Ioy9%s& z?bla=A$NRY96(~$Q3^O?bjW-FU*q(7jXBNx2K9c5_y`*6EL|2#_aDL^?i^v-_18XdH?=zQ;usfUrPiH*Hk zdha566y5ougNcuDmj~q&c@)-}$*gOHmfSGNXx*Mc)P8{rXh^L(#(lcn&lc<(vX*aa zyF;ccX=dzh$J{Jr`y^GX>it?*0*Z7aJDqgX?!V>LL%fp;arI<7TrfQqQrg6Ps)F5g ziPj-$$K9!tMrG$=GA>a-;?KUpw&OMm)+1qsasRlrwo&{XVTekN*Nbc3yl*{6Lgu2_ znsK3!3Eu`vdw2Iq2}7E?7O|&>!H;*yX3@%{tBTEL{OI)th=@hv?Gsfk&KpCtgBIrX zGZcLWU{_QCJq}Aiy1z7u6eQ~28tt^6gv9-sGO@WL6SdeOJ4Td_I1C&29P$z$5W_Sd z#y-nUaWYOwRlTF4B!(ukguYc7(e!@<-cR^xqyW^X>HoNkrSi#2T?!Gw8tab{J3|b0 zSFpZDA=NYk-`e(2a>?a@@-%mf4L-s|!#&FRQW?NnE@^slpR|n4u(Pv=L6U;2b6u-6 zkFWF0mXQX)DKf6-0Ot|a$Jo>qJjAjQn}G;}C=W*<+E_?1t@fMdOlFRzQt}YL$p3hl ze2fzO7--)XBaGdQftgb4F6Ywpj-89xZ3>cN$749fCfBk<44q((-*mNc|JlI{1`;EU z-^gs#cls;m6OoNcnj13pgKUXd&0A!s8(x(Vlh`$5LRCTH--S$U2;A%w-7!XO>0tOj zvdagMt&eYm!#GCU)wC1$W`}!cm$!FJVGUWvVh zWF@`qV}pBDr;NrnpX#NDNX^meNplHHQ&ml`C%~v}?Q;vw6K_hhG*|+`b^0P0CpFr(AHm9V_+E5e;W}61m^T z{K!HRN7M>-u_90;R@a-x0R51Cz8UaC2=&DL(wW;ss1|K^74i?W%Ugs9ODnNl>bQxa zH)Kw1Kw9o-?ej2)F=t8mn zH^JbeoQ1DlKc3o;e^t@Zm^}c0%tUVva=_wbwvTdYzuQ5mgv1#w9ijwJ7`QD-ujn`k3TCyFAW9Dm{UdXlkkeFPC>{T(IC#pVfNphN+Q@|fUL>4d+Q@hSx<1UJ7o zqfNmo*+4jpaiies~>9r@aVM(NBdKqMBLJEWPwtxj~b+LAQkh~76i0O#0%Q)8U% zT8T3`Rgtls;=I_~=-DZ3w8wK$TCEpTBc}w-m}3-#dX9#wmV&p>^nBtl7t!IRXZhRi zVP#I2aD@!A_`p?j)tG1J!jS|xdfsu+F`qTWvR#L%gfF)Cm3Ef+JTh4oel@|A4-y?T z-gMK7hXoQp!MNE|k*_%qDw)zzdOJiMSZ-6lo`ExS>HBJby6Gb)VwS0wIpRcl)Xq~Fng3xL_*@8Ymr zDxT#pZsLi z9xOZZ3{AvrNbpu-mB523AVcTwYoY9aa@YUEb}h5561>r*&MCtzUo z5I0ch^~C8PuhElmyd+amY^m7LflfX_cKl6YpJej9&7bQ?Q|LhaTmRm4aW}IS107kP zN{B`mA1PYW+f)G5at|dQga4{D@+Zg_o~?fMRTNjri-fy%@UK?zf<`d+VkYxgFm}8PTrz_I{KJbp z$pF{N*vq3~T=H9CuEaVQ&#=K^3gN@qH;p8ir7_#4E52B0N3+kKz@NaQwsuYn&k(56 zn8Z@DqA6P@wa<)`4i!vPHAQ*GZMMU3hoJO|NU-&orv!2CE%pw-4hs`O1Jdqw95F%` zOn3#{=y8;fpYkc-=^N{q8XV7?D)|pYzUH~ErR02l$AkB;2U;z!`eqRW*g8rHb2nNA zqYPETCl&+oKZ@z@%S^yu&h(Kn0pQGtMEH<=jtgSvwWig8UfmC& zFSrgu-_nzVe$YZzp?D4d0K+^=+R_EI{P6);|2lY&fOzSDaBS)4wSwpR_BL7!LG(d# zQ_!2(eG#5|&Kem%m~~~_MRP|^hrMz>KIU~!6gvtwM{%O8)RLy1?9&Z*wfNHFD z=Zm4ib@N)s;SMyQdVPs9dWeE4qNVc-p9!7!!s)9YZ>H~7dg+vGm{?Nu_}@ZGqF~vH zkpak<_69Jue@l08iyAX7(M{VyK5wUNcF=vjSASU)NKJTLPv*Ui$tn(nTGuQSwjC-|2m&Bmp^{EY!3-5BU9;Ie_zsoN&JKith;0#=dQKB zO}f6lSLm}EghvEGqhoDoxOh2uN>6QVk+`ql#_dwYdh-5qlK$zq*8R!GhjLL*@{6HjbR_(Y>%mLH7~y^*1)O)wH8->-P& zlew!x3P`86^k3tR!L|=-rpDX{n^ATCQ9tEQHULNY-6F0X#bKquFH-5cR=dw}ju>Rj zf7P*!R<{4z$_-ps{yY;d38;kK>^36r`C!ISw#_K^k{ReM-WW7mwb@|dT;kgba&7II ztey3bu}@Pjgs^RRD26VI2c$Pbm%d`=$0`&dOG*_slENow-((gyt*pwr#C>o>J8^`< ze?Lrx8&0gPCCeSe-16DdzgGthJL3I1r26Z&?doR2TtyNXC7b$2n6ajfI%m_FlbtMn zT-{HztGnL45kU>8TUF;JkNE> zl`|>ZWG+favY(TJm^@cr#@?P|bt4OnQcqY-#$nHd<%8$` zV4b2F7I>NG4xbOFWPEFS?ek38?wu@nY)tPB*}5^i{MG8mzW#RUU@JMuFOQs)j6giH zj*w;9yW{S>M9Mo0k(}4wjrea(Z$-v6$eT9LHI)JmD2E$29!pT=&m`fI&1d8D~37*>5gYzP>se<9Z&-0QU>21GU8;2j#3^m2_(Ma zZ8cbqRr0_S@AlDpD-~p(D`nB@d$3SSEn-@A3rGjz$(?Z;#Ru_!yS!H2TgXr^2>l;E zIH8JU)tIO^$1BNwp^SBcK2gh;snUSJeawrm`COn&QIcrMju#oM$r{Q53$))M_3r+m z5wQi5b-6$cVl}zAfKe8d=5)xSTjPC>Ok18qX8;u*PeTA+dG=zxK5XaHAx+&5SF3t*Cnm8LqmQtH`zh{2M0Q(g1jXZgD| zy6aS*yN#rJaTbhd=yM^w3z0X|!QX0TdJY8(XC##@)P4j{yKj90pE}Wkb%U71;me|7 z8(HT`oW^|vruG_ERx8BB*5%Lf(eBYMg{lh&%vha*fwo9ffMAESKnMfYX zum4J;5$wa3e9(%OMb5nfc_XJVf6 zmw+={2$ktlA*oyuB|o{iC|y1ob@crjajHE!K>7Vhz@%!`%A@`MqMSn7viuy1bdpR3 z%4=IN)VR~M*u`kfRufD{e%UNqQmZG0>_baLt(q>;d*x8l2aQW?4amZW!~|GBgl01v z4fyp~@>tn;wf%YZixG*TT8*P1zx25^PHD@9o}UoAgY6V&(%oYG&%$elDP)Nk_qv}? zvgjhBKZzIh?h1xQ`eIe=+M=<^w!=BZ&($2kJsBc@e>OSWZ+dQwTJh0($5E8}{83rm z{zm;Hu&&tERy|9gODXu}mn|HJMKkm&-0H-luy`c_y7s z`H6y*rzPEj>atqF2Gpj%Wvbpe12Q^oY$Y4C+zKup_{)~ZlV*n3CGDF``wU?2wN|qL2TKzDJ5+`Cp0fDGrCvGKk$CLRt~3X$^T5Ox+i_o1=7+e1sJqb5 z48>{`+f}TwFVS=9D<^-QJr6on4Q=&ebjTDXX=`jn*>T zHlhO-r~M;joD2&75GBy;)SPYVIKcTD2xp%&utQ_Q2 z-HN;L(NgBz9j0&Q>Jp{y*;?S<(sPSiBd5RHer0NqcG*8xu;c0bZv7#g0zU1MA;awm z&@r710LLN=#|k`$a`X>YSOVSRNS&W8eIpG^(>99yyR35-Map1e{%dgx4+oUQS!ULPv%_$y-m7@50C3ew5ch7UYwjvUH{PetWeHglok2+>%y*0ZynVMGKiF(nW^e$&m`QrJ~EKo4zwTEK~fES;G!+ln5P%gLG z>Bcr$kg%mOr?rq31Y4`}P{4d*|LBZ?$uNh?^?63dgYf@5%)F zwR5h`jkmD)P3R_j*64R1=4FYB3*;U8W0}1-J90&vr{Wb;P&HiR(HjV?VkCt;{HK>g zo{s&MqJ$Movy^eKHM%iKu9Hb-19|P6GTazxQ6CDo-m?J0SBm4NcXWe->Xwi}1n5=2 zFrn`~x!ygofLVq#hU_2%Bz~L`eZj9Zy zt5Po{SC}eLLdBaez6PuKTEX4(R1>Ry=p-yrQ+vl;5XHXa>tA z6!*@zWb%j4rZ>F#SGGBP4nDAAdEf|?)39>7^zY)rBCvo;xC>I!-5@DQ2}pON#Ii0ST}y+cq;!K4N(zW{h;(-&xO6YM zy>8$~^)&6RE;A`dq;`u*idtZu+NZ3MOtt@H+;R^?uIEy>wy3^yilI`Q566gM;7eX-uoJ z6}lXSR*g?fTq9=dWa(~iZ>brGKArmc`F%%S{_g%noyuceYlp#mYFeeU$8hxVbewq> zU&KO{dSG*9tZ}s4JQ^4|*X@}1wjlz{@` zPiU9cc4?&wCX^0?@rXWFShV?Ho$oKSaa1nea|bRmDb3BZbbW+8=6sjpp7;99xV>pN zEKAfvnD@!J=V)z5M)kuT+w&@dD4jMCN}# z9Tr5Cc;sk58_c%;Fr%xZr!{)N5@IMg%_HWYi-*&;Ci!3 zJK$?H{CGe0t-deQDEbTA!IKsW1-6j0T~Z~-1S^#Brui`>+xNlp%#XcRX@{}oYCfS} zKjjbmZ+N7C&2Sc95nZeV+%u!|TLk^G)n=N(^gX@8F0qRPy?y2-MvJ%FMG-?kn(iDD z8sdMxNwG>S^Qz58${(lajTI^dXl!`FV!a2yVxV3=zdsV^(h1rQ{yrXUe)Bxc_@wpW ze=Bm2C2z;b=7m#!+edMtZFLpQt2b1&7FlV^*Bcs5d>z+5v+Fp(F1`=61y3|l$w54BTyyPR#uuo}Se;%yNa z6%bmR5WqU?M>HjZPCglV*`}mELxd{rr5W#w>P&5L*l5U?MdwwB>3KM1(PY{KY#w(={x1dr_h zj%xx=iRLmZSdTKKKlBH}UEfn@1(QXAyyZqU8;oSE>PQii z1WQ&d2@h1p?JJyq3v|pJ$%x^<&eT}w4beww?Kz{n{&}qSY-aT=_NNEcpHKv3O1v=1WkGfA#*C%fsbWd@VJb&WL@mA@Y zI($SbyaY3w6)$A6HVG~=3rqM(@4!fEJom$9z=%;Pwpr~`Ysj$dlU5WsrZeZA6LW@L z?!S^>7mtMLGRYEcRkNsU=CvSjqA?M49tDPFE)1O{G(!~Ulw?G03WWr>{GlEAQE(fZ zssxsqMB1yr&fs=_9}36dJ~6c;DaY4<9$NFp(=lAWXC$g=%}&6BVx;LR;Tcm;{bC|T!OMEzTQ%&2&iDL){H!{*KP>Lh;dmCyWcLAkh9Xkhu7 zUbAFkHiLq5cG;`lUE|O0JHNoXRTu4nHTP6R88bxS?K+LOtrTI833Ye-LiDFA%zT?A zyPK4~n#OpV!$OLFKe7ZE0$A37(Tw`0v;vvu`4tTFd!4;x^nNm&oCXz=?-qYK-?KMM zB|6w~;wx-wwLjp)vG2mCR2&Q>t&^0_Zxz0>eX2NwTOBNmFix;&^IgEfe|BWCX63XT zCQ!e*-2)_R|Hwt-HI^nT!WQCWgs^=Z`k=^sqQ7A?XF6OoZQnb^wOulo;3^{VWyneaSZEH0D++3l;VO}sB)wA5nZ$Dc# zV10&s^@mlH$DK^R>H7#bSyh9C*E2aQJ1H+(v)$?P>-d|*7d-hH-reX>+ixTzGPyU; zuPu80dMf|9|H6CVUh?qOl_@(MpD!s`Mn3u}Zw{NnG1=P%e$NV~G#$9$C~+A;kfW1B zlHE^dPO&4B-tUu-_NA`vaMqk3DnV(PzS-|&I8}H8Bfy7~hU3v?7*;%MwCi>sZ+?x7 zQ4|lq(ynCpS~M6;y^iwkup6|5KD3rO5N+kTpuT6ay>N+2ee>nuAw$cq0W(>%UVm0_ zW#zQOA9^c=)4CaR-$Uu^y^vft`%|uDK}lC?Yv`8m?b(dRvgeB5ag$!-3!x+7k@ai0 zT0D3Q{S@9`>MVuFb3Bb(1v$t6dMwyqwVYr!_?B{#gB&|X_1Y7SJt&4ho7Wf_PPGzP z7_e^d?%{XLGHBSHyzc?*2!PYDtiq)+|ly6&pyl`sV(j_DQzmgaO6Pn=V=<`{f< zU_rXEQxN1rSnZSwBGy_IDv&sYAXaWkIwb=2ULY%CGjxt^IfY(YcvW1GURjXj)Att z(<#-EJ_IGgcdi8KFQ7d{KmCy_eiy4{W2cImo6y-!RqRol)(z-enK}ZbM%p*5pe3w8 zv?eSExqE0bo|>xLZ0b@TFs_2lu9TpkQ%idwKGH}n0^w02BD7aN!A8+D4ik>?{+5E2+(4)k?C z>}1<6+O7o#HY0z=#}OY!^pqsI;POGTA~&#n5Ksjg?0a^FN2PPcmmxv!p}za~B%h>q zC%)#-GXhGdcEcKQEi=$%`j^Zw)l9Foq>fz_1PObX%M)3jBlwXg%9@_91~zh#yxYpF z&#qPlu6+S)e^#}b&Jv*)=ad{p^Zm2R(OfC8TpZQo15;f$|9(Y{fZC~oP%7(^7$srR ze(NiHSz7+f;YZSD!hkZ(rK8(KGl40@VI~7iFJt=FMxK4!5`m~7?4I|yoRm4Jv^?;0oAOQRz zS^!3@`0qu;>R{EYSZOKuysNF00J^go?edk8tf6PY(93WOcXz2e+j@*0M*qh1NVQ^` z&_?EN=nS@AEFJJX`|_j3^g4NWWy2S=)EXMEAo|q;W6R=YR(W#w(-A<_+8u>YKpJ|@ zYQIkkH@e39mJQ4_s>Wt*!24}pAEh1D!p|31QJm|4MUR0T`NDUzjXRdx=1jbe0pXC)X77 zt|%tuIgpV8B=DzC*|G1?}9odJKs1O$2xY-g%scZE^Pu(dXa zt*SrjBV&2|A%Rr9f}&_j;WQk{1@cx40V4ujcZ#E2FrtRGwD8i zN5a-p1YV6JKkZS1o}p{|ON(>nxt&UydE;s@hM@Uu97{4tviH)1UJ8|*&JXypsNIUD z12X~OvQ4cml+6m%-33vwHwPEvW$QzH_>LqCB2k-9UZ#mu&2a&N*+G!PF8*Ux=qkLG z!_*8STl|go*wQ0l)%s7@xQ)!)+DAXDADKbCDJj+XV8dDYXp(=Yk~D)o0(_cKfMU>; z*Io0U#|pg--`Qeto5bElBaI-^0VJTzjV4r4H{tJ8{)uEBAZ^)u zE<`Jbhs9ev*pVK(NBX>)785_+p;wq@31x$W0`)BQJHK~UD^(Z=Rq}m%_W2Ppa?U1o zb)we04O85Ry;+cW@M(A2A5`ND?T|hbNMB$Qi`tKYlF82*)%MU2e3_PF+{4Xb9sC^V zY~$s19oVFR<_@?kZAkBt>FW}{Q~Hdvgb_$3H3(9ZKC2&OFg^_Ful(kv zhzL1O2_oqY?6%j(S}6bRYJR<;%1niMj<1MJK$Fz=gdD`lRdDuZoS?4;g6{+(xBXs~ z^>eM$X|hy#ynEkn;i|r|F~@XinYp>4&PTeJwArv6QRg-&kEuXc>5q)x9q)EYECOgnmjar?RpOu}D(HKXGEjEVC%snkhN zj&k+bqP_N^=%pqYuC~(q1(QA`pqT=;e)|)2Vsrr!rs@Bo9sOHi)Dom!ovjDSl7Pzd zd==4#PYR3@{2z**cZ#kE%!0(azY@=Hi!6q&`7~wkKfn2xHr2=MI5S4ZX}02U@-nug z5g!h;C913KJbDhCVigq#W7!shNv6Xu)V5|rE*{0=mTvZ>!j29TTJ`xx*hdbbZ zXf|KgSpu~_SZv^ZJwpQz$-t7Y0K6B$zxz=)#9{w0XUrrCsnqExNkh6(K0g1lfaWw9 z@V(t$5h`drZc#Q}c1Rps8~0{gnE%HCa5PII@B+*q&hCp5fi`n8IXYr z&_n!i4L@0py|@S~-oM4t>4m=7?$}TJIhVGSPxau>+`!;5{H!!nNkl`xur8!AWMi%& zV7)*2;7cvE4*VG_Vij91^>D8C!d`NQ$rc0+i|=wR!paQDAc+5jz;q8p;SGV~2?!!? z_3IY#?fvoEABpv(pKZ=GYCplB8G!99d^?d}K?Ah8uV7%3G~JaVwah)2{#3mQVlNQ6 z2wAg=X4eN>WUJuEgEIU-mh;nf_HzQ9F@xlpzh$i3L)1Pk>6$W{TfF^1b09Mrq6p0W z&`F?*k~1FppQ{)&4B#WMS9#`$LtiUo%9>xpSL^!D4RRIVx!Csh_s3ibe->j9NC+6* zm&p{!k=2a@H)HGW4G(+l;&SHmHzMG2HGGMFQJTdBG@l;i-@#;2hB(R)jn{m;g~P9} znIq=95$zSue;B#}gWB1E0u?N^haPu1?){r*bf4F7>kP_1LOA?2quQP>H}RYZB_Jy* z45_;k_;8AQD(B-_XC}a0=q(7~>TYdkIo>Ut^bQ~90N0a&CjQ{~-cK1=+(xVNwz%aV z{m!q_mjtfBPe@-pjjLkxvB#ri)+Y8re`%onan1ZbwJD`9q!FK|BM!-sfg`N4UlKuH9*y*(*n(^Cb8sby!pQkqkz2Hd{p<&Sskz2lZqNhGtFjhY z)8Z#g<}F{xS6taD9VO^7R_B;E@9a`0=Fcb%LI1S_N%y>0!=BP62Z%`Pk=ixey(Pmi?jJh`6pih?7CEC{3=_ob|~^mit53&0>I#w z!v`V9&j@%FSoDe14kI2^B1dQ-VN(fI)(D$JlTNb%sXB z*D?p^`YzGLrOv!0)w94Vt?AnP`nKEs;Tem7Tb25nKCH203rGW=Ta*0NvU)P14T{_7 zZ>k+$!K!t)XnFNK_`UaL_Jts3M*X`V%^U0w^8f`3TdH^CkqA@rQ`j7ZW%$;78fKt5 zYbH?Ag6Fu@>mF@($I;!Ny-G-{vB`@CmzgzrEMt9z6Tj`KYa;UC*6kv2|MRitk|agn zFGtz@-<~BpHsKekXlVW!$rL^GDMh)vVGS8O1yCTrrCK+O?e`BQr&&4vpOq1(l0>6H zlT$j=#HEl2qwl-Sr5djqoLtIBtd#%54PI2i!wKq>8`_5g1XWhKY&EK(w<8TGn1T<^tTG%NdhM!@4`lg zYw%2aLs(#uhPl0Hk6YNqlBb0)GCIZx!3M0vg00QB=L@74lm~Mi$?geu<|A}m;K2Hv z4eIzLL{#-PY%tCF(+!XmDYlehlXn0H$h9YeWp3bQ37$R0mESdzYX}(;njpETzS;1` zJJuYpcRh*Bs;z7yx^=<>GE&ej;KxAb?JP@9+7gg!wZ^>U-oLYBGmeH>X}TR5KP49^ z#R8*Ij)Xx(p1S1^8+uM4I)I0=|N7l!3L9YGTtsUcPmWgZI;y=m#A))!Fyw;@ z4gF8S2%&lRNi8Ka9t-^d`i!|dLy!xWHE}%NT?oa%P3E_bR2{qte~SX}S;9y|#wGU? z9HzeM`C(nr{gplwOyw0wINPRu2vGH45Fqhxpet>svbuN@V`%Vv`%{lBKN z-M?f3Ty~CgE}CKaH{U{Tsc~!v?esu_#Fk7%O4Vi;%#_N0BIPG&1;XDFfrW3lLC0!) zs;NBtO?Owjo4w&3<{sUA&ZHv%EUE!uq!JXnEV7ABl~Dklp5>G1o-`waW04ds|6(Ob zB(Mm$zfq}fHw8f_5+4RSqKR%gXxwF_yE_U`?I%2b)xY+k^d|!pImS%-je4(vS~jaG zN-b~hT!<&o_UjKc~|9obNvw(umZ?eaEOlxN`8+0(qQ- z{_XHm*DtK@Cq5Qr@+aFlWYx%tQM#nML@DEZ7-AG2eSG<4beD1*k;_5bURG?QhTF6& zmtEwOaQk{NLm0tR%1XaG(Ex4F=}~yxr5IEEsA!z>@Lc&s%^sT8Y&jO2l-EPjqCWN?|J3)hrM=R zn!YRr$XzYbvYQr$B?!2^Q!#nuU>>!rE?F9%Ai`V-o!ExXhDx0+>Ui-#;-wT3xzchZ za8P`^mFFH`Va^*NS?V7)ifof?ZMq&)qPxXiz8njoUh#&u)ApPDKl9}nb3K$j%R%Hw z8cX_ ztpwg`nU>tocvt@a9nWD3nF^czq@!p`Zev!9;QK#g<37H=q?0r; zyq=(=pmsz>!$zg;P{vuJ{I{SABH5Gqa7jw#(WFKq(rvT0H)1&EMKI~`+GD#3^5(<# z^cbHZgQ7R-cU9hqMx|LM<6nPO!rhd7BULQCcIR&;iJ`y6$ z^tCh(&LJ1C|B8jMb<^q9+&S#PpGwbAvT{m#vJn=^HAutg zflkZZ=FOKiF2QXUMH4cf(e24~yg}+wy~33SPp}NPh~zYPmcw~3KT1zJR%7A$e63x0(0%Dm{?e4OEQWApVuiLhb`f@rF8zC4T1ffkE|eR=<7}u@EP&SzBB1 zx@Lc8>FZuUx@1AK$9tnj~s9eXtA@z;?p>(Z_(vSy}sMuYqCwAv+Z2XzO=O7_d= z_|y990q8zf(w5_H>XDS)wGmHGPrBKIKc3@AG^QvOMKEz;JCbu-d9mm^A`(ecIepdc zQk#_ud#Pqd`@<2^q60=}Gw6Ns;EcS< z9~%jr+}B?FaOg@}Zf?+j2lmQ+(^6zuoZ{Zr>wyjG#HCAk9&BrK z!N4@)r%UhcXYs9eSFoYWLT%i7Q-93*z4MfwL3ygelZcGq%^=BmQmvWrA4NQ*MxrrN zmY@DYssL+|6KkU)XlX(kQn2ds*9x@(RFmVc)sKCGuwhBL)+FRd)Auys-$3oJk(8@N%morJeq$7Vv! zO+2ZTdMaS6*D6+Q;}$)@93YKF_b>XJcD&Hz{A#o^4%kTAZRO4L9;X~6x)1;BU(Ed@ z0vWn6^w)yYt^)G>c*({O|hX8RSTk2P*s4!eM9S_7bQcTM8Hh(*aa&CvWO2FGsBN zs=6+{T^dg34~a9F6Z+eW$mnhoG3b6a3daJU_O&`5@RX%9r_wC@52~>^z33aw-*)zZqi>0E zdZ!TSlI*q*G>j$+Bzw?WTca;FcuLQmQd)j0WeS}+YG-z;7WG9<)aj@fN@q^PX@f$o z9bCP0!DfOPL>yQS-$Cl`3dOx(z(zUXgtVXTn!e1p8J*A5I!u44S&(!vn^=$3yS~H@ zn=F>g8*LKV5mx*6R_@=6rY~y&eu3lSbadldhlSEK1@33Yo9KAIPga-qU&n+SwSd*} zlKcody2Bl|8Px>*bNBxiWgNmwP4Sa-S77sd%<8RO?&{s!T6BH2_jP=Gh)d5B+JTB( zI2-#BSIon!5K&P%?M!f*Uk1-0_J>=#I2f~NeCsLT;hpj`TV|Ep6d7LMQRRd=ynzGb zfCFT0BTBoyN$>2?4Bz~OGy=9pO~t-MX9?b2wy*E7CB1u1hm`|$FCC2WbJP|}UE#EJ z^&0HfE8WS@tAb@wX5qWV>s-sQ8S&6En;};*X&MLb5>h+kV(%EGbRpH^eV)Ul{1aiR z+!1phvqEaUpLiQ)al5H32oqXbu`z$?hOy>`cGaXhZqm5f+FT8iKZoZ;m}K)qN6T&C zFw}C{9dl!9mQm)A0ZWrMqowwfnP}grfty8KeERMu)~2D9S>%1|maBaNr#9GWcLf<( z`$=0EZ1z9=J=O4IgcWuvD@ymsESuAc58El7YxyYWcpNFwzp>C2Yb-Nt8C@ZWI-J;? z+Sc^*t6f_6158Ux`q8=5lnE}9VI`i{ z`O6&Aney!7(-?o_Xp!6C1FDC$%XP4`fgjheJg^Beo!A5!4-3=LsRdpkbET~%;_Zk$ zlSkH!-fZ*OMPTvpe_rabr%y UJ%h;P{}Pmx71ZS`URehJFT68}fdBvi literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/btn_up.png b/d2d_app/client/images/control/btn_up.png new file mode 100644 index 0000000000000000000000000000000000000000..f7012e35de1a00f4e4f7c8857a2b473d28b026a3 GIT binary patch literal 9766 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 literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/control1_bg .png b/d2d_app/client/images/control/control1_bg .png new file mode 100644 index 0000000000000000000000000000000000000000..5ebcc5b63bb4890dab167fdecda267d5fb67be71 GIT binary patch literal 10420 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 literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/control2_bg .png b/d2d_app/client/images/control/control2_bg .png new file mode 100644 index 0000000000000000000000000000000000000000..67920ef0dbb791b13b4db314a16094836f612f89 GIT binary patch literal 7809 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 J2t}*+{|6ThOLPDL literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/cta/oval/default.png b/d2d_app/client/images/control/cta/oval/default.png new file mode 100644 index 0000000000000000000000000000000000000000..43818ea0134a24ed3cc2673533b17b21c5752bae GIT binary patch literal 4606 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 literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/default.png b/d2d_app/client/images/control/default.png new file mode 100644 index 0000000000000000000000000000000000000000..43818ea0134a24ed3cc2673533b17b21c5752bae GIT binary patch literal 4606 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 literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/ic_control1_bottom.png b/d2d_app/client/images/control/ic_control1_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..a9b8d11cc097b011f19162369b038b32102fcff0 GIT binary patch literal 458 zcmeAS@N?(olHy`uVBq!ia0vp^ia;#Q!3HEhu|8V@q!^2X+?^QKos)S96TLuo?+DS>sQW^hRahF zuiWRl-)HC}=o0(2xxg#*&30$oQt5|%uV!pF%y|+g{@%FWg=oEa>%`E%42?`Ttw-8!8=N59T{%ToUH0XKs#2uNAtpNUBKM z-1AQMMcZfJbscTC>uH_~yk8N^5+IfWVg?501&j>LK$;OGwtxvPE4P3d&Q<{_RJ<@<38?I-r;B4q z1n1G|zS=H{5^d`7)kpXzOz6-N3}*Y^=reheY_^ivDX*l*%9{e}S}rN1>P~9?!*E1M zGiJMumG9*APkzKYPHYH1QQ%k@dT!%O1YGz`wYs zbWJI}^es8LjQ!ce zvt5B}b|zWcC5oEdJucw+snd6ffAeAkzW%V1tzts6otv+-RX@o2@u#DddA$KEa{>3l z$Kg3je^Xzx)wf+l7#PW_H>k*x8_ATud>;3MQPsqjiP_n z=pFgA=YWdJL%yzKQ*XGW=j=+5v|FH)d2kl%-tT)~$O?KJMI`;5_3Eux{F&v6H==b; a|6`Bc=Dc;`?1VL-i1l>!b6Mw<&;$T=_~#w~ literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/ic_control1_right.png b/d2d_app/client/images/control/ic_control1_right.png new file mode 100644 index 0000000000000000000000000000000000000000..657944d7e11ed0c73c9a2b38e29e002e5627afb5 GIT binary patch literal 606 zcmeAS@N?(olHy`uVBq!ia0vp^azL!Y!3HGfUF^yPQjEnx?oJHr&dIz4a$Hg)JkxxA z8MJ_G4hF{dOa>N^5+IfWVg?501&j>LK$;OGwtxvPE4P3d&Q<{_RJ<@<38?IZr;B4q z1n1r9zS=H<636!*7y8J!#G^}RsYdgA2bHI}$^LQ6rtE#=()EMSrEQ9Ar;6vb8_CW0 z>t_|u&bz)N|GAd`U#s($#^3*(E3STa&L{AqyldvX?fo$}2c=bnG$<3=FuT1ZKtSX}Z*sC|yup+3i>pRODg*!P+^(l9nnZUr z_!S)5cB3Q8^IU@HrgKYK5hiHN7!eOLOC{YNm6lp*Qwj z{q@$2UG{;;$+clM2mW3DpfS-pC*)603J2SP;8o5?G{ZjUI2fl$cYHkFv3h5op-+>X z&_1QCqwgcc7Rc6kmu}J!l`s4&Vw16Wf#9-7;ws7$ngW7kjaF22XJ4_g-euwSWAD{p zp$l(U3As+If158_|KXX*7RQ{RZ$-0S2MdR%%y_L_^ggP;bd}phW(SpD=Aof4{C8@t dx%%Y(G4pK!-f@qweYgXPTTfR%mvv4FO#tz2^uhoD literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/ic_control1_top.png b/d2d_app/client/images/control/ic_control1_top.png new file mode 100644 index 0000000000000000000000000000000000000000..1ffd3922c1f8e429f2c7763c6bf2b70d31ca56cd GIT binary patch literal 489 zcmeAS@N?(olHy`uVBq!ia0vp^ia;#Q!3HEhu|8V@q!^2X+?^QKos)S9Uqt@rH9J$Rzl#u65nw`HDTSsonVZ8~KpWOJW~0 zoQ!;1o@XFCX$o^+^&DxJ*Gu+1l9&)|{k$eWcG3i9pRX48y{mneAG-Z!_GQo0K6f9Q zZ3tO!`E2VoP2rUn^nO3vdP(f={2kmnrpfbmMt<5}+Z>!&`|a%6sxleTT@E|;{OrB; z;0teiqtNP~MU!?tTEb#+Zc6a#+Oo&bCT-nQAGNURfa=1+Z?-l&>#ZKg-Z630{qBBy z58q#(6Mq?sp87AdC|}`n|BAg%e}(9IFMsX{_doK*%{iz$FHx?Z*=Fu8m$%`Y^g+Sw M>FVdQ&MBb@0EI8TQUCw| literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/ic_function_media_next.svg b/d2d_app/client/images/control/ic_function_media_next.svg new file mode 100644 index 0000000..e3be188 --- /dev/null +++ b/d2d_app/client/images/control/ic_function_media_next.svg @@ -0,0 +1,15 @@ + + + + SVG/ic/ic_function_media_next + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/d2d_app/client/images/control/ic_function_media_prev.svg b/d2d_app/client/images/control/ic_function_media_prev.svg new file mode 100644 index 0000000..3375154 --- /dev/null +++ b/d2d_app/client/images/control/ic_function_media_prev.svg @@ -0,0 +1,15 @@ + + + + SVG/ic/ic_function_media_prev + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/d2d_app/client/images/control/ic_function_media_stop.svg b/d2d_app/client/images/control/ic_function_media_stop.svg new file mode 100644 index 0000000..941c24b --- /dev/null +++ b/d2d_app/client/images/control/ic_function_media_stop.svg @@ -0,0 +1,10 @@ + + + + SVG/ic/ic_function_media_stop + Created with Sketch. + + + + + \ No newline at end of file diff --git a/d2d_app/client/images/control/ic_home.png b/d2d_app/client/images/control/ic_home.png new file mode 100644 index 0000000000000000000000000000000000000000..d0127de1a244032d43df8dd810bac0aff76b3189 GIT binary patch literal 483 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1|*NXY)uAIjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uxqunL1}TjAJUtGm%-7S!F~o!S z?KE#~mqeNN^E*s6m!6oWzhKIgoE)9p8cAz4FC8`MXzl2IjlENQS+%*PPdeQUJf-`% zvTyp5@^eRJQVsW4-7CKL|LOO*S3Z+fo^EmZ$@pVU%wdanj@<7KU*7rAYfHmv(>)H% zuO7aKqi6Q^b5*~KuKFKk+jB_u zjI&^5`rg`auZ6FwTnx@QsK?_d8JR!-@2?l%m&)Cn_E0b{LC|UK3Oy=Qd(iIimU&od5P0@U%b;)qAkmJ*VQXF;rp(C_e+0j*KimYTuZA?R;-gg z+24L6R3$xw%dbi@XCA}-$I`>nc^H!0DHRnxvXN^5+DZYV_;xjz{tQ1q!~eC3z!hH3z*?-A&|nFoqtaQmGOAGIEGjV z?wxv&i!o57Eq%h2UX`UPPZ{5=S+P6)DXYdOn`x8xG|t_$VanXO<{JXmq%77Exj%8^ zte5i=f4rW3dhh?A?+ea9u@-e?QwIj01}+NZTh?bz?u7Ln>v zou)ozV``1*Qu7PT?q>LX73yl#Jav+3pWX?HWo+EyHyq5)h#2J0=&sSp?aJHGAd-<{ z;Cj!aseS#Sm3snDJgCfjazC=a(=MarkV%8&iJdE#&DGT}iM5+(^LCNppGWyl ooAN#N+*dfTJ-Rm4q4L=t_U2msY_BW6xuEdzboFyt=akR{00irtyZ`_I literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/squarcle_bg.png b/d2d_app/client/images/control/squarcle_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..e101dffdf9ae901d8a22e301d69e98695b5f1018 GIT binary patch literal 2503 zcmV;&2{`tNP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91PM`w-1ONa40RR91P5=M^0Jud2M*si`F-b&0RCodHTx*C`RTN(5Uf<8r zW*ikX!zg=bIGJw=#}GpyEC_-kd{CqaYBl~yVtyFWXrm!2g^oe}Ne~kaR2-#}Ofxmb z%19IiWzuqdO*y0Y^nK^veP`cu&zbu==gi!>cfsYHvma~i{oS?K-g~Wcwjlx0qUGkW zyAc^9hCIlhY040YE;mI=4UqwO?uYbVVoEophYdp_Y#P!-xZFoxGxC~{eiL=Bqs}#? zH{kh-8Ig;4zR*1+r#99amsrnlf;{i(jknFxdl9Jw=L&SZ0-YO+YpM5=k~u=wHOM-F z>v7~B?-G&&pM7i)WKYR6;1(=12SO9(qIEChSBb`V@wBB`G6R73Q1t+Q+tAq^Th~^V9*1?v&l`i9aEC<`SX;_IY zt*$njQ?)-OaPzCop=Psu4MxwTV%8b*Vf&6^ikn+kV_a^lKLFXCsA+`+8j*nQ9*?$Fa`mZ#zn3#YnC8fWbYB68TNaG|D!Lo&&} z!${INYa3Ol2)Xpz36liixM9!Ny{Ai`y-CJ?+`>lVmH=GDkaxAb;;n{2%mWlpiQBlC zKdqso_|f7m>>xJ)ss+1>!OEZ4s&S^gSOm@eU!t!OKRRkHiUS8#r02FsZ6grJ$Qr7# z7{QgI#fVl z{vmRYQG*UZ#E4j-DPJkz#s=B0(t#o`%n}(lMx=XpcgfFJirl>`a_p4I&OL|+dJ<-F zmzPcsfFo8>;DBUBI+b!Q6Ap{KG#gQ!X(H6Nbcn!Cfq!NKn!Epdk?r3g$a+7Wn*Nkg zSXs@-*k#<)SL)kGWXXJyhaYkl^B**;@kTVSq`ycHnof@A>#?InrcV~(y-rvE7Fh*v zS$l!kGbF=}1xwA@Sc>e{8|LLbhv$mLiJH~|W4|2|>kp+KcC0^RDu(zRETpvI{pWd+ zk2a*P?`2;UFRbC_gfK!!s02T*v}yYAym?!s1|8n_ZF-%iJ!4tcVO>S!N#5;2#4Kb$ z?feqX*^?82B5K5Bl3XQB&|HlUZMMbrWF@ik@6DJHM zn+w{(gQ7ouajWtP80%KAL9jX&4P)K_>`FL{%ga>BK&}npipkXzp>b1!5XWJA=B&u! zpYe_;hHW{9qpm$pZQwfX$O(~+pNsr-5`Vy*=s^Zw zorW$1PXvul$WbHV6ohL?c{$Q~1%etzO{2ys3ToKm!O3;0PQuc-{sw zH}Sp@iG6oFbA))f0>?}q&;)yTl=p>1>@)k`R-coWBlf~Pl!|8!!4Eawp4S}*gmuZDCY}rTlHPuO8#3iN1v5=zT!Fvjc6gIB4SoF@CFmToo;NE4=%iCx4 zh36-=H4!-VEhCN78Sp3}#A8>%_9bjZ^fDd!9=0sl!$s|2(&7gzj)%mfv3TW1ZlPTKka#>_M*2nAtP7}kI;cb9{|8DR^S=Un Rf$RVP002ovPDHLkV1k+dnvDPe literal 0 HcmV?d00001 diff --git a/d2d_app/client/images/control/tw_list_icon_connections.svg b/d2d_app/client/images/control/tw_list_icon_connections.svg new file mode 100644 index 0000000..a08d6b6 --- /dev/null +++ b/d2d_app/client/images/control/tw_list_icon_connections.svg @@ -0,0 +1,17 @@ + + + +settings/main_icon/01_connections copy +Created with Sketch. + + + + + + diff --git a/d2d_app/client/images/folder.png b/d2d_app/client/images/folder.png deleted file mode 100755 index c8395f541840ed9fe4e13514961260f9557e7b66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 743 zcmV?P)00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i*Y| z4FVjzHBMOo000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0006)Nkl)yf6okK#$FQXemh5sL&XS|#I#jWS6*nMNELczk$H9v1NHg=A#f<+TB$knX zrpi?s$un+s_vqBmivu8m}@DuHOc(Dg`tA zu=W-oQ{Fs9L(=wdxivvs^M8=|=5bhu?Sa*rT4jFi~U->YAbMrnHNAy0={u z-sWGkcyWSKbFk<5Ubqar)n78O(dhwgNvR^G&IeaEzok(A#5f;dX5bffZXs25UckUsq diff --git a/d2d_app/client/images/ic_back.png b/d2d_app/client/images/ic_back.png new file mode 100644 index 0000000000000000000000000000000000000000..ab49ba852acffa2c368add8b8b932677f99d05fa GIT binary patch literal 804 zcmV+<1Ka$GP)P000*V1^@s6{^R5m0004mX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iQ$^8=pdCaUGE^rEVnrOa3Pq?8YK2xEOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4P#IXWr2NQwVT3N2zhIPS;0dyl(!fKV?p&FYu{G~G5+ ziMW`_u8Li+=tU3%h$1F4%b1g-Bz(u$Jpz2ai}Ec0bAOILHD@s(AQI0q!?cMvh^IGg zgY!Odm=$G}_?&p$qze*1a$WKGjdQ_efoF!zbZVYBOe_}KSZQNcG&SNW;)ts0lrLmF zRyl8R*2-1ZyeEHQD5tM1bDic05?I6%B#2N@MG0lt)K>{QDHc++ANTPOyMBpW3b{&P z;V-)Dx1sXNS`95}>#t9I72Cnp$zfuQgK1r{& zw8# zj1?$*-RIri?Y;ebrrF;QsjG6m6xwr(00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4#NNd4#NS*Z>VGd000McNliru55FB;Ui+rj_<0U=35K~zY`-IP6wgg_95pKG9j znP4m?=EInJ0Zj#?VJ_fbAPk;h5+l8e;32#~BN~_t2y+6#+GH1I*@5Ynm1XzE{rIY@ zUKQ}$YMO?21;lYo0BASRCm>0ZKMIJVXcvI=2&k$Gnx^4!IB=O|S%zU4I3AA(f&ivz zO3&WCJsJRji2oDIvY_iabfQX zR1^hq2Ve{6bUKl$sx(a#Kd5b6ArNDX08m+$wCh>1EQ`W0q;KhZCeQPvEfB*naKGQd z1=*^3o}ugdeh|hOjpGQ%arV33Lh0Hfp*<1RtBwDX9@lk+Dp=PQx7!WFFhEfhWLbvm i^(y@+g!c;nAH4&CT%3g|&oMv%0000uV6_upZ~zTGjrz5nKS2}_RLfEz7vl>A}6zMrgJXms3ZHI zY~lal(^KvD>g2b^T99$|k!M`zTvj!Ff*bL4ZRavixU^rt6HmP4s_U=1?vksn&O54K zzr3rjz3Spie}9p4H!U1_%FscltgqRlVCl}j$J~4S-;TNJ8N(x+7h3`nl`#k2P&{pByWKUm|WHre-Q&QDvN|NLL>eBs{vzbanwhZioN zJGS84sb!<)^<4YLj*;(APaB_}{rHg`PwISo_N#pxR#|@M=aVL{SlzDou*{}cyWI5m zFU-HLv`K<1ysdlpgBp)d`cVb&Nq{W}Uo#k#HS@`5165LsT%de5} z>?1C(+C}&Fcb6RQ-k5&c{R7 zy7#VDF8L2`$QMnT+~ofJq^mw~`{~`c9rRZ2+SX>NC*SKnrfJs!!_G=?drjKur?+d^ za@tX~4yxYeyu|ZH^lmrd<|peMGOSbO`OD}^=eFH2 zF15Vz`RA`HTQmLjt9v`Q;`-ZWl(lL9e%;#-Prdz$vgey^PQK)vtY`nH;DL+ZtK55( zdv^W8(|25rZ3aB|@R$V))~sGV|L945&pPj`({C*sI^o>$rQvN1Z=raO>);PO5s%U;2-D zaK|ApHomX#Ut4|FY-ag|E0?t?PU^X=vwP>Vo(X?=r0pwbUy!u>m=?K%uOGj%z`5-o zU-jwimgz~iUvlS)={J^d=~a5fv(4P?7a#T4Yn(f$f75n@zIwmc=jqP%e|A{wcly-Z z`DyJo<5TN@nzH!Qtdb#J{@l0eqzQd<`(|Evd;M#Nw0h%?zAf*b`c8w^L)y>o-JsL> zlP9wA`t1$o5 zBa^E>&@}JMd#j(+_?SmJAKBsL`v>KndSrv`J+4jcde83$e)P!UU${f=D7ky=5gqMx?DE{&Z(hHo^1_FD_WS(c z@#|`*b)5A3gWFA>*!SJT+GIR>!IXC!zmfg=7-QI$QDYM*~dhkFJe z*`~?dst;9bpZkY<`%OBuY1RAs9nxaV!-+?|`;S30tIixa^U9N(tZ(z`Q=N{i+vL$N z7hZVzdud(&)+Xtyw@>iD~U1v@1noes{ zFM8sTKBvAg;^ZZ-JU6IH=ZDVh`{r|_Pk#HPdtRy5>3>FaoqA`@qmFs;&F3GRRriuw zmlRz3_PXmosH)iMDUE|Kr?;YB*&QrD1Y7eb*W9_$} zIQFGFvmU7P`JjUj?XdBQwNF-l@~Tq@w;tX4k2N0oD)X_UA8Y(m{mP8syjtLL0@>std)?Rd(nS2Jcm{`#q}jXZJVDfLbn`s(4Y-1FMdSFRe=>mRqB zQF>qM85574ctXE_ob>Fw=dKz%IWOyiI`7}qCjauB*YEzHVVx&6e|PGFKi<&#<0ncR zeEdL<*Is?DYrl?1cRc<5lXv{>;$CU1p17v)>FbZrSljaD;X7`-e`)nCtyZ?G_fn^0 z$8@;pcbC8R`0&REzkcNFC%t~e#!tGuwdv)NFMTrL<1>nfRqFHk(Jg-0;)tOSO-mWM z_LK#uEO|Ne<(kL!=(g*vcCTIjV!h`+?tkOBD_`FH#54ao=k{lgz3SzqH-ECWsQ#_( zO9z!+QS|bzBeDmlzMtJRby4=T+TB0ve9cwe8?^s?(YBNNojtL4zZcJY?7ZPC{`|<8 z8Qou)Gw^>0R(|l($-i6Gbk!A;ubBKo^VH_~&5t>5!*QEOoP6Avms-7a__2o{`}x$b zr#?S*?vtIL>d|4|A#0yn`_#OrmVGef%$v?^Gy0X$A6|6Sd#lfU>5R>z$6k5YnO)C# zaqy{Up8fv7H%GqNZ0^Tze*AKkm&Y9c=<%;VGk563ceaiGa`dYo)Olyk{M1EnjlN>^ zt>+Crzt+$XK6`88=0`ty^wy7V{om3aX*u^SsPuY+GaKA?-9N9b-tDw*OGiw5dULN^ zKim2E`u0NyPtTn`zvHUW)uyzXbm_=bo|<*U&{{*sTzBV=dmp&(m^-Gl8{V_sQ}re< z`Qnq+M_<3|nzL8jGIQ6+r`~^R!lqXiy}h~1=1Vu_SwSx1u)atpr=e2)d)pJ$% zLzf=1^o(=AK6LyCUwkm-go#%@bM9Ts`u(X%`Gw`Tl+SQ4-`*@?XwrSd`V2cOvAFP- zKjx47ORsK=F53Oxf=zuMe0EHq8hswR*juwcHXz=JuvaM>=t+3bJyv2_xj7#_YST*qr>pdH_lkx@499Ei~2v_f9X?0JDkw< z?Y2jEZr$^>c9(Tuc<4u+KI%2O-Nk2oJ!kO9!AJf6nEGAYwSKG1mB0VjvXV_Z?pZl< zW!9=c)Ow=*7iV96^K;WC?7Zvcny3_{09TwNGyAS86`kY(vBH+}v7SBoA#^yw{s zFW*#kLe&+29sT0n$DH1_!QgK{dE>IK?{&ZC=0%ySYNQ-=_i3qbbpP=F(XFqTbHeMJ zP9Of(ZJ#v1<+#g-o%88ecYHc3;qr}Hr)I9X>(-5n=WROsgu(64ST^dsqPs`d>sjNz z``@a*sMhcrf12NN@l9*$-E-AfnL*e;B*F(|2*KGPcX=YMsT9Znn=Z%>?r@_n~gHC>E?m-)msPuWGf0d2ga%0<^E;*=WtUaHYRgBt*RPm4p!|WghmSpc+V8f1c>VVG7Okmv`iG~Fc)Q!VS8TX`L-(>r zXPxl*$4`Ge;;k{iyL`;%TRs`}hl>l=*L&vBX-jr~a`U#D<#Xpe)3wKvPj=jLRl#Qk zyOz~la@(~nN~cZvc)^V=HorOcgt6!D?7gYaf__WxnbYg6vc>baEdJAF<8OR+$Be~C z6r|pD=k&5ic0E+NU&=#IJ~ZX-oVzzZb6C%=U03$Hwsd{T%l)QbIKBBZwaT6^oAOqz zn(c2ZoU?J>v>8v#cy9Ri;g62H;*T$uZWzC@&fAM7Png{BUtiwTvBNn#Pb=Q^>5YqT zY_R2pWtC4@{l~mNwJg76&%3)$`R3)~N9#QLXnAtd6FW*S=-76V?Kkr-IP&D4Mz_yQf&Wh47dMTpt?0I)agY+wM0#Qez+jqzAB7t5&&n>(x6tB{`*gQc}_( ziHV8LQd3hiGcqzOS@QdeADY`(-57430* z_7u6o!a`S2P+;kz-Nv`bc&3$`b6HuL9-!U3cY8qg>;arT9xMaH;jz7d3;|9~ zPIh=YKw4T_h0n~)^c`UPjva3IuHBAs`}Xa{CTn(SNy)fv+qORc#TQ>Nl1t1p;{Q*l z>fbb|rktkMl&J`)CsmG_KrnRVAB{!jJ)v7K#JKK+>UAuNU{0=iXz~LB` zfXAqm3)93y2VY1F1KC8UvH*HKj+-p1rfOvaYdF*}F=WDk;^fRdY7CnlZOBTHMZ^JN>j74-RR8 z5`ro|(ZnNq7>b8!Su-mJBM!(pIXSL!<;pHMH`nyo<-Xgr$!*!P*|04dZyoHRi4!J_ zH+jY88NL6tsrferY6xcEe*Mn0Dey|$@U*K{tEOXA0^%k!+_r7oDhw+SFmk*TV1(o| zas|}>8g5{C5n&$u;1SA#DdZuK5nR1`br1BW&70l&^&6Zm0W%8=3jX@ZCu3i-BL6jT zL*0CX(D%RCseGNLgr?b)zWw?SPEAX_!PdxD_3G7iSvJjW*s#HEHbY@NbPJUhND4#U z#YY~Vv}kH9p~^}=BQu`v3HBqNP>$-9{2DcCcz~Inzg@eIX?p&iJ%#s;{rKZoOa$Qm zs?&0)oAmy#f@%t|;HC8H-Mg!e$_KKtvpY3xP~Wk8UAuOz2NRuhb>QUL}A zf*pW}<8hi&mFJ1}gW&}xG?iBks8y?$v!=S$tJk>o8#b)B9o4O4$A0|0@&2NtHr^)a@~eSrmHE-xq)C%X&0Dm1 zDl;?dr2PE61iRLAD_5@ch6_g+29cAopot#R5G}gO5W>USrfHKf_t+sWvuPW*@ui1d z*`~GrdenBo?cCDl7S<|A2v4T4ToK=jG?KLtHR_z6VrgX$xMXiZ}{}MuwM>fX6_}qm0TyXR2jgCJt|T z%R^nI8%DUq{5Gz{4tI-7t)Ai{FJH3*b>XE4Ax=6F;^61hNp(Zl`VLKWbu{u-R(V{O z*$8#mA-{2cquksoAKG$srHM~9-d`RAHO9B#Km0*K+XSWe?%n5awzD15v}u!sEp~ar zW(XJGa2l`r$sT8mOFVX{OF8Tqmt>~0gMF7`qckbWoUoC}Tr-`X7`Gv57pYvM~BAZ@~v>esKI)23~^S1VPnG_Y}Ao?EeEg+B$N2%yLi zq)|o+g@%v;#KR~F4Wu$`hB#p&O_|c#Os(T;28NU!Ae7sPGGMLS_n5Z%z7_Tk8+oiu^LqE`TYt{%S*IEA4&#k3nkDex z41W<&O`#;)5LId3qUGos)vI^5%N4hH@ghGJY822w8b>3E%Mr&g&~X?;Wk?f;CSyUv zDBMxOF@lOZ9_7l8xzvx&a+_+sDC`*YeLDg0MulHSrcOMvaneh=D1?p|KcN7mocM@K zSK{y}FO5Yugv9n&hc(F6P z8DC;&Q**5G547^%8Sj4t?0*ERDUj5xS+lAQ8|96uQKM!%c9nMDu>u$jL?hK80R)Xa z8Z90g99}|Te9|&9an?^9#w@Pi$}K(eI+tw+7)ds@h9fh?2O!WxP)W!4VrZIr$&)cC&y*`elplJ$Tik7k zOEtT*yNwM+2BtatF%?jwyo^!GShY@6V)~dI*5ds+>8(70DV<4&U=qix+>h~v?V()) zoAS$-FL!x)c~srblA~;CVZ?4XzF+~7W6Zedgolb z4nr{<3dc7X#nosUg9kj($cM)Ch$F2KV{*w-0r2rxxi31N8-Zzn`b!qVQoEe7uvj!( zTS-HQ=JAfnmOg}`mtKT&)Gt6)PI-jrOgqG6*jCX90h`Xsh^=I&UDc{q?cDmH zgWkZtR^Pvc&(AIttB6DS$8vKk_v6}Y*|KF`Pa3U}20=zpgUEx14;zmWLqm!m8M^gG ze9y@@xk)v;yQ~BoHP(p*pdHQFRXn4%%(2S_%!)8ZXS`CsyZ}_1kb0pLk|r*F6_OXm z(MxGU%HVP0rL8#faiLt*3oiqMJ&9fN^y}TH&*R3LVr70dMn7x%wF=NGxnIBjSJ~45 z=Wr(6CTH9-8!qE?&h6aqvpVh!XvV{Nke>(8Hxh_8KwE4T)RK}u<>zTOe=qq`&pox#H60RdiTi4%ovuRmzQ97A1Xi$d!Op3 z@i+lXTn&&RNsEts8VU`gvHlU(ZFi`9u}WX-PR1JpG*Ud8R<$u=e6W66H$s$miX}2V zbNLgyIZh_VmO}^9p)SfJBrnuGzHG=N0K@VJiqk$hfz0KO0h_RR$&z6`di0z&apHvW z#zTmJCN4UeV*r?cLBM zxNkaNVDqp&R+3ugifn`$wg%l^#{}iK6wyHS8ziIn{{(EHY)1C_pp)v{E8&M@@T(na z7h&j>Ry)ExXaY~2L43%?QC_wo&BFpVaMG77UHWw6#*I5!K0D&Qy%44YxSs^738V!n z&6+oV%5I%C;xWqb)>f3gx95|_qqvkO#5mAVp0o^wZjvE>MihK4I(2j7wwanKHqxw9 z+gP&s&k7JXpoCp=%*GrtMANX<51;WE$#KO@{oxvBqzWfvLy!&?nHEu-pdm*9s14Ge z{7{zC)Qep4iAS>FLl$&+ctVng-)h#V*~kixusb_v7`@13(CQy_H2bHxq&|K7o|BVP z>BK5_Zn<$I570$UKq*8ayc&R#`}6R_BM*=CB~*HAO?xS`pv2B`t+CK;SIY*e*gCD> zAX&ULw$o*EWV39v>-F*2VSX$woe8CrXy}8-`0QwPP{H*wUTL1v;Ov;R07Zt{p*SN` zqZ51JNULqCpAZ+ORTewvn$mpJgxkB(GRDADHks>w;och;+0 zCxIPWIPD^u#;E~eRZpy)KGLEqR9=`St~6zk ziA_{Ld9o2Sbiq!cEm`IoG-!~pd*`lU7QSWmY_)PfI1T?Gs3rj0q%_LQd$eY)nzi&m zn3N)0U`ctU389Hjqi~d^TqJt0aiZMl7eL|5$f<1Lm{IM2q8Zz7h)iQz#58PMLd!E1 z{jN7E3j`iW1Df|OBIp4%mLKR8ubcFWr$;3tUCC4DAjAt8_>jTKW;EkMS&GwXv>J(vKXc%}H(e>&#aNA4m;C{D(oXQ$$9tdLWIloUJm> zXGiOq^rLR-#CRAPAL`?aSsUUV?NT0b%7o>R4-neu3E;3^$)rQ5yz*rS)dMd#02(!F zWH~l*=JuEdGEGa0%PF;K{cUhpOT)D{y^P2brM&vUR_aC3ZRf0MkZ+# z1vGf1pg>e!sIY_rB91bW*{or0w=>6p*|f(c7THC;X~eo}OQ`jXXtb7FJ;heWH1Xw= zEYI(DEuTpWR&sWiC%arL8yegfupjhR2c&*E(nr&i|?A$#qyRsQO z)0Jdbv-)g$-?7#0+Op9V?u^cvEJZUPGQIro&N~#g$Nm=61aVQ=->ca5IXjn7X zmDR{}Im_&Nb$0}6GzUi|Y@9?>u?LnBV{%z84NTtwVzN2yEi+J&iF_Qo$YX4b&Zr`e zBThS^bIOCOTsha5shv^c(lc`0)E&9*>+%L}?5<3=-Q<;}*}Y%uoQ*QeU7L+lotycI z+q!tRZ!2|k#lVAabRgP|eCV=)Yyu4jT{LWB4~x63?5xA=H1G6J$B%!}SoVAEx?fOD z7?w`4(Q{Mv>ecLtxYb@bMj(qyiOUgJuU1H&=xPK&OG%ZD54lf@{Hj%|xbl=NcX;z^ zuEV_DZo-;ES1r{>r4=Z3cHC$PmKsndkonv;P!nq9q#&Q(X5=^WC9s zTDp39OXce{t?rn<4)D@AqXSWjZ6 zNyMCqZi#ikCE16&w0_-P=Z-U7+QgS!!HW4_4v*b%sY0iT%)GaQQ@`vZT|)b?w%TZA zI=f2T3U)d(_1~mJ^!z7-G!qHT(Nbq zjG9(khTS4eNp_{?%V@hjN0V&RL<-Ztb*M?X2fN%;4t5=A#?Z?t|7R1+4B(v*}dc|nOM;N)Zg(y)bIG!)v5SiO3~( z>(;Hez1Px)Ib01DD1-olCoZ}`QW{0Yhgk6=4<16rm8Y_VfLf(Wt}84xgJx#Cdrxj= z#@JmHYEPX;F0+L%;iexIGk=-@7!fi&U6`d>}BU%1JraZ161?T2#o->mU|#0Kt0Cb>;X>3KCoGP3Xi|q6&`n` z9eYOCxGZtlnq9JH2#rkiL=O!DLf!@hAH&H$_hlQ5IJXbM8j@(Q;MYt}N$yi(2GUeO zna~haNJXM6uIWm2LMap)6N8CIa-qdu&G*-2j1s1%RGZ?g?beB$8-8AUH*U^Gw{Gn= zSF27XS7fURl9+ZAjVaL;xn>LBa;?hOyDU4-_1~ zU$e*$64p!Fjm^+iI--trmumJJhqLco^tR{2YR;WImo+k)pDhw0BTlnj&04iCvzL5Q z=sEivRiZH}soX1XA#w5u$rGPw3ROnsM3)NCc{Y~DF$E$k+14~%)tof<=GC2D$<_i_ zu)WYF+qA`qO)1>tDs5ZtI)3q>Ym@k$FU#?o0F`Vy9mc^cP8i0OPZ>JgMI)xUZ`T#L zI`wQVH{I9_mHIW*OlR1XgO<_hT!0mgOp6=A$32(=H_A75pO;jpkxRd3xJ&JQYK0E0 zv)Y_WZ^95@(yXmEqovfSS@SYW?t^1R!U~~Ra#CXAi5L=tsKE%KfuUE=0VJG2L=1d{ zc;&;RIHC9zl8+;gZ9CI%xUNLG&UJ5D!`*UfGq-ug77u2!=~-{n7p~{(H(g6Rte|cV z!qr(+Cv*X}KM+G2N2~BZ_Tggp^1oKP+D)tZvt|xD%9(OKsMbzPmw}x9-wR?4z&bovvG&UPOBybGt_g!b** zH&04RZn4{X3x(tq$3PMGk@2Yz8eTjqLkJyX32104BRLAWE~F7mxjZ+_D}lNbLOD73 z|9n~-H*WSuH*4xL*EV~qYmrspa_xYC>uKtf!w~2tK&6Z7Bn;zGIWEJ}+~;%GyDMIp z<0{z*O|;9EBBoith8kKnI?JuBzr}|P`^S{4sWuv|q|FAFzc)`b=&?NV&8Kzj6dy{9v&K0S{j|ej6A=k z>ss=v2NXWL-?-20B15QN((3gZm86NwlTNjB#+`P=chhs@Y`bcY(d4Asp#~$8O%dxU zQ?N#9)HVRB7^yxU0p%}mJa`d^6>F}67>!neYvoNyN~J2U&gJ*Gs>hsDp;M@L7)Mv0 zfzGX5DIqf}>l`yrg<->yYW7aH&)V!IVNg86WE_mksDg$g1Q3k^z+l>>9AyYmAar3` z@(BT)sh4+6xU>j$p*-cv?4Y5zxX`s|RKpD!GQ>Ui+;d(BMm2TEJIWvzU5FFn4iuIe zPWRq>udBOqnQNBS!R>O<5ur6CHaZC-a2c&8$OGitYH>y#WPrx+LpOrxCN7HmFh;jb zz^#4CP`7#1^M0nnuAvLVp{;hz+t16_6k}a#>s5i z!Bs!<43}K9eg&vh$Rf{rz_yz>yp)$iN%-U$!8`WEB(?xf6~* z&b4aU(w`M;=PaJE9^$kM8S>B+55rL(e&klITH{|B?v^muHD39e-&HfSX$`HojPW2E zIMzHr3M~Y*eMe*rJOS-_qG>;xt|LIBj$j>c!)mwn&EfuIA)2k!DY3siwxO-enr5rE z_Q*@FnZ;_^dySK5>)25_m2#5x78#ioqVXY^&=J(?hDZHlm{m`?-0fOA$L*T^h1)fK zqAOgz7#2S|kfo>UxrhfSWZ@KIPyhi?p73Xb#Me*4Q7WJa;oqCKFIC@svpe(5Gd*Zb zN0h|~ICwR!tE|tk9~p(TbYaK;!V51{?4H?$w@xc|IrB!iMNLn1>(g7o9f2F$^?CqV zQ$4`3(2xb(c-r0#(!RjEb<14Q+|S+a#WP%z#kqk{Xfr1IOE-nI4LXiEOQ78(NVa3u zqihL!-pHkzYpwo-p7wb-x4meaFQ6X@lOT-4)VOW-6lY7cf21VIuD7xqv~(Fqp6iO% zEO&+TzH)^#Cc2_!v;AHh1G4r~7I`|s(MZ(vZFlzl)Tv1O})LZ4%LCGVIBQD;1?zzXe4H-BNEm+^1)~V*Iu6oza-MYxlJLpt!rC@AS zS{NIl-vbh0_sIiH|1e(xYEoiSaz}0D#jGBWAPfTt2*i*(CXI4Q%?|OS)juj?orh;*f=0>f%h3(QrORAC!)30T?NXObca@8GdLXMbZs2udx!`sh`k^QFX&^~o z(rPm_Iq8PJ#I3DOEzi1=t*J&#Xn*j*O|5VSJvH7*Acb*+_+&eeEnGCiB{b_01JW)J z3{Xa`)e!+~VEZThpjD~s%DSB3$~vFm%C~KFiA$!rw3+{MDJ$ogylDMC%&rNu?PHR1 zD69I_Xwmi;UVr`d?y}1+^ZGHu7zvbrvu2*L6&Wy<4tjy6IMozm0+ zADx9WWoCh@1?yeI*>Ah5*>)+l#n#{1<6ON7e|HU+PI7rE#jZikYTjlH7RoRxnckU6 z@W@oCHYm-k2~D21h)3~|m$nxb6;HJX)4pN)1+mu2w%FRD;@d+*C;*tm5k?$gqy>EO z%t@~N*vtG$vIoxd9$=*U={Xw7jA%{Od$MY{g!X;imragv&wX&MTe|97*Ry9&$2v(5 zSEJM*=@X`*;h^>C(ZemUk7kS?Ki=z%@!6QMvyOKke)ypueHaiv^?dk{i46pT%F>~s zV*?u*&OZ3%Hroh(XVmMiR`sf`RQ$Q+ zS2;p^OvTD3&}*aTFHBIrJ=a?yM8XtOk>Uywlv-@3NvjsR(t6GO)a!x57_n)%V(K-U zn_e*>8M%093Z1KxQRHUS?c-|9ALHiCnd3JthaY~pJLHfg`aoU{Mz0GmywJ^< zF~i@^f}a_NkrFx%{6F~M1HUN?4^se)k%c^5SRcFcu3fu&-=|NXip|*e4d1#ZxoK|L zW6${STxfSsd2A>?2*MSoX1e0M_8z2Y>WzUG12Lijs7;5l&6Ee#@|lh`H3M*AZY`Jg z$us`e8`p^6e*3MPJbAKv@4fe&eFo02L!35YG#V=dD2z0Uewl8^jvec-IpOCpd)b}0Vv(U8yo~Pof{{l$%u^c()i#C7ql}#LNRyv#=K$80t+rl2$Mll|STuSHi{L%X1Mqf7|Zs7 z~>zPG#0BHaG9(YOR~&HzgQ_HH~@zgiR0+HACaNl2OLm zi{YC$Z|*w)`a)+UGFoH^?mt530$-g3K-F%(BWQQ2DyDmF3PU?c7IlOUo6rI6sLspR zwJmkwB!jxbj&UG)DnrMhOlWg2(0)`_p`T$4N2&u<7_xP(6iZk1UeXA~hf@=ZQlYPO z#&}m;tGUIa>2$xqDvw^ZPkb-HiT0Sv)>>`d9t-)X6>A;9pc@SY1nT9;5hHSG!L-Ws z4A20ZmzU?JO`GOY^3!PfYF`N*riLCik&g?@iJCeUh()mY=fTY)TvV^_wmOc z`|{{4JE<&n;*g;@JUG<q?l#FfE$OQ$KYXlmF}gT7^p-5l9mv~NlPGM z;=IXjPrr-(+u9|XPHi*-F6$=k(8x4WG*t&9*_82*qa>MP3HD^*wpuM+)%ElI8pr-8)*fnX-cZA#9r>qKC$8%H_?rL|cS+Rc}+#aC*CT zyVNU3BbY+T7r@+Qfi69{AlEKb`?q53bM>naq`MA-Di7?8Cz=|eeq?M0Rp_hNR z+HL7@oZD$ryX_Gx)=fWZ%|5&+Ox*ta2d@D$iAOyRNbh5553GFxAbrDJms}8mL~o}K zdMCY~=@(;R5Yf@eo`iJ$`t|c8mFXFN>8UmlQU*F}E@>`Xn8I<;Lyy7Y)1oQ#1?@+& z*_17}vtr2?sNzE&&f5)xm{T1-5lc(YkfyTKjhBNLv)i|n@AV_q8ee3iEd!b94({hbRI(G>f1&UHqN<_Jl$5CJg93kXtT;sF^t9f3_2?c|H$6AQ- zC*Z<3d2+}FD0E~NvBUL>vdB_7Lb*_;Xp|REd>kINA(Thwu!qA7tql)G8>NKAokq-t zSx!PpV;JSB5n;Y)8TRr>-ziVHH(FlgN(|UUdygb~*M-qZJO-*YI05hsOr~2O0=DJj z6KoW(v`+-*WY|M!yVrV_ z=?KgOY?xSE(T`arv>7@AylAp7bmHO66!M4ykWG&dkW&GqQk)um@epGX&o(uq*|kSE987e)s44iW80;Ino;uUJL<^2iii% zLB$CtoZ#Ml_gybnmmjo)wzIRw0We33fCN}?zx}owHoc+i&~&BiZF=@^TitbSUflqT z-Y?2ZXJ&}5Sy=+ufYDjdgE*mViC)x4h!dR1Q3QoNz3tk4^!XnZ^pUK+26Rs+8yPVl~;3{%5vOyyAs?s12M_|v}JCR zUHsdtVD)NeyDp9Dxo*v>xZbU++f(OzHxy+h_C$aQw(sFueNhdeK4D`O=LP^%D*6Kg zvkxOS+$2fYbIv)(KQGJ_iSgiPG|3k5(NQ_IV!fsAwYlwGc8w}-(&_>?asFa=_oyYV zeZxwwXUl5t*!HztzjpjZsa#i7xZ7pe?7}9FQLfIS8IUv{nF3IH5z-zU`S{Q&Egte> zc-f*Afok2wEr%F-F`@)?fgLXhKIOrO<2DzYkA(6fw{h&#u2ai4u4CIauGF5@Ey=8I zH0gX;FgKs7EU{L=2r>c=<6ZuQbO;?zq$gkd`5=Q4&fVT}lMrw0R;bc0`U z!W(bA(VchRd49U11F#m#@S$wt)L-7HgG)$HbG0+mT|%vF8`WiQ#->6y?Vros!(&#s zfi`llAK1VRI4Ik7Xk5#!S=+$h>*QKpQ?TR;%+RLFQz+Y#Mqkp>A3G>+WbCrc*vkA7 zlKolBde)ndR{ExTZTA4NzRxaLL2Qg*x!aKwm~Nnpp0`T1KdfLQ+P^t&uViH8*c4qY%cWD%c6tfkc-Emi@Yb;4|U^255q7I9@6#(9N&Z(X%DYW_n_L}jVZCu z%U-It%U}!}9vXtUfE0)dRfh8L&=VOw>@F+kWVyKu7Q5wZzq7|so!hw89_z4UiX?k1 z)in3Ys~*bZXb3L85uO#Hl3ni2C8e%+UWTiZR_4B* z_DzLe*h^0OE3LNv)U-MVwzjt4YG>Z-?Te}9<@Pk);*!#m0vaDyLYzt{sKQjHv_g1f zAo68Q;y4V(LtBj69lHzsMfvR6v;7ke-24W3Mgzt}htQz|@+3b@i^h`@T;t~D2>#pcg9zP+KnMrk9h#K0>xUt(WliPEX|%?FF8rMg1fSh?&B zSFNdi?$0K|(tV> z`Gox_Pi@4;<`$Xv^SO2?hH1$(6W9*rB@9j+4UVTl$0!&~`BIWJj!^mJAsa(+UzAZx zdd!$H{-U01MW#WfNG>68OoKQ9hz^QFN9KbMKInTZGXZ%x_{2*GQJc^Q9`Q*}(fGS; z7him_8$Nuv*PY86^rxO}b=tb3tmvktuOV`)>afEO^N00ZQ$iQel{vONs2j-CO-zP{of0*CG7MJwE1ET z=iUjqW$x1*iEc>$6WyFo-tl0?Mwg`dy68aYfSx#b(4G3_$b%NPi8`#T;kWNdE!(_l z(+BoNmJ$>owY}Q*Y(ixSUmGW36yH|ka@eoEW z2LL!Vma| zwc(7Ghs^{o`8W@Zg~Nso^I&U~`pj59apY4c9S4V6v;%!`((6FsJ$K#Zet+eao{w)1 zCuUai@8GL_e129fB~-KZwKaQ*)#t;{h-GKIDJ##%(T#Ogve1Wip|5E0NLTVjCoTs+ z1IaqwEPIM@i_yJGnttIcwH@%d%%qGCtV5wd3JV12q;aYUg+jo{g9lz26&em&$O|8G z*l_|VhvE1yzx>iqgFK$e2C8x6CieZJs{Tcz`)njJnpsEVN9DhaT#9KZnDNEseX|hpt#o;1-y4VA3&5TAZXO1#yk+QX8#BnU!57TT)76 zyL8!+`eiTVNe}EoTzRrLG&yD<+t`h_bj2vy2UP3z&)aKpe4EFf3*NgqB90)0$|F?9 zpi(IaT~7H*6RNxvi!aB92@tiBV$`l!zRVrb{V>;~O*8km4<`C!H?Bw3SjmmAhcxxz zciE0MHN}j_*V1CN9||dZ?X}ms$usA<`SztW|K^%aG#)q)8itL~gNE~AkO%0>D@e1? z*cySUTr-Adz<97^6Z9jG(8~|(Pg(41e-)#A=gwWvTmF7QEuTMc-a>mCZh@^)EfFl? z3gbb74oyn=nu8xdLTq}#g*@?!k}t)HGgGi;ax0AE#sv!(xtTL(xrb^ua*J#V+t}#> zn@epY5xZyWKViqIlz+rG}V zKBS8qYtM7ptAh4NVysg`kAbC87y%dMS(P!TksSeBU?$Jl^_`sw7x+B@)9-Q`>sC!<}n%Cp_FlZW{!+?1=Z zo^QGRL>7qY9upQbO9gL&P2Z{O*Vt)$bdQ&{5Jy`DB5g(|<&h5!Cp(ibXEjUA*{-C~LDqh1His=@g)Qn`G;)oOVzGSXu_kBk zSnEn{wqVmo{j`lR)J672pyHv;iQ_3#Y@emGPXCy(R!qH=+Xqx*wlA_JY_N^Wcr(ZV z3di>%3W-J>9vsHPQCWPxKq6l~PyF#T%6o;)xEL7zlBS(pV(&BkO?LPr9t#DmZGZre zO;Gf)ji_Vs5lFtffU5{&dU|5)M_|%<_?v6oisKp>hYq*~Z{6Mt%)^4jE zR0S<&h%8|`M3E>oHfEKYc2!np5540glep}G9c2^I6p}}qLr2;$9dG(>Kunmo52&$> z65CBZWTSNeT2YaJix&((`BH{-$U`|s9Lf=AgopVm7f#P=2&XRaCZ?vl;&bou7NcF> zQ%|fe)6PDWGqb>CG;7bD6~e?8PN%5b4J)EwIbXfyFK?JmBcEtfv~8lyr&?Wm>5AJEhIToVFmKX6oj=khvSk>@ zR-q>^w3*W2V+Z)-EWOVtCI5RP)r@JjNGP_E@@QgG(v$YAi|?sw9EEVCF^u8@&=X?$ ziW5rFkQN_@hY^ZgI!D4`$Jv)CI{InXV`l{-Y#4X+|0qo!0P-a=WJF&ki$cGq+P%h9 zzRPM(qk+-MG{}3Z8ll`|;4M22Lo`K(?V=M@n)s3{Yu3q?)ylJu=S4=-t{}PCQpb(Bz7KH72ahm_+5S-@u{OlCfFpAI8>!@!+Dp4H6z$o=b0JJf;(P2=U~{)51LEV`$bjWS7;>cS)ySk9c3d2he^1uwtaf(&Uj5eTfV( zZG%S|fH|kLQB*lCYO3nsT9~zS=FFM?wjIE73B{cxc%&b?$TLNAB$@K}oA?`;u@P!v zI6{eAy^P$7QCqm(KC#2MEuw=2wO6*0{Rr{YCmV-0r=yW)ooj*J-Fm@Vz0U>-GvM|M zstE>tJL508M{5!5o<^HODWOpGut)h?><1n-LbNa>pDB-!hGbp-a5NGD&KTL~AeXoW zQCw*WGK2E%T@R=km8rMLu3xil{%cf)NvXuIot#E-50(eHM~@!uM<$m|j9Ti)`MQuF z=K;2gO{d8(-{E)09=zmes%58~VsRf@+)v8}aMGL!el0~7P94T4Vn5U?51--+VUsS_ z>1>n1Sw>9Rm<$E`1vQpgYQ6Z?l9J-D!%G+`rV2u^C6rM401c1Ip@;HBgP&;^M}u?D z`GZT$@$b(XFS2}A4A2;`MuJSru=5E&Au~FS;DNP*yY`g12368rp8b`IBKw;$Tz_)8 z!U$!DtBsHVML!vxc)Ujw%2ZxsBX8EH(J1vJ)2=VAUS7fUe;6SaXSBN66Dd~V;yX8; zSWfoAZa9V5inxu|FKo~As%7mh~Ld~Z!vmI*hz__g&019hwk^tGS>6;L@ODWP(N zAy~wfR!F0CuM~c!733l-?ckm+z1wmAc_1t5K})cc9J7%J*W>49Ml`fauy=2umviES zZZVJSQu`8Uqk8tYZIX-Kf+gSDBQ=Zs8p?fKZXmD$!iNt1)HdRwgO0w0g)iLUD&@C! z2~}!ED}2Q|N@s{ll@-}d|M^o~5|6!@EZQg+pN5W&LXhE+4XtdEbtu-P1CCN;{Ln}x zpPlgJJw-)tQW5jHCt5{R22FJG!i}+Ck-F@tZ&52>`q9v%O3D`01`lY zFoD+M&?-W>AP|t}<3s>AMxd}gQgTSWG`DNxN;hrBEH`D!6#pFw9ya5&iYZ@4Q>dAR zH1TjY5)b;48omN-H8tT{6Xieo)b?F9ZC{r@f9gyV(vhoRW3e83@*gk;o z3GLg{JlEcz9|YAZqgxekSik=FCXkEViV9RwsDNlPgz~}$scJPu>nQ0u*VsC0?FiRT zK%!}k#Yi4HM0(hTlJAv19TV)QU?Tu*L9sn~P%YcFOW)`|`{HYVo;B zr*@F1HZU^rO4BBEubya!B>x;yv5qqRde8c5@siKp^VjF_Q(mEDk!E>Qs5(`j^6WjC zwe}9~4VM3dqm=SL2r3L_>@r(#Hd`6Sda;uuwY zHBY_VrRN_M1JKIHWO(3Wz%uYi`#hg7a0wxp$5}|as4&$HsA)Uat&811?CuWhCP#Ga za2XZxo}#ozBS!Hs4NY`r9e_>za+E7yHq(z(ZIT$ZNqg*-%LP*r>&y5^>__b;#3?N> zL%L;`+v(At>{4sH)%}B`6j?tCDoo}|Z43Rpf$$CqRV*M0L!|&R-V0FmJPdLN`9_Gq^y7Fhrp9j%ExMena@Rd&nH&Dee_ge1-P((d^rO?RFK9nM2~?P^5)S*f+In=M#osqW_y>nj z2BRFv(EtpJ3wcqR#X$in&Lq?r=oI>L0g)VYo92)7ctkTLO9s#Sm4|-lD<0CJgO9wB zpL{^U(|Hp}0_9#H6X1f!Rm-haa0R>e=6cBQL5C=m5r z5q>PRN*R_Z_RYYjY}0YJjDQ@xlqJMNLvh~N=BYq7Dk=6^*~M$t+Fxa==IUK_mmL;l z`Fo+fdCsTqz^KGdf{6322v0XT#r9cJfaE>bVzU@w(7ROuGl%9ED{mkNer6`a%Y*DV=UF)xKw&j(%#q6ebKSBhII2XoQTwI;%%N zHIh_b@?v!n>|+elG#t4R2}`umSIJ(X z_{fy$Oc`Xw%Oj1lfJ*Phljb@Rh4S+9_L=ga$%lFfX!4LL9y$cm9+wuJ3=xti7q5@# zKNS8@`LKRuOTI$n#?zIjk*T&w2k4^N#%Rjw)vE^DF8wE6zJ$6;-oG_cD+(thB-v40 zReKnFtc}=q&{0s05FeqG7L9b+7&VxDKu6h7VWp9+xMYQ)@EoIP%3$s0NDpLu6t^bsE(n5a2yf`FMJKTJ;Dd z(yB{&Y9DmP4==aP%^}$Q2B%*2&Bam)&c!MP5_}dWkY$&lO6&Ry7yP2&&gegBgi2S{t2E&+0;(5ez}gy{W8l7K$_@w{K|T$VF+)X&hiQ0m zG+J~TuQ+*OoHP#E(8F@#BUIfHcl3)+;wO{~`NbnZkOQyyp{pLzkRyK4lva6o$g@q+ z$98OanysNbEd8?pMTY7oF87Opia@Kt{*Z4cW6%zuM9F0}O zp@quI5SpS@=7&O+C!~Dn!g}KMA{~~cTsU=ya)?V7q3RKhe90G0`dFIl(C6%~%jI?n z^rO36WbMyM*D&uF1r@1|@bOT=FfL=M0O?Sc=#<$X zUHJ;(k$lDXSC%}1p|WA9x)dreJ`Ek3IBF8VC((5ItTEMwxg+k|%noWK3p7S<*64C@;Rufzm3YeCmvM@BpYl zjqh0ES3YUU32D$NtM*&oO1sg0p^eZ_EsHlIe(*Y!@;~HMXUOxbfJy~c8J0@27o95G zCC^hfb)IOA^Yzi_P?-b8WqcWww0Ma_S6YoyI^98#-M+l(g*@40a+YsG0bLNa^jr<=? zx5y2h+OQ7|<$i5v75h)FT5s3%*4E!ev`3XLRvC?=&9O5ZR~{Dc@Xo)ab&y4LC9i7xGCmoe0{MD!5urgm^q=g69ZU~%imq0h0 zFZ2!4Ot9BIRaYKmR{oN3@*X{2^C5O$DP8HE&8W8hI-bfv}r zLm?dqClFOubrXh8^{FoLS^1eJ>rn&qMdJs|Uwo2!1ic#Vf?b-djrddQ~P z@y7aJ0~5V)`)m9EIjE6pUO5nCT29W(%d2Uh+WEa1@I+I(nS~L$K_g`J5D3ZoPeU1s z5cx_Y*XlJ=`63J7wzuLQTfTfbkIwQS&96GmQuqE`sGIVCGoVT#LQ@oQnVOTEHf`F% zHdQ=f(Z}d*jOItM8iUb8Z}}A?4*G$d%7-CwdC7^%U_{O~AjjFw?|;~{!}Bd4Aemyn zzb!scrN07Q`iG)_lb}jLQd`!VcPK4UMIq`6?FY>(F@k_}g5RW$5yke+hYkW}9Kd?XEQzUukRQ0^7NMWv|@x zwG+T&6#DSD0;1`&kBdyQ56LC)MX~>1olS!p$pSkJiQ^PTspwbpG9e!D!m!-zBA%$k kZ}gYfNaCF}xV$|1>H6z0+kD + + +settings/main_icon/05_wallpaper copy +Created with Sketch. + + + + + + + + diff --git a/d2d_app/client/invited.html b/d2d_app/client/invited.html new file mode 100644 index 0000000..332e212 --- /dev/null +++ b/d2d_app/client/invited.html @@ -0,0 +1,31 @@ + + + + + + + My Device App + + + + + + + + +
+
+
+
+
+
+

Would you like to join the room?

+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/d2d_app/client/js/actions.js b/d2d_app/client/js/actions.js new file mode 100644 index 0000000..b158f2c --- /dev/null +++ b/d2d_app/client/js/actions.js @@ -0,0 +1,58 @@ +const serverPort = 9000; +const serverURL = window.location.protocol + '//' + window.location.hostname; + +class Actions { + /** + * Launch App on TV + * This method creates function for onclick listener + * @param {string} appPkgID + * @param {string} appAppID + * @param {Function} callback + * @returns {Function} + */ + + launchAppOnTV(appPkgID, appAppID, callback) { + const xhr = new XMLHttpRequest(); + + var self = this; + var retFunc = function() { + var data = { + appPkgID: appPkgID, + appAppID: appAppID + }; + self.sendDataToApp(appAppID, data, callback); + }; + return retFunc; + }; + + /** + * Send data to host + * @param {string} appID + * @param {Object} data + * @param {Function} callback + */ + sendDataToApp(appID, data, callback) { + const xhr = new XMLHttpRequest(); + // add tv app id + data.appAppID = appID; + data.appPkgID = appID.replace(/\..+$/, ""); + + xhr.onreadystatechange = function() { + if (xhr.readyState === xhr.DONE) { + if (xhr.status === 200 || xhr.status === 201) { + var response = JSON.parse(xhr.responseText); + if (typeof callback === "function") { + callback(response); + } + } else { + console.error(xhr.responseText); + } + } + } + xhr.open('POST', serverURL + ':' + serverPort + '/app'); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.send(JSON.stringify(data)); + }; +} + +export default Actions; diff --git a/d2d_app/client/js/app.js b/d2d_app/client/js/app.js new file mode 100644 index 0000000..d717a9a --- /dev/null +++ b/d2d_app/client/js/app.js @@ -0,0 +1,513 @@ +import Storage from "./clipping-storage.js"; +import Actions from './actions.js'; +import { openAppWindow } from './myApps.js'; + +const moduleapp = {}; + +(function () { + "use strict"; + var tau = window.tau, + HomeApp = function () { + this.version = "0.1"; + this.appsList = []; + }, + prototype = HomeApp.prototype, + storage = new Storage(), + actions = new Actions(), + appsList = [], + socket = null, + homeApp; + + const defaultList = [], + getAppsList = new Promise((resolve, reject) => { + const requestURL = "client/updateWebclip"; + + fetch(requestURL) + .then((response) => response.json()) + .then((response) => { + //addWSListener(data.wsPort); + resolve(response.data.apps); + }) + .catch((e) => { + reject(e); + }) + }); + + function updateAppsList(message) { + if (message.type === "full") { + return updateAppsListFull(message.data); + } else if (message.type === "diff") { + updateAppsListDiff(message.data); + return true; + } else { + console.warn("app.js: unsupported type of applist."); + } + return false; + } + + function updateAppsListDiff(apps) { + apps.forEach(function (remoteApp) { + if (remoteApp.action === "add") { // add (or update if app already added) + let localApp = appsList.filter(function (localApp) { + return remoteApp.appID === localApp.appID; + })[0]; + delete remoteApp.action; + + if (!localApp) { // add new + appsList.push(remoteApp); + } else { // update local app + /** + * @todo + * Which properties we need update + */ + localApp.isActive = remoteApp.isActive; + } + } else if (remoteApp.action === "remove") { // remove local app + appsList = appsList.filter(function (localApp) { + return remoteApp.appID !== localApp.appID; + }); + } else { + console.warn("Unsupported action:", remoteApp.action); + } + + }); + + updateOrderOfApplist(); + } + + function updateOrderOfApplist() { + var change = false, + currentOrder = ""; + + currentOrder = appsList.reduce(function (prev, app) { + return prev + app.appID; + }, ""); + + // check apps order + appsList = appsList.sort(function (app1, app2) { + return (app1.isActive) ? + (app2.isActive) ? 0 : -1 : 1 + }); + + // order has been changed + if (currentOrder !== appsList.reduce(function (prev, app) { + return prev + app.appID; + }, "")) { + change = true; + } + + return change; + } + + function updateAppsListFull(apps) { + var change = false, + appsCount = appsList.length; + + // remove app from local apps list if not exists on remote host + appsList = appsList.filter(function (localApp) { + return apps.some(function (remoteApp) { + return remoteApp.appID === localApp.appID; + }); + }); + + if (appsCount !== appsList.length) { + change = true; + } + + // filter app which should be add to local apps list + const added = apps.filter(function (remoteApp) { + return !appsList.some(function (localApp) { + return localApp.appID === remoteApp.appID; + }); + }); + + if (added.length) { + change = true; + } + + // add apps to local apps list + added.forEach(function (remoteApp) { + appsList.push(remoteApp); + }); + + // update active items + appsList.forEach(function (localApp) { + apps.forEach(function (remoteApp) { + if (remoteApp.appID === localApp.appID) { + if (localApp.isActive !== remoteApp.isActive) { + localApp.isActive = remoteApp.isActive; + change = true; + } + } + }) + }); + + if (updateOrderOfApplist()) { + change = true; + }; + + return change; + } + function onWSMessage(message) { + if (updateAppsList(message)) { + tau.log("change"); + storage.refreshStorage(Storage.elements.APPSLIST, appsList); + + updateWebClipsUI(); + updateWebClipListPopup(); + } else { + tau.log("nothing change"); + } + } + async function getManifests() { + const promisesList = [], + indexesList = []; + + let responses = []; + + appsList.forEach(function (app, appIndex) { + app.webClipsList.forEach(function (webClip, webClipIndex) { + promisesList.push( + fetch(webClip.url + "\\manifest.json") + ); + indexesList.push({ appIndex: appIndex, webClipIndex: webClipIndex }); + }); + }); + + responses = await Promise.allSettled(promisesList); + + for (let responseIndex = 0; responseIndex < responses.length; responseIndex++) { + const response = responses[responseIndex]; + + if (response.status === "rejected" || !response.value.ok) { + appsList[indexesList[responseIndex].appIndex].webClipsList.splice(indexesList[responseIndex].webClipIndex, 1); + } else { + const contentPromise = await response.value.json(); + + appsList[indexesList[responseIndex].appIndex].webClipsList[indexesList[responseIndex].webClipIndex].manifest = contentPromise; + } + } + } + + function changeTheme(event) { + tau.theme.setTheme(event.target.value); + } + + function onPopupSubmit() { + appsList.forEach(function (app) { + app.webClipsList.forEach(function (webclip) { + const webClipName = getWebClipName(webclip.url), + checkbox = document.getElementById("popup-checkbox-" + webClipName); + + webclip.isSelected = checkbox.checked; + }) + }); + storage.refreshStorage(Storage.elements.APPSLIST, appsList); + + updateWebClipsUI(); + tau.history.back(); + } + + /** + * Click button event handler + * Opens drawer + */ + function onButtonClick() { + var drawerWidget = tau.widget.Drawer(document.querySelector(".ui-drawer")); + + drawerWidget.open(); + } + function onDone(result) { + console.log("onDone", result); + } + function createWebClipCard(webClip, appID) { + var card = document.createElement("div"), + webClipUrl = webClip.url; + + // add slash for name of webClip + if (!webClipUrl.match(/\/$/)) { + webClipUrl += "/"; + } + webClipUrl += "webclip.html"; + + card.classList.add("ui-card"); + card.setAttribute("data-src", webClipUrl); + card.addEventListener("webclip-message", function (ev) { + if (ev.detail.remoteui) + actions.sendDataToApp(appID, ev.detail, openAppWindow); + else + actions.sendDataToApp(appID, ev.detail, onDone); + }); + + return card; + } + + + homeApp = new HomeApp(); + + prototype.createControlCard = function (data) { + var controlCard = document.createElement("div"), + title = document.createElement("span"), + icon = document.createElement("div"), + img = document.createElement("img"), + a = document.createElement("a"); + + controlCard.classList.add("ui-content-area"); + icon.classList.add("ui-icon"); + title.classList.add("ui-title"); + title.textContent = data.title; + img.src = data.icon; + a.href = data.href || "#next-control"; + a.setAttribute("data-style", "flat"); + a.setAttribute("data-inline", true); + a.setAttribute("data-icon", "next"); + a.classList.add("ui-btn"); + + icon.appendChild(img); + + controlCard.appendChild(icon); + controlCard.appendChild(title); + controlCard.appendChild(a); + + return controlCard; + } + + prototype.addControlCard = function (data) { + var controlCard = this.createControlCard(data), + appBarElement = document.querySelector(".ui-page-active header"), + appBar = tau.widget.Appbar(appBarElement); + + controlCard.setAttribute("data-title", data.title); + + appBar.addInstantContainer(controlCard); + } + + prototype.removeControlCard = function (card) { + var appBarElement = document.querySelector(".ui-page-active header"), + appBar = tau.widget.Appbar(appBarElement); + + appBar.removeInstantContainer(card); + } + + function updateWebClipsUI() { + var webclipsContainer = document.getElementById("web-clips"), + // get Cards elements and convert NodeList to array + currentWebClipsCards = [].slice.call(webclipsContainer.querySelectorAll(".ui-card[data-url],.ui-card[data-src]")), + // list of webClips url in order + webClipsUrlList = appsList.reduce(function (prev, app) { + return prev.concat( + app.webClipsList.filter((webClip) => webClip.isSelected) + .map((webClip) => webClip.url)); + }, []); + + // remove card + currentWebClipsCards.forEach(function (card) { + const found = webClipsUrlList.filter(function (webClipUrl) { + return card.dataset.url && card.dataset.url.indexOf(webClipUrl) > -1 || + card.dataset.src && card.dataset.src.indexOf(webClipUrl) > -1; + }); + + // remove card from UI if not exists on list + if (found.length === 0) { + card.parentElement.removeChild(card); + } + }); + + // add card + appsList.forEach(function (app) { + app.webClipsList.forEach((webClip) => { + const found = currentWebClipsCards.filter(function (card) { + return card.dataset.url && card.dataset.url.indexOf(webClip.url) > -1 || + card.dataset.src && card.dataset.src.indexOf(webClip.url) > -1; + }); + + if (found.length === 0) { + if (webClip.isSelected) { + webclipsContainer.appendChild( + createWebClipCard(webClip, app.appID) + ); + } + } + }); + }); + + // set proper order of cards + // @todo change inline styles to css class after merge HomeApp branches + webclipsContainer.style.display = "flex"; + webclipsContainer.style.flexDirection = "column"; + currentWebClipsCards = [].slice.call(webclipsContainer.querySelectorAll(".ui-card[data-url],.ui-card[data-src]")); + + webClipsUrlList.forEach(function (url, order) { + const card = currentWebClipsCards.filter(function (card) { + return card.dataset.url && card.dataset.url.indexOf(url) > -1 || + card.dataset.src && card.dataset.src.indexOf(url) > -1; + })[0]; + + if (card) { + card.style.order = order; + } + }); + + // add/remove mini control cards + appsList.forEach(function (app) { + app.webClipsList.forEach((webClip) => { + if (webClip.manifest && webClip.manifest.cardType === "control") { + if (webClip.isSelected) { + if (!document.querySelector("[data-title='" + webClip.manifest.description + "']")) { + homeApp.addControlCard({ + title: webClip.manifest.description, + href: "#open-control-card", + icon: "images/Icon.png" + } + ); + } + } else if (document.querySelector("[data-title='" + webClip.manifest.description + "']")) { + // remove mini controll card + homeApp.removeControlCard(document.querySelector("[data-title='" + webClip.manifest.description + "']")); + } + } + }); + }); + + tau.engine.createWidgets(webclipsContainer); + } + + //TODO: provide mechanism for getting web clip name from webClip meta data + // and separate from getting ID + function getWebClipName(webClip) { + // remove all text to the last \ + return webClip.replace(/.*\//, ""); + } + + function updateWebClipListPopup() { + + var popupList = document.getElementById("popup-list"); + + // remove previous li items + while (popupList.firstChild) { + popupList.firstChild.remove() + } + + appsList.forEach(function (app) { + app.webClipsList.forEach(function (webclip) { + var li = document.createElement("li"), + input = document.createElement("input"), + label = document.createElement("label"), + webClipName = getWebClipName(webclip.url); + + li.classList.add("ui-li-has-checkbox"); + li.classList.add("ui-group-index"); + + input.setAttribute("type", "checkbox"); + input.setAttribute("id", "popup-checkbox-" + webClipName); + + label.setAttribute("for", "popup-checkbox-" + webClipName); + label.classList.add("ui-li-text"); + label.innerHTML = webclip.manifest && webclip.manifest.description || webClipName; + + li.appendChild(input); + li.appendChild(label); + popupList.appendChild(li); + }); + }); + + tau.engine.createWidgets(popupList); + + appsList.forEach(function (app) { + app.webClipsList.forEach(function (webclip) { + if (webclip.isSelected) { + const webClipName = getWebClipName(webclip.url), + checkbox = document.getElementById("popup-checkbox-" + webClipName); + + if (checkbox) { + checkbox.checked = true; + } + } + }); + }); + } + + function init() { + var themeChanger = document.querySelector("#theme-selector"), + page = document.querySelector(".ui-page"), + themeChangerButton = page.querySelector("#selector-opener"), + burgerButton = page.querySelector(".app-btn-icon-burger"), + popupButton = page.querySelector("#popup-submit"); + + themeChanger.addEventListener("change", changeTheme); + + themeChangerButton.addEventListener("vclick", function () { + var dropdownmenuWidget = tau.widget.DropdownMenu(themeChanger); + + dropdownmenuWidget.open(); + }); + + burgerButton.addEventListener("click", onButtonClick); + popupButton.addEventListener("click", onPopupSubmit); + + // use apps list from storage or default apps list if sth wrong + appsList = storage.readAllFromStorage(Storage.elements.APPSLIST); + + // check webclips on remote server + getAppsList.then((apps) => { + updateAppsListFull(apps); + }).catch((e) => { + console.warn("Error getting app lits: " + e.message); + if (appsList.length === 0) { + updateAppsListFull(defaultList); + } + }).finally(() => { + // check webclips access + getManifests().then(() => { + storage.refreshStorage(Storage.elements.APPSLIST, appsList); + updateWebClipsUI(); + updateWebClipListPopup(); + }); + }); + } + + function onPageBeforeShow(event) { + if (event.target.id === "main") { + init(); + } + } + + /** + * Map array of D2D apps to webclip list + * @param {Array} dataApps + */ + function d2dAppsToWebClipsList(dataApps) { + var result = []; + var webclips = []; + + dataApps.forEach(function (app) { + webclips = []; + if (app.webclip && app.webclip.manifest) { + webclips.push({ + url: 'client/webclip/' + app.webclip.manifest.name, + isSelected: true + }); + } + result.push({ + appID: app.d2dApp.appAppID, + pkgID: app.d2dApp.appPkgID, + isInstalled: true, + isActive: false, + webClipsList: webclips + }); + }); + return result; + } + + document.addEventListener("pagebeforeshow", onPageBeforeShow); + moduleapp.onWSMessage = onWSMessage; + moduleapp.d2dAppsToWebClipsList = d2dAppsToWebClipsList; +}()); + +export function UpdateWebClip(message) { + var data = { + type: "full", + data: moduleapp.d2dAppsToWebClipsList(message) + } + moduleapp.onWSMessage(data); +}; diff --git a/d2d_app/client/js/client.js b/d2d_app/client/js/client.js index ea2b591..3e1a6a1 100755 --- a/d2d_app/client/js/client.js +++ b/d2d_app/client/js/client.js @@ -1,134 +1,5 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -"use strict"; - -const serverPort = 9000; -const serverURL = window.location.protocol + '//' + window.location.hostname; -(function() { - var xhr ; - function emptyElement(elm) { - while (elm.firstChild) { - elm.removeChild(elm.firstChild); - } - return elm; - } - - function showListView(dataArray) { - var objResult = emptyElement(document.querySelector("#detail-main")), - objTable, - objRow, - objCol, - i, - prop; - - objTable = document.createElement("div"); - objTable.className = "result-table"; - - if (dataArray.length > 0) { - for (i = 0; i < dataArray.length; i++) { - objRow = document.createElement("div"); - - objRow.className = "result-table-row"; - for (prop in dataArray[i]) { - if (dataArray[i].hasOwnProperty(prop)) { - objCol = document.createElement("div"); - objCol.className = prop + "-detail"; - if (dataArray[i][prop].hasOwnProperty("appName")) { - objCol.appendChild(document.createTextNode(dataArray[i][prop].appName)); - } - objCol.addEventListener("click", sendAppID(dataArray[i][prop].appPkgID, dataArray[i][prop].appAppID)); - objRow.appendChild(objCol); - } - } - objTable.appendChild(objRow); - } - } else { - objRow = document.createElement("div"); - objRow.className = "result-table-error"; - objRow.appendChild(document.createTextNode("No Data")); - objTable.appendChild(objRow); - } - - objResult.appendChild(objTable); - } - - function showList() { - xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function() { - if (xhr.readyState === xhr.DONE) { - if (xhr.status === 200 || xhr.status === 201) { - showListView(JSON.parse(xhr.responseText)); - } else { - console.error(xhr.responseText); - } - } - }; - xhr.open('GET', serverURL + ':' + serverPort + '/appList'); - xhr.send(); - } - - function sendAppID(appPkgID, appAppID) { - var retFunc = function() { - var data = { - appPkgID: appPkgID, - appAppID: appAppID - }; - xhr.onreadystatechange = function() { - if (xhr.readyState === xhr.DONE) { - if (xhr.status === 200 || xhr.status === 201) { - var res = JSON.parse(xhr.responseText); - document.getElementById("page-main").style.display = "none"; - document.getElementById("spinner-main").style.display = "block"; - var timer = setTimeout(function(){ - clearTimeout(timer); - document.getElementById("page-main").style.display = "block"; - document.getElementById("spinner-main").style.display = "none"; - window.open(serverURL + ':' + res.port + '/app', 'newWindow'); - }, 1000); - } else { - console.error(xhr.responseText); - } - } - } - xhr.open('POST', serverURL + ':' + serverPort + '/app'); - xhr.setRequestHeader('Content-Type', 'application/json'); - xhr.send(JSON.stringify(data)); - }; - return retFunc; - } - - function init() { - var eventSource = new EventSource(serverURL + ':' + serverPort + '/updateAppList'); - eventSource.addEventListener('message', evt => { - showListView(JSON.parse(evt.data)); - }, false); - eventSource.addEventListener('open', evt => { - console.log("Connected to..."); - }, false); - eventSource.addEventListener('error', evt => { - if (evt.target.readyState == EventSource.CLOSED) { - console.log("Disconnected from..."); - } else if (evt.target.readyState == EventSource.CONNECTING) { - console.log('Connecting to...'); - } - }, false); - showList(); - } - - /** +(function () { + /** * Back key event handler */ window.addEventListener("tizenhwkey", function (ev) { @@ -156,7 +27,4 @@ const serverURL = window.location.protocol + '//' + window.location.hostname; } } }); - - window.onload = init; }()); - diff --git a/d2d_app/client/js/clipping-storage.js b/d2d_app/client/js/clipping-storage.js new file mode 100644 index 0000000..02af624 --- /dev/null +++ b/d2d_app/client/js/clipping-storage.js @@ -0,0 +1,24 @@ +class Storage { + constructor() { + this.appsList = JSON.parse(localStorage.getItem("appsList")) || []; + } + + refreshStorage(element, data = []) { + this[element] = data; + localStorage.setItem(element, JSON.stringify(this[element])); + } + + writeToStorage(element, link) { + this[element].push(link); + localStorage.setItem(element, JSON.stringify(this[element])); + } + + readAllFromStorage(element) { + return this[element]; + } + +} + +Storage.elements = {APPSLIST: "appsList"}; + +export default Storage; \ No newline at end of file diff --git a/d2d_app/client/js/control.js b/d2d_app/client/js/control.js new file mode 100644 index 0000000..79f82ec --- /dev/null +++ b/d2d_app/client/js/control.js @@ -0,0 +1,211 @@ +const KeyCode = { + BACK: 9, + _1: 10, + _2: 11, + _3: 12, + _4: 13, + _5: 14, + _6: 15, + _7: 16, + _8: 17, + _9: 18, + _0: 19, + RETURN: 36, + HOME: 71, + VOLUME_DOWN: 75, + VOLUME_UP: 76, + CHANNEL_DOWN: 95, + CHANNEL_UP: 96, + UP: 111, + LEFT: 113, + RIGHT: 114, + DOWN: 116, + //POWER: 124, + EXIT: 182, +}; + +var websocket; + +(function () { + var page = document.getElementById("open-control-app-1"); + + function onPageShow() { + var x = window.innerWidth / 2; + var y = window.innerHeight / 2; + + var id; + var SERVER = -1; + var link = document.location.href; + var pkgId = "2FUI52kIJP"; + var wsUri = "ws://" + link.split("/")[2] + "/" + pkgId; + + websocket = new WebSocket(wsUri); + websocket.onmessage = function(evt) { + var json = JSON.parse(evt.data); + if (json.id == SERVER && json.type == "id") + id = json.data; + }; + + function sendMessage(type, data) { + var packet = {type: type, data: data, id: id}; + websocket.send(JSON.stringify(packet)); + } + + var volup= page.querySelector(".app-btn-icon-volume-up"), + voldown= page.querySelector(".app-btn-icon-volume-down"), + channelup= page.querySelector(".app-btn-icon-channel-up"), + channeldown= page.querySelector(".app-btn-icon-channel-down"), + up= page.querySelector(".app-4way-btn-up"), + down= page.querySelector(".app-4way-btn-down"), + right= page.querySelector(".app-4way-btn-right"), + left= page.querySelector(".app-4way-btn-left"), + enter= page.querySelector(".app-btn-enter"), + home= page.querySelector(".app-btn-home"), + backward= page.querySelector(".app-btn-backward"), + touchpad= page.querySelector(".app-4way-touchpad"), + num1 = page.querySelector(".app-num-pad-1"), + num2 = page.querySelector(".app-num-pad-2"), + num3 = page.querySelector(".app-num-pad-3"), + num4 = page.querySelector(".app-num-pad-4"), + num5 = page.querySelector(".app-num-pad-5"), + num6 = page.querySelector(".app-num-pad-6"), + num7 = page.querySelector(".app-num-pad-7"), + num8 = page.querySelector(".app-num-pad-8"), + num9 = page.querySelector(".app-num-pad-9"), + num0 = page.querySelector(".app-num-pad-0"), + mediaProgress = page.querySelector(".app-media-progress input"), + progressHandler = page.querySelector(".app-media-progress .ui-slider-handler"), + labelMin = page.querySelector(".app-media-progress .ui-slider-label-min"), + labelMax = page.querySelector(".app-media-progress .ui-slider-label-max"); + + volup.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.VOLUME_UP}); + }); + voldown.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.VOLUME_DOWN}); + }); + channelup.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.CHANNEL_UP}); + }); + channeldown.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.CHANNEL_DOWN}); + }); + up.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.UP}); + }); + down.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.DOWN}); + }); + right.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.RIGHT}); + }); + left.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.LEFT}); + }); + enter.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.RETURN}); + }); + backward.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.BACK}); + }); + home.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode.HOME}); + }); + num1.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._1}); + }); + num2.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._2}); + }); + num3.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._3}); + }); + num4.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._4}); + }); + num5.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._5}); + }); + num6.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._6}); + }); + num7.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._7}); + }); + num8.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._8}); + }); + num9.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._9}); + }); + num0.addEventListener("click", function () { + sendMessage("keypress", {keycode: KeyCode._0}); + }); + + var ontouch = function (ev) { + switch (ev.type) { + case "click" : + sendMessage("click"); + break; + case "touchstart" : + x = ev.touches[0].pageX; + y = ev.touches[0].pageY; + break; + case "touchmove" : + ev.stopPropagation(); + // lock the default web engine behaviour eg. scrolling + ev.preventDefault(); + sendMessage("touchmove", {x: ev.touches[0].pageX - x, y: ev.touches[0].pageY - y}); + x = ev.touches[0].pageX; + y = ev.touches[0].pageY; + break; + case "touchend" : + break; + } + }, + onProgressTouchmove = function (ev) { + // lock the section change event listener + ev.stopPropagation(); + }, + toTimeString = function (value) { + return Math.floor(value / 60) + ":" + + ((value % 60 < 10) ? ("0" + value % 60) : value % 60); + }, + onProgressInput = function () { + progressHandler.setAttribute("data-value", toTimeString(this.value)); + }; + + tau.event.on(touchpad, ["click", "touchstart", "touchmove", "touchend"], ontouch); + tau.event.on(mediaProgress, ["touchmove"], onProgressTouchmove); + tau.event.on(mediaProgress, ["input"], onProgressInput); + + // update slider labels + labelMin.innerText = toTimeString(mediaProgress.min); + labelMax.innerText = toTimeString(mediaProgress.max); + progressHandler.setAttribute("data-value", toTimeString(mediaProgress.value)); + }; + + function onPageHide() { + websocket.close(); + if (volup) volup.removeEventListener("click"); + if (voldown) voldown.removeEventListener("click"); + if (channelup) channelup.removeEventListener("click"); + if (channeldown) channeldown.removeEventListener("click"); + if (up) up.removeEventListener("click"); + if (down) down.removeEventListener("click"); + if (right) right.removeEventListener("click"); + if (left) left.removeEventListener("click"); + if (enter) enter.removeEventListener("click"); + if (backward) backward.removeEventListener("click"); + if (home) home.removeEventListener("click"); + if (touchpad) { + touchpad.removeEventListener("click"); + touchpad.removeEventListener("touchstart"); + touchpad.removeEventListener("touchmove"); + touchpad.removeEventListener("touchend"); + } + }; + + page.addEventListener("pagebeforeshow", onPageShow); + page.addEventListener("pagebeforehide", onPageHide); +}()); \ No newline at end of file diff --git a/d2d_app/client/js/invited.js b/d2d_app/client/js/invited.js new file mode 100755 index 0000000..a0130ed --- /dev/null +++ b/d2d_app/client/js/invited.js @@ -0,0 +1,131 @@ +"use strict"; +import Actions from './actions.js'; + +const serverPort = 9000; +const serverURL = window.location.protocol + '//' + window.location.hostname; +const actions = new Actions(); +const NEW_WINDOW_TIMEOUT = 1000; +const myappsmodule = {}; + +(function () { + var xhr; + function emptyElement(elm) { + while (elm.firstChild) { + elm.removeChild(elm.firstChild); + } + return elm; + } + /** + * Open app in new window + * @param {Object} response + * @private + */ + function openAppWindow(response) { + document.getElementById("page-invited").style.display = "none"; + var timer = setTimeout(function () { + clearTimeout(timer); + document.getElementById("page-invited").style.display = "block"; + window.open(serverURL + ':' + response.port + '/app', 'newWindow'); + }, NEW_WINDOW_TIMEOUT); + }; + + function showListView(dataArray) { + var formResult = document.getElementById("d2dApps"), + imgResult = document.getElementById("d2dAppList"), + formObj, + imgObj, + textObj, + objTable, + objRow, + i, + d2dApp, + icon; + + emptyElement(imgResult); + + objTable = document.createElement("div"); + objTable.className = "result-table"; + + if (dataArray.length > 0) { + for (i = 0; i < dataArray.length; i++) { + if (dataArray[i]['d2dApp'].appName === 'Watch Together') { + formObj = document.createElement("div"); + imgObj = document.createElement("img"); + textObj = document.createElement("p"); + formObj.style.textAlign = "center"; + d2dApp = dataArray[i]['d2dApp']; + if (d2dApp.hasOwnProperty("appName")) { + if (d2dApp.iconPath) { + icon = d2dApp.iconPath.substring(d2dApp.iconPath.indexOf('/', 10) + 1); + imgObj.src = `/d2dIcon/${icon}`; + } else { + imgObj.src = `./images/icon.png`; + } + imgObj.className = "app-icon-big-img"; + imgObj.alt = d2dApp.appName; + textObj.style.display = "block"; + textObj.style.marginBottom = "60px"; + textObj.style.fontSize = "16px"; + textObj.innerHTML = d2dApp.appName; + } + imgObj.addEventListener("click", actions.launchAppOnTV( + d2dApp.appPkgID, + d2dApp.appAppID, + function (response) { + openAppWindow(response); + })); + formObj.appendChild(imgObj); + formObj.appendChild(textObj); + + imgResult.appendChild(formObj); + } + } + formResult.appendChild(imgResult); + } else { + objRow = document.createElement("div"); + objRow.className = "result-table-error"; + objRow.appendChild(document.createTextNode("No Data")); + objTable.appendChild(objRow); + } + } + + function showList() { + xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === xhr.DONE) { + if (xhr.status === 200 || xhr.status === 201) { + showListView(JSON.parse(xhr.responseText)); + } else { + console.error(xhr.responseText); + } + } + }; + xhr.open('GET', serverURL + ':' + serverPort + '/appList'); + xhr.send(); + } + + function init() { + var eventSource = new EventSource(serverURL + ':' + serverPort + '/updateAppList'); + eventSource.addEventListener('message', evt => { + showListView(JSON.parse(evt.data)); + }, false); + eventSource.addEventListener('open', evt => { + console.log("Connected to..."); + }, false); + eventSource.addEventListener('error', evt => { + if (evt.target.readyState == EventSource.CLOSED) { + console.log("Disconnected from..."); + } else if (evt.target.readyState == EventSource.CONNECTING) { + console.log('Connecting to...'); + } + }, false); + showList(); + } + window.onload = init; + myappsmodule.openAppWindow = openAppWindow; +}()); + +export function openAppWindow(response) { + myappsmodule.openAppWindow(response); +}; + diff --git a/d2d_app/client/js/jsencrypt.js b/d2d_app/client/js/jsencrypt.js new file mode 100644 index 0000000..de5a14f --- /dev/null +++ b/d2d_app/client/js/jsencrypt.js @@ -0,0 +1,5371 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.JSEncrypt = {}))); +}(this, (function (exports) { 'use strict'; + +var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"; +function int2char(n) { + return BI_RM.charAt(n); +} +//#region BIT_OPERATIONS +// (public) this & a +function op_and(x, y) { + return x & y; +} +// (public) this | a +function op_or(x, y) { + return x | y; +} +// (public) this ^ a +function op_xor(x, y) { + return x ^ y; +} +// (public) this & ~a +function op_andnot(x, y) { + return x & ~y; +} +// return index of lowest 1-bit in x, x < 2^31 +function lbit(x) { + if (x == 0) { + return -1; + } + var r = 0; + if ((x & 0xffff) == 0) { + x >>= 16; + r += 16; + } + if ((x & 0xff) == 0) { + x >>= 8; + r += 8; + } + if ((x & 0xf) == 0) { + x >>= 4; + r += 4; + } + if ((x & 3) == 0) { + x >>= 2; + r += 2; + } + if ((x & 1) == 0) { + ++r; + } + return r; +} +// return number of 1 bits in x +function cbit(x) { + var r = 0; + while (x != 0) { + x &= x - 1; + ++r; + } + return r; +} +//#endregion BIT_OPERATIONS + +var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var b64pad = "="; +function hex2b64(h) { + var i; + var c; + var ret = ""; + for (i = 0; i + 3 <= h.length; i += 3) { + c = parseInt(h.substring(i, i + 3), 16); + ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63); + } + if (i + 1 == h.length) { + c = parseInt(h.substring(i, i + 1), 16); + ret += b64map.charAt(c << 2); + } + else if (i + 2 == h.length) { + c = parseInt(h.substring(i, i + 2), 16); + ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4); + } + while ((ret.length & 3) > 0) { + ret += b64pad; + } + return ret; +} +// convert a base64 string to hex +function b64tohex(s) { + var ret = ""; + var i; + var k = 0; // b64 state, 0-3 + var slop = 0; + for (i = 0; i < s.length; ++i) { + if (s.charAt(i) == b64pad) { + break; + } + var v = b64map.indexOf(s.charAt(i)); + if (v < 0) { + continue; + } + if (k == 0) { + ret += int2char(v >> 2); + slop = v & 3; + k = 1; + } + else if (k == 1) { + ret += int2char((slop << 2) | (v >> 4)); + slop = v & 0xf; + k = 2; + } + else if (k == 2) { + ret += int2char(slop); + ret += int2char(v >> 2); + slop = v & 3; + k = 3; + } + else { + ret += int2char((slop << 2) | (v >> 4)); + ret += int2char(v & 0xf); + k = 0; + } + } + if (k == 1) { + ret += int2char(slop << 2); + } + return ret; +} + +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ +/* global Reflect, Promise */ + +var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +} + +// Hex JavaScript decoder +// Copyright (c) 2008-2013 Lapo Luchini +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ +var decoder; +var Hex = { + decode: function (a) { + var i; + if (decoder === undefined) { + var hex = "0123456789ABCDEF"; + var ignore = " \f\n\r\t\u00A0\u2028\u2029"; + decoder = {}; + for (i = 0; i < 16; ++i) { + decoder[hex.charAt(i)] = i; + } + hex = hex.toLowerCase(); + for (i = 10; i < 16; ++i) { + decoder[hex.charAt(i)] = i; + } + for (i = 0; i < ignore.length; ++i) { + decoder[ignore.charAt(i)] = -1; + } + } + var out = []; + var bits = 0; + var char_count = 0; + for (i = 0; i < a.length; ++i) { + var c = a.charAt(i); + if (c == "=") { + break; + } + c = decoder[c]; + if (c == -1) { + continue; + } + if (c === undefined) { + throw new Error("Illegal character at offset " + i); + } + bits |= c; + if (++char_count >= 2) { + out[out.length] = bits; + bits = 0; + char_count = 0; + } + else { + bits <<= 4; + } + } + if (char_count) { + throw new Error("Hex encoding incomplete: 4 bits missing"); + } + return out; + } +}; + +// Base64 JavaScript decoder +// Copyright (c) 2008-2013 Lapo Luchini +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ +var decoder$1; +var Base64 = { + decode: function (a) { + var i; + if (decoder$1 === undefined) { + var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var ignore = "= \f\n\r\t\u00A0\u2028\u2029"; + decoder$1 = Object.create(null); + for (i = 0; i < 64; ++i) { + decoder$1[b64.charAt(i)] = i; + } + for (i = 0; i < ignore.length; ++i) { + decoder$1[ignore.charAt(i)] = -1; + } + } + var out = []; + var bits = 0; + var char_count = 0; + for (i = 0; i < a.length; ++i) { + var c = a.charAt(i); + if (c == "=") { + break; + } + c = decoder$1[c]; + if (c == -1) { + continue; + } + if (c === undefined) { + throw new Error("Illegal character at offset " + i); + } + bits |= c; + if (++char_count >= 4) { + out[out.length] = (bits >> 16); + out[out.length] = (bits >> 8) & 0xFF; + out[out.length] = bits & 0xFF; + bits = 0; + char_count = 0; + } + else { + bits <<= 6; + } + } + switch (char_count) { + case 1: + throw new Error("Base64 encoding incomplete: at least 2 bits missing"); + case 2: + out[out.length] = (bits >> 10); + break; + case 3: + out[out.length] = (bits >> 16); + out[out.length] = (bits >> 8) & 0xFF; + break; + } + return out; + }, + re: /-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/, + unarmor: function (a) { + var m = Base64.re.exec(a); + if (m) { + if (m[1]) { + a = m[1]; + } + else if (m[2]) { + a = m[2]; + } + else { + throw new Error("RegExp out of sync"); + } + } + return Base64.decode(a); + } +}; + +// Big integer base-10 printing library +// Copyright (c) 2014 Lapo Luchini +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ +var max = 10000000000000; // biggest integer that can still fit 2^53 when multiplied by 256 +var Int10 = /** @class */ (function () { + function Int10(value) { + this.buf = [+value || 0]; + } + Int10.prototype.mulAdd = function (m, c) { + // assert(m <= 256) + var b = this.buf; + var l = b.length; + var i; + var t; + for (i = 0; i < l; ++i) { + t = b[i] * m + c; + if (t < max) { + c = 0; + } + else { + c = 0 | (t / max); + t -= c * max; + } + b[i] = t; + } + if (c > 0) { + b[i] = c; + } + }; + Int10.prototype.sub = function (c) { + // assert(m <= 256) + var b = this.buf; + var l = b.length; + var i; + var t; + for (i = 0; i < l; ++i) { + t = b[i] - c; + if (t < 0) { + t += max; + c = 1; + } + else { + c = 0; + } + b[i] = t; + } + while (b[b.length - 1] === 0) { + b.pop(); + } + }; + Int10.prototype.toString = function (base) { + if ((base || 10) != 10) { + throw new Error("only base 10 is supported"); + } + var b = this.buf; + var s = b[b.length - 1].toString(); + for (var i = b.length - 2; i >= 0; --i) { + s += (max + b[i]).toString().substring(1); + } + return s; + }; + Int10.prototype.valueOf = function () { + var b = this.buf; + var v = 0; + for (var i = b.length - 1; i >= 0; --i) { + v = v * max + b[i]; + } + return v; + }; + Int10.prototype.simplify = function () { + var b = this.buf; + return (b.length == 1) ? b[0] : this; + }; + return Int10; +}()); + +// ASN.1 JavaScript decoder +var ellipsis = "\u2026"; +var reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; +var reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; +function stringCut(str, len) { + if (str.length > len) { + str = str.substring(0, len) + ellipsis; + } + return str; +} +var Stream = /** @class */ (function () { + function Stream(enc, pos) { + this.hexDigits = "0123456789ABCDEF"; + if (enc instanceof Stream) { + this.enc = enc.enc; + this.pos = enc.pos; + } + else { + // enc should be an array or a binary string + this.enc = enc; + this.pos = pos; + } + } + Stream.prototype.get = function (pos) { + if (pos === undefined) { + pos = this.pos++; + } + if (pos >= this.enc.length) { + throw new Error("Requesting byte offset " + pos + " on a stream of length " + this.enc.length); + } + return ("string" === typeof this.enc) ? this.enc.charCodeAt(pos) : this.enc[pos]; + }; + Stream.prototype.hexByte = function (b) { + return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF); + }; + Stream.prototype.hexDump = function (start, end, raw) { + var s = ""; + for (var i = start; i < end; ++i) { + s += this.hexByte(this.get(i)); + if (raw !== true) { + switch (i & 0xF) { + case 0x7: + s += " "; + break; + case 0xF: + s += "\n"; + break; + default: + s += " "; + } + } + } + return s; + }; + Stream.prototype.isASCII = function (start, end) { + for (var i = start; i < end; ++i) { + var c = this.get(i); + if (c < 32 || c > 176) { + return false; + } + } + return true; + }; + Stream.prototype.parseStringISO = function (start, end) { + var s = ""; + for (var i = start; i < end; ++i) { + s += String.fromCharCode(this.get(i)); + } + return s; + }; + Stream.prototype.parseStringUTF = function (start, end) { + var s = ""; + for (var i = start; i < end;) { + var c = this.get(i++); + if (c < 128) { + s += String.fromCharCode(c); + } + else if ((c > 191) && (c < 224)) { + s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F)); + } + else { + s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F)); + } + } + return s; + }; + Stream.prototype.parseStringBMP = function (start, end) { + var str = ""; + var hi; + var lo; + for (var i = start; i < end;) { + hi = this.get(i++); + lo = this.get(i++); + str += String.fromCharCode((hi << 8) | lo); + } + return str; + }; + Stream.prototype.parseTime = function (start, end, shortYear) { + var s = this.parseStringISO(start, end); + var m = (shortYear ? reTimeS : reTimeL).exec(s); + if (!m) { + return "Unrecognized time: " + s; + } + if (shortYear) { + // to avoid querying the timer, use the fixed range [1970, 2069] + // it will conform with ITU X.400 [-10, +40] sliding window until 2030 + m[1] = +m[1]; + m[1] += (+m[1] < 70) ? 2000 : 1900; + } + s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4]; + if (m[5]) { + s += ":" + m[5]; + if (m[6]) { + s += ":" + m[6]; + if (m[7]) { + s += "." + m[7]; + } + } + } + if (m[8]) { + s += " UTC"; + if (m[8] != "Z") { + s += m[8]; + if (m[9]) { + s += ":" + m[9]; + } + } + } + return s; + }; + Stream.prototype.parseInteger = function (start, end) { + var v = this.get(start); + var neg = (v > 127); + var pad = neg ? 255 : 0; + var len; + var s = ""; + // skip unuseful bits (not allowed in DER) + while (v == pad && ++start < end) { + v = this.get(start); + } + len = end - start; + if (len === 0) { + return neg ? -1 : 0; + } + // show bit length of huge integers + if (len > 4) { + s = v; + len <<= 3; + while (((+s ^ pad) & 0x80) == 0) { + s = +s << 1; + --len; + } + s = "(" + len + " bit)\n"; + } + // decode the integer + if (neg) { + v = v - 256; + } + var n = new Int10(v); + for (var i = start + 1; i < end; ++i) { + n.mulAdd(256, this.get(i)); + } + return s + n.toString(); + }; + Stream.prototype.parseBitString = function (start, end, maxLength) { + var unusedBit = this.get(start); + var lenBit = ((end - start - 1) << 3) - unusedBit; + var intro = "(" + lenBit + " bit)\n"; + var s = ""; + for (var i = start + 1; i < end; ++i) { + var b = this.get(i); + var skip = (i == end - 1) ? unusedBit : 0; + for (var j = 7; j >= skip; --j) { + s += (b >> j) & 1 ? "1" : "0"; + } + if (s.length > maxLength) { + return intro + stringCut(s, maxLength); + } + } + return intro + s; + }; + Stream.prototype.parseOctetString = function (start, end, maxLength) { + if (this.isASCII(start, end)) { + return stringCut(this.parseStringISO(start, end), maxLength); + } + var len = end - start; + var s = "(" + len + " byte)\n"; + maxLength /= 2; // we work in bytes + if (len > maxLength) { + end = start + maxLength; + } + for (var i = start; i < end; ++i) { + s += this.hexByte(this.get(i)); + } + if (len > maxLength) { + s += ellipsis; + } + return s; + }; + Stream.prototype.parseOID = function (start, end, maxLength) { + var s = ""; + var n = new Int10(); + var bits = 0; + for (var i = start; i < end; ++i) { + var v = this.get(i); + n.mulAdd(128, v & 0x7F); + bits += 7; + if (!(v & 0x80)) { // finished + if (s === "") { + n = n.simplify(); + if (n instanceof Int10) { + n.sub(80); + s = "2." + n.toString(); + } + else { + var m = n < 80 ? n < 40 ? 0 : 1 : 2; + s = m + "." + (n - m * 40); + } + } + else { + s += "." + n.toString(); + } + if (s.length > maxLength) { + return stringCut(s, maxLength); + } + n = new Int10(); + bits = 0; + } + } + if (bits > 0) { + s += ".incomplete"; + } + return s; + }; + return Stream; +}()); +var ASN1 = /** @class */ (function () { + function ASN1(stream, header, length, tag, sub) { + if (!(tag instanceof ASN1Tag)) { + throw new Error("Invalid tag value."); + } + this.stream = stream; + this.header = header; + this.length = length; + this.tag = tag; + this.sub = sub; + } + ASN1.prototype.typeName = function () { + switch (this.tag.tagClass) { + case 0: // universal + switch (this.tag.tagNumber) { + case 0x00: + return "EOC"; + case 0x01: + return "BOOLEAN"; + case 0x02: + return "INTEGER"; + case 0x03: + return "BIT_STRING"; + case 0x04: + return "OCTET_STRING"; + case 0x05: + return "NULL"; + case 0x06: + return "OBJECT_IDENTIFIER"; + case 0x07: + return "ObjectDescriptor"; + case 0x08: + return "EXTERNAL"; + case 0x09: + return "REAL"; + case 0x0A: + return "ENUMERATED"; + case 0x0B: + return "EMBEDDED_PDV"; + case 0x0C: + return "UTF8String"; + case 0x10: + return "SEQUENCE"; + case 0x11: + return "SET"; + case 0x12: + return "NumericString"; + case 0x13: + return "PrintableString"; // ASCII subset + case 0x14: + return "TeletexString"; // aka T61String + case 0x15: + return "VideotexString"; + case 0x16: + return "IA5String"; // ASCII + case 0x17: + return "UTCTime"; + case 0x18: + return "GeneralizedTime"; + case 0x19: + return "GraphicString"; + case 0x1A: + return "VisibleString"; // ASCII subset + case 0x1B: + return "GeneralString"; + case 0x1C: + return "UniversalString"; + case 0x1E: + return "BMPString"; + } + return "Universal_" + this.tag.tagNumber.toString(); + case 1: + return "Application_" + this.tag.tagNumber.toString(); + case 2: + return "[" + this.tag.tagNumber.toString() + "]"; // Context + case 3: + return "Private_" + this.tag.tagNumber.toString(); + } + }; + ASN1.prototype.content = function (maxLength) { + if (this.tag === undefined) { + return null; + } + if (maxLength === undefined) { + maxLength = Infinity; + } + var content = this.posContent(); + var len = Math.abs(this.length); + if (!this.tag.isUniversal()) { + if (this.sub !== null) { + return "(" + this.sub.length + " elem)"; + } + return this.stream.parseOctetString(content, content + len, maxLength); + } + switch (this.tag.tagNumber) { + case 0x01: // BOOLEAN + return (this.stream.get(content) === 0) ? "false" : "true"; + case 0x02: // INTEGER + return this.stream.parseInteger(content, content + len); + case 0x03: // BIT_STRING + return this.sub ? "(" + this.sub.length + " elem)" : + this.stream.parseBitString(content, content + len, maxLength); + case 0x04: // OCTET_STRING + return this.sub ? "(" + this.sub.length + " elem)" : + this.stream.parseOctetString(content, content + len, maxLength); + // case 0x05: // NULL + case 0x06: // OBJECT_IDENTIFIER + return this.stream.parseOID(content, content + len, maxLength); + // case 0x07: // ObjectDescriptor + // case 0x08: // EXTERNAL + // case 0x09: // REAL + // case 0x0A: // ENUMERATED + // case 0x0B: // EMBEDDED_PDV + case 0x10: // SEQUENCE + case 0x11: // SET + if (this.sub !== null) { + return "(" + this.sub.length + " elem)"; + } + else { + return "(no elem)"; + } + case 0x0C: // UTF8String + return stringCut(this.stream.parseStringUTF(content, content + len), maxLength); + case 0x12: // NumericString + case 0x13: // PrintableString + case 0x14: // TeletexString + case 0x15: // VideotexString + case 0x16: // IA5String + // case 0x19: // GraphicString + case 0x1A: // VisibleString + // case 0x1B: // GeneralString + // case 0x1C: // UniversalString + return stringCut(this.stream.parseStringISO(content, content + len), maxLength); + case 0x1E: // BMPString + return stringCut(this.stream.parseStringBMP(content, content + len), maxLength); + case 0x17: // UTCTime + case 0x18: // GeneralizedTime + return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17)); + } + return null; + }; + ASN1.prototype.toString = function () { + return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? "null" : this.sub.length) + "]"; + }; + ASN1.prototype.toPrettyString = function (indent) { + if (indent === undefined) { + indent = ""; + } + var s = indent + this.typeName() + " @" + this.stream.pos; + if (this.length >= 0) { + s += "+"; + } + s += this.length; + if (this.tag.tagConstructed) { + s += " (constructed)"; + } + else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null)) { + s += " (encapsulates)"; + } + s += "\n"; + if (this.sub !== null) { + indent += " "; + for (var i = 0, max = this.sub.length; i < max; ++i) { + s += this.sub[i].toPrettyString(indent); + } + } + return s; + }; + ASN1.prototype.posStart = function () { + return this.stream.pos; + }; + ASN1.prototype.posContent = function () { + return this.stream.pos + this.header; + }; + ASN1.prototype.posEnd = function () { + return this.stream.pos + this.header + Math.abs(this.length); + }; + ASN1.prototype.toHexString = function () { + return this.stream.hexDump(this.posStart(), this.posEnd(), true); + }; + ASN1.decodeLength = function (stream) { + var buf = stream.get(); + var len = buf & 0x7F; + if (len == buf) { + return len; + } + // no reason to use Int10, as it would be a huge buffer anyways + if (len > 6) { + throw new Error("Length over 48 bits not supported at position " + (stream.pos - 1)); + } + if (len === 0) { + return null; + } // undefined + buf = 0; + for (var i = 0; i < len; ++i) { + buf = (buf * 256) + stream.get(); + } + return buf; + }; + /** + * Retrieve the hexadecimal value (as a string) of the current ASN.1 element + * @returns {string} + * @public + */ + ASN1.prototype.getHexStringValue = function () { + var hexString = this.toHexString(); + var offset = this.header * 2; + var length = this.length * 2; + return hexString.substr(offset, length); + }; + ASN1.decode = function (str) { + var stream; + if (!(str instanceof Stream)) { + stream = new Stream(str, 0); + } + else { + stream = str; + } + var streamStart = new Stream(stream); + var tag = new ASN1Tag(stream); + var len = ASN1.decodeLength(stream); + var start = stream.pos; + var header = start - streamStart.pos; + var sub = null; + var getSub = function () { + var ret = []; + if (len !== null) { + // definite length + var end = start + len; + while (stream.pos < end) { + ret[ret.length] = ASN1.decode(stream); + } + if (stream.pos != end) { + throw new Error("Content size is not correct for container starting at offset " + start); + } + } + else { + // undefined length + try { + for (;;) { + var s = ASN1.decode(stream); + if (s.tag.isEOC()) { + break; + } + ret[ret.length] = s; + } + len = start - stream.pos; // undefined lengths are represented as negative values + } + catch (e) { + throw new Error("Exception while decoding undefined length content: " + e); + } + } + return ret; + }; + if (tag.tagConstructed) { + // must have valid content + sub = getSub(); + } + else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) { + // sometimes BitString and OctetString are used to encapsulate ASN.1 + try { + if (tag.tagNumber == 0x03) { + if (stream.get() != 0) { + throw new Error("BIT STRINGs with unused bits cannot encapsulate."); + } + } + sub = getSub(); + for (var i = 0; i < sub.length; ++i) { + if (sub[i].tag.isEOC()) { + throw new Error("EOC is not supposed to be actual content."); + } + } + } + catch (e) { + // but silently ignore when they don't + sub = null; + } + } + if (sub === null) { + if (len === null) { + throw new Error("We can't skip over an invalid tag with undefined length at offset " + start); + } + stream.pos = start + Math.abs(len); + } + return new ASN1(streamStart, header, len, tag, sub); + }; + return ASN1; +}()); +var ASN1Tag = /** @class */ (function () { + function ASN1Tag(stream) { + var buf = stream.get(); + this.tagClass = buf >> 6; + this.tagConstructed = ((buf & 0x20) !== 0); + this.tagNumber = buf & 0x1F; + if (this.tagNumber == 0x1F) { // long tag + var n = new Int10(); + do { + buf = stream.get(); + n.mulAdd(128, buf & 0x7F); + } while (buf & 0x80); + this.tagNumber = n.simplify(); + } + } + ASN1Tag.prototype.isUniversal = function () { + return this.tagClass === 0x00; + }; + ASN1Tag.prototype.isEOC = function () { + return this.tagClass === 0x00 && this.tagNumber === 0x00; + }; + return ASN1Tag; +}()); + +// Copyright (c) 2005 Tom Wu +// Bits per digit +var dbits; +// JavaScript engine analysis +var canary = 0xdeadbeefcafe; +var j_lm = ((canary & 0xffffff) == 0xefcafe); +//#region +var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]; +var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; +//#endregion +// (public) Constructor +var BigInteger = /** @class */ (function () { + function BigInteger(a, b, c) { + if (a != null) { + if ("number" == typeof a) { + this.fromNumber(a, b, c); + } + else if (b == null && "string" != typeof a) { + this.fromString(a, 256); + } + else { + this.fromString(a, b); + } + } + } + //#region PUBLIC + // BigInteger.prototype.toString = bnToString; + // (public) return string representation in given radix + BigInteger.prototype.toString = function (b) { + if (this.s < 0) { + return "-" + this.negate().toString(b); + } + var k; + if (b == 16) { + k = 4; + } + else if (b == 8) { + k = 3; + } + else if (b == 2) { + k = 1; + } + else if (b == 32) { + k = 5; + } + else if (b == 4) { + k = 2; + } + else { + return this.toRadix(b); + } + var km = (1 << k) - 1; + var d; + var m = false; + var r = ""; + var i = this.t; + var p = this.DB - (i * this.DB) % k; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) > 0) { + m = true; + r = int2char(d); + } + while (i >= 0) { + if (p < k) { + d = (this[i] & ((1 << p) - 1)) << (k - p); + d |= this[--i] >> (p += this.DB - k); + } + else { + d = (this[i] >> (p -= k)) & km; + if (p <= 0) { + p += this.DB; + --i; + } + } + if (d > 0) { + m = true; + } + if (m) { + r += int2char(d); + } + } + } + return m ? r : "0"; + }; + // BigInteger.prototype.negate = bnNegate; + // (public) -this + BigInteger.prototype.negate = function () { + var r = nbi(); + BigInteger.ZERO.subTo(this, r); + return r; + }; + // BigInteger.prototype.abs = bnAbs; + // (public) |this| + BigInteger.prototype.abs = function () { + return (this.s < 0) ? this.negate() : this; + }; + // BigInteger.prototype.compareTo = bnCompareTo; + // (public) return + if this > a, - if this < a, 0 if equal + BigInteger.prototype.compareTo = function (a) { + var r = this.s - a.s; + if (r != 0) { + return r; + } + var i = this.t; + r = i - a.t; + if (r != 0) { + return (this.s < 0) ? -r : r; + } + while (--i >= 0) { + if ((r = this[i] - a[i]) != 0) { + return r; + } + } + return 0; + }; + // BigInteger.prototype.bitLength = bnBitLength; + // (public) return the number of bits in "this" + BigInteger.prototype.bitLength = function () { + if (this.t <= 0) { + return 0; + } + return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)); + }; + // BigInteger.prototype.mod = bnMod; + // (public) this mod a + BigInteger.prototype.mod = function (a) { + var r = nbi(); + this.abs().divRemTo(a, null, r); + if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) { + a.subTo(r, r); + } + return r; + }; + // BigInteger.prototype.modPowInt = bnModPowInt; + // (public) this^e % m, 0 <= e < 2^32 + BigInteger.prototype.modPowInt = function (e, m) { + var z; + if (e < 256 || m.isEven()) { + z = new Classic(m); + } + else { + z = new Montgomery(m); + } + return this.exp(e, z); + }; + // BigInteger.prototype.clone = bnClone; + // (public) + BigInteger.prototype.clone = function () { + var r = nbi(); + this.copyTo(r); + return r; + }; + // BigInteger.prototype.intValue = bnIntValue; + // (public) return value as integer + BigInteger.prototype.intValue = function () { + if (this.s < 0) { + if (this.t == 1) { + return this[0] - this.DV; + } + else if (this.t == 0) { + return -1; + } + } + else if (this.t == 1) { + return this[0]; + } + else if (this.t == 0) { + return 0; + } + // assumes 16 < DB < 32 + return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]; + }; + // BigInteger.prototype.byteValue = bnByteValue; + // (public) return value as byte + BigInteger.prototype.byteValue = function () { + return (this.t == 0) ? this.s : (this[0] << 24) >> 24; + }; + // BigInteger.prototype.shortValue = bnShortValue; + // (public) return value as short (assumes DB>=16) + BigInteger.prototype.shortValue = function () { + return (this.t == 0) ? this.s : (this[0] << 16) >> 16; + }; + // BigInteger.prototype.signum = bnSigNum; + // (public) 0 if this == 0, 1 if this > 0 + BigInteger.prototype.signum = function () { + if (this.s < 0) { + return -1; + } + else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) { + return 0; + } + else { + return 1; + } + }; + // BigInteger.prototype.toByteArray = bnToByteArray; + // (public) convert to bigendian byte array + BigInteger.prototype.toByteArray = function () { + var i = this.t; + var r = []; + r[0] = this.s; + var p = this.DB - (i * this.DB) % 8; + var d; + var k = 0; + if (i-- > 0) { + if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) { + r[k++] = d | (this.s << (this.DB - p)); + } + while (i >= 0) { + if (p < 8) { + d = (this[i] & ((1 << p) - 1)) << (8 - p); + d |= this[--i] >> (p += this.DB - 8); + } + else { + d = (this[i] >> (p -= 8)) & 0xff; + if (p <= 0) { + p += this.DB; + --i; + } + } + if ((d & 0x80) != 0) { + d |= -256; + } + if (k == 0 && (this.s & 0x80) != (d & 0x80)) { + ++k; + } + if (k > 0 || d != this.s) { + r[k++] = d; + } + } + } + return r; + }; + // BigInteger.prototype.equals = bnEquals; + BigInteger.prototype.equals = function (a) { + return (this.compareTo(a) == 0); + }; + // BigInteger.prototype.min = bnMin; + BigInteger.prototype.min = function (a) { + return (this.compareTo(a) < 0) ? this : a; + }; + // BigInteger.prototype.max = bnMax; + BigInteger.prototype.max = function (a) { + return (this.compareTo(a) > 0) ? this : a; + }; + // BigInteger.prototype.and = bnAnd; + BigInteger.prototype.and = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_and, r); + return r; + }; + // BigInteger.prototype.or = bnOr; + BigInteger.prototype.or = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_or, r); + return r; + }; + // BigInteger.prototype.xor = bnXor; + BigInteger.prototype.xor = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_xor, r); + return r; + }; + // BigInteger.prototype.andNot = bnAndNot; + BigInteger.prototype.andNot = function (a) { + var r = nbi(); + this.bitwiseTo(a, op_andnot, r); + return r; + }; + // BigInteger.prototype.not = bnNot; + // (public) ~this + BigInteger.prototype.not = function () { + var r = nbi(); + for (var i = 0; i < this.t; ++i) { + r[i] = this.DM & ~this[i]; + } + r.t = this.t; + r.s = ~this.s; + return r; + }; + // BigInteger.prototype.shiftLeft = bnShiftLeft; + // (public) this << n + BigInteger.prototype.shiftLeft = function (n) { + var r = nbi(); + if (n < 0) { + this.rShiftTo(-n, r); + } + else { + this.lShiftTo(n, r); + } + return r; + }; + // BigInteger.prototype.shiftRight = bnShiftRight; + // (public) this >> n + BigInteger.prototype.shiftRight = function (n) { + var r = nbi(); + if (n < 0) { + this.lShiftTo(-n, r); + } + else { + this.rShiftTo(n, r); + } + return r; + }; + // BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; + // (public) returns index of lowest 1-bit (or -1 if none) + BigInteger.prototype.getLowestSetBit = function () { + for (var i = 0; i < this.t; ++i) { + if (this[i] != 0) { + return i * this.DB + lbit(this[i]); + } + } + if (this.s < 0) { + return this.t * this.DB; + } + return -1; + }; + // BigInteger.prototype.bitCount = bnBitCount; + // (public) return number of set bits + BigInteger.prototype.bitCount = function () { + var r = 0; + var x = this.s & this.DM; + for (var i = 0; i < this.t; ++i) { + r += cbit(this[i] ^ x); + } + return r; + }; + // BigInteger.prototype.testBit = bnTestBit; + // (public) true iff nth bit is set + BigInteger.prototype.testBit = function (n) { + var j = Math.floor(n / this.DB); + if (j >= this.t) { + return (this.s != 0); + } + return ((this[j] & (1 << (n % this.DB))) != 0); + }; + // BigInteger.prototype.setBit = bnSetBit; + // (public) this | (1< 1) { + var g2 = nbi(); + z.sqrTo(g[1], g2); + while (n <= km) { + g[n] = nbi(); + z.mulTo(g2, g[n - 2], g[n]); + n += 2; + } + } + var j = e.t - 1; + var w; + var is1 = true; + var r2 = nbi(); + var t; + i = nbits(e[j]) - 1; + while (j >= 0) { + if (i >= k1) { + w = (e[j] >> (i - k1)) & km; + } + else { + w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); + if (j > 0) { + w |= e[j - 1] >> (this.DB + i - k1); + } + } + n = k; + while ((w & 1) == 0) { + w >>= 1; + --n; + } + if ((i -= n) < 0) { + i += this.DB; + --j; + } + if (is1) { // ret == 1, don't bother squaring or multiplying it + g[w].copyTo(r); + is1 = false; + } + else { + while (n > 1) { + z.sqrTo(r, r2); + z.sqrTo(r2, r); + n -= 2; + } + if (n > 0) { + z.sqrTo(r, r2); + } + else { + t = r; + r = r2; + r2 = t; + } + z.mulTo(r2, g[w], r); + } + while (j >= 0 && (e[j] & (1 << i)) == 0) { + z.sqrTo(r, r2); + t = r; + r = r2; + r2 = t; + if (--i < 0) { + i = this.DB - 1; + --j; + } + } + } + return z.revert(r); + }; + // BigInteger.prototype.modInverse = bnModInverse; + // (public) 1/this % m (HAC 14.61) + BigInteger.prototype.modInverse = function (m) { + var ac = m.isEven(); + if ((this.isEven() && ac) || m.signum() == 0) { + return BigInteger.ZERO; + } + var u = m.clone(); + var v = this.clone(); + var a = nbv(1); + var b = nbv(0); + var c = nbv(0); + var d = nbv(1); + while (u.signum() != 0) { + while (u.isEven()) { + u.rShiftTo(1, u); + if (ac) { + if (!a.isEven() || !b.isEven()) { + a.addTo(this, a); + b.subTo(m, b); + } + a.rShiftTo(1, a); + } + else if (!b.isEven()) { + b.subTo(m, b); + } + b.rShiftTo(1, b); + } + while (v.isEven()) { + v.rShiftTo(1, v); + if (ac) { + if (!c.isEven() || !d.isEven()) { + c.addTo(this, c); + d.subTo(m, d); + } + c.rShiftTo(1, c); + } + else if (!d.isEven()) { + d.subTo(m, d); + } + d.rShiftTo(1, d); + } + if (u.compareTo(v) >= 0) { + u.subTo(v, u); + if (ac) { + a.subTo(c, a); + } + b.subTo(d, b); + } + else { + v.subTo(u, v); + if (ac) { + c.subTo(a, c); + } + d.subTo(b, d); + } + } + if (v.compareTo(BigInteger.ONE) != 0) { + return BigInteger.ZERO; + } + if (d.compareTo(m) >= 0) { + return d.subtract(m); + } + if (d.signum() < 0) { + d.addTo(m, d); + } + else { + return d; + } + if (d.signum() < 0) { + return d.add(m); + } + else { + return d; + } + }; + // BigInteger.prototype.pow = bnPow; + // (public) this^e + BigInteger.prototype.pow = function (e) { + return this.exp(e, new NullExp()); + }; + // BigInteger.prototype.gcd = bnGCD; + // (public) gcd(this,a) (HAC 14.54) + BigInteger.prototype.gcd = function (a) { + var x = (this.s < 0) ? this.negate() : this.clone(); + var y = (a.s < 0) ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { + var t = x; + x = y; + y = t; + } + var i = x.getLowestSetBit(); + var g = y.getLowestSetBit(); + if (g < 0) { + return x; + } + if (i < g) { + g = i; + } + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + while (x.signum() > 0) { + if ((i = x.getLowestSetBit()) > 0) { + x.rShiftTo(i, x); + } + if ((i = y.getLowestSetBit()) > 0) { + y.rShiftTo(i, y); + } + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } + else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + } + if (g > 0) { + y.lShiftTo(g, y); + } + return y; + }; + // BigInteger.prototype.isProbablePrime = bnIsProbablePrime; + // (public) test primality with certainty >= 1-.5^t + BigInteger.prototype.isProbablePrime = function (t) { + var i; + var x = this.abs(); + if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { + for (i = 0; i < lowprimes.length; ++i) { + if (x[0] == lowprimes[i]) { + return true; + } + } + return false; + } + if (x.isEven()) { + return false; + } + i = 1; + while (i < lowprimes.length) { + var m = lowprimes[i]; + var j = i + 1; + while (j < lowprimes.length && m < lplim) { + m *= lowprimes[j++]; + } + m = x.modInt(m); + while (i < j) { + if (m % lowprimes[i++] == 0) { + return false; + } + } + } + return x.millerRabin(t); + }; + //#endregion PUBLIC + //#region PROTECTED + // BigInteger.prototype.copyTo = bnpCopyTo; + // (protected) copy this to r + BigInteger.prototype.copyTo = function (r) { + for (var i = this.t - 1; i >= 0; --i) { + r[i] = this[i]; + } + r.t = this.t; + r.s = this.s; + }; + // BigInteger.prototype.fromInt = bnpFromInt; + // (protected) set from integer value x, -DV <= x < DV + BigInteger.prototype.fromInt = function (x) { + this.t = 1; + this.s = (x < 0) ? -1 : 0; + if (x > 0) { + this[0] = x; + } + else if (x < -1) { + this[0] = x + this.DV; + } + else { + this.t = 0; + } + }; + // BigInteger.prototype.fromString = bnpFromString; + // (protected) set from string and radix + BigInteger.prototype.fromString = function (s, b) { + var k; + if (b == 16) { + k = 4; + } + else if (b == 8) { + k = 3; + } + else if (b == 256) { + k = 8; + /* byte array */ + } + else if (b == 2) { + k = 1; + } + else if (b == 32) { + k = 5; + } + else if (b == 4) { + k = 2; + } + else { + this.fromRadix(s, b); + return; + } + this.t = 0; + this.s = 0; + var i = s.length; + var mi = false; + var sh = 0; + while (--i >= 0) { + var x = (k == 8) ? (+s[i]) & 0xff : intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-") { + mi = true; + } + continue; + } + mi = false; + if (sh == 0) { + this[this.t++] = x; + } + else if (sh + k > this.DB) { + this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh; + this[this.t++] = (x >> (this.DB - sh)); + } + else { + this[this.t - 1] |= x << sh; + } + sh += k; + if (sh >= this.DB) { + sh -= this.DB; + } + } + if (k == 8 && ((+s[0]) & 0x80) != 0) { + this.s = -1; + if (sh > 0) { + this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; + } + } + this.clamp(); + if (mi) { + BigInteger.ZERO.subTo(this, this); + } + }; + // BigInteger.prototype.clamp = bnpClamp; + // (protected) clamp off excess high words + BigInteger.prototype.clamp = function () { + var c = this.s & this.DM; + while (this.t > 0 && this[this.t - 1] == c) { + --this.t; + } + }; + // BigInteger.prototype.dlShiftTo = bnpDLShiftTo; + // (protected) r = this << n*DB + BigInteger.prototype.dlShiftTo = function (n, r) { + var i; + for (i = this.t - 1; i >= 0; --i) { + r[i + n] = this[i]; + } + for (i = n - 1; i >= 0; --i) { + r[i] = 0; + } + r.t = this.t + n; + r.s = this.s; + }; + // BigInteger.prototype.drShiftTo = bnpDRShiftTo; + // (protected) r = this >> n*DB + BigInteger.prototype.drShiftTo = function (n, r) { + for (var i = n; i < this.t; ++i) { + r[i - n] = this[i]; + } + r.t = Math.max(this.t - n, 0); + r.s = this.s; + }; + // BigInteger.prototype.lShiftTo = bnpLShiftTo; + // (protected) r = this << n + BigInteger.prototype.lShiftTo = function (n, r) { + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << cbs) - 1; + var ds = Math.floor(n / this.DB); + var c = (this.s << bs) & this.DM; + for (var i = this.t - 1; i >= 0; --i) { + r[i + ds + 1] = (this[i] >> cbs) | c; + c = (this[i] & bm) << bs; + } + for (var i = ds - 1; i >= 0; --i) { + r[i] = 0; + } + r[ds] = c; + r.t = this.t + ds + 1; + r.s = this.s; + r.clamp(); + }; + // BigInteger.prototype.rShiftTo = bnpRShiftTo; + // (protected) r = this >> n + BigInteger.prototype.rShiftTo = function (n, r) { + r.s = this.s; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { + r.t = 0; + return; + } + var bs = n % this.DB; + var cbs = this.DB - bs; + var bm = (1 << bs) - 1; + r[0] = this[ds] >> bs; + for (var i = ds + 1; i < this.t; ++i) { + r[i - ds - 1] |= (this[i] & bm) << cbs; + r[i - ds] = this[i] >> bs; + } + if (bs > 0) { + r[this.t - ds - 1] |= (this.s & bm) << cbs; + } + r.t = this.t - ds; + r.clamp(); + }; + // BigInteger.prototype.subTo = bnpSubTo; + // (protected) r = this - a + BigInteger.prototype.subTo = function (a, r) { + var i = 0; + var c = 0; + var m = Math.min(a.t, this.t); + while (i < m) { + c += this[i] - a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + if (a.t < this.t) { + c -= a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while (i < a.t) { + c -= a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c -= a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c < -1) { + r[i++] = this.DV + c; + } + else if (c > 0) { + r[i++] = c; + } + r.t = i; + r.clamp(); + }; + // BigInteger.prototype.multiplyTo = bnpMultiplyTo; + // (protected) r = this * a, r != this,a (HAC 14.12) + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyTo = function (a, r) { + var x = this.abs(); + var y = a.abs(); + var i = x.t; + r.t = i + y.t; + while (--i >= 0) { + r[i] = 0; + } + for (i = 0; i < y.t; ++i) { + r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); + } + r.s = 0; + r.clamp(); + if (this.s != a.s) { + BigInteger.ZERO.subTo(r, r); + } + }; + // BigInteger.prototype.squareTo = bnpSquareTo; + // (protected) r = this^2, r != this (HAC 14.16) + BigInteger.prototype.squareTo = function (r) { + var x = this.abs(); + var i = r.t = 2 * x.t; + while (--i >= 0) { + r[i] = 0; + } + for (i = 0; i < x.t - 1; ++i) { + var c = x.am(i, x[i], r, 2 * i, 0, 1); + if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { + r[i + x.t] -= x.DV; + r[i + x.t + 1] = 1; + } + } + if (r.t > 0) { + r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); + } + r.s = 0; + r.clamp(); + }; + // BigInteger.prototype.divRemTo = bnpDivRemTo; + // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) + // r != q, this != m. q or r may be null. + BigInteger.prototype.divRemTo = function (m, q, r) { + var pm = m.abs(); + if (pm.t <= 0) { + return; + } + var pt = this.abs(); + if (pt.t < pm.t) { + if (q != null) { + q.fromInt(0); + } + if (r != null) { + this.copyTo(r); + } + return; + } + if (r == null) { + r = nbi(); + } + var y = nbi(); + var ts = this.s; + var ms = m.s; + var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus + if (nsh > 0) { + pm.lShiftTo(nsh, y); + pt.lShiftTo(nsh, r); + } + else { + pm.copyTo(y); + pt.copyTo(r); + } + var ys = y.t; + var y0 = y[ys - 1]; + if (y0 == 0) { + return; + } + var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0); + var d1 = this.FV / yt; + var d2 = (1 << this.F1) / yt; + var e = 1 << this.F2; + var i = r.t; + var j = i - ys; + var t = (q == null) ? nbi() : q; + y.dlShiftTo(j, t); + if (r.compareTo(t) >= 0) { + r[r.t++] = 1; + r.subTo(t, r); + } + BigInteger.ONE.dlShiftTo(ys, t); + t.subTo(y, y); // "negative" y so we can replace sub with am later + while (y.t < ys) { + y[y.t++] = 0; + } + while (--j >= 0) { + // Estimate quotient digit + var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2); + if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out + y.dlShiftTo(j, t); + r.subTo(t, r); + while (r[i] < --qd) { + r.subTo(t, r); + } + } + } + if (q != null) { + r.drShiftTo(ys, q); + if (ts != ms) { + BigInteger.ZERO.subTo(q, q); + } + } + r.t = ys; + r.clamp(); + if (nsh > 0) { + r.rShiftTo(nsh, r); + } // Denormalize remainder + if (ts < 0) { + BigInteger.ZERO.subTo(r, r); + } + }; + // BigInteger.prototype.invDigit = bnpInvDigit; + // (protected) return "-1/this % 2^DB"; useful for Mont. reduction + // justification: + // xy == 1 (mod m) + // xy = 1+km + // xy(2-xy) = (1+km)(1-km) + // x[y(2-xy)] = 1-k^2m^2 + // x[y(2-xy)] == 1 (mod m^2) + // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 + // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. + // JS multiply "overflows" differently from C/C++, so care is needed here. + BigInteger.prototype.invDigit = function () { + if (this.t < 1) { + return 0; + } + var x = this[0]; + if ((x & 1) == 0) { + return 0; + } + var y = x & 3; // y == 1/x mod 2^2 + y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 + y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 + y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 + // last step - calculate inverse mod DV directly; + // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints + y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits + // we really want the negative inverse, and -DV < y < DV + return (y > 0) ? this.DV - y : -y; + }; + // BigInteger.prototype.isEven = bnpIsEven; + // (protected) true iff this is even + BigInteger.prototype.isEven = function () { + return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; + }; + // BigInteger.prototype.exp = bnpExp; + // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) + BigInteger.prototype.exp = function (e, z) { + if (e > 0xffffffff || e < 1) { + return BigInteger.ONE; + } + var r = nbi(); + var r2 = nbi(); + var g = z.convert(this); + var i = nbits(e) - 1; + g.copyTo(r); + while (--i >= 0) { + z.sqrTo(r, r2); + if ((e & (1 << i)) > 0) { + z.mulTo(r2, g, r); + } + else { + var t = r; + r = r2; + r2 = t; + } + } + return z.revert(r); + }; + // BigInteger.prototype.chunkSize = bnpChunkSize; + // (protected) return x s.t. r^x < DV + BigInteger.prototype.chunkSize = function (r) { + return Math.floor(Math.LN2 * this.DB / Math.log(r)); + }; + // BigInteger.prototype.toRadix = bnpToRadix; + // (protected) convert to radix string + BigInteger.prototype.toRadix = function (b) { + if (b == null) { + b = 10; + } + if (this.signum() == 0 || b < 2 || b > 36) { + return "0"; + } + var cs = this.chunkSize(b); + var a = Math.pow(b, cs); + var d = nbv(a); + var y = nbi(); + var z = nbi(); + var r = ""; + this.divRemTo(d, y, z); + while (y.signum() > 0) { + r = (a + z.intValue()).toString(b).substr(1) + r; + y.divRemTo(d, y, z); + } + return z.intValue().toString(b) + r; + }; + // BigInteger.prototype.fromRadix = bnpFromRadix; + // (protected) convert from radix string + BigInteger.prototype.fromRadix = function (s, b) { + this.fromInt(0); + if (b == null) { + b = 10; + } + var cs = this.chunkSize(b); + var d = Math.pow(b, cs); + var mi = false; + var j = 0; + var w = 0; + for (var i = 0; i < s.length; ++i) { + var x = intAt(s, i); + if (x < 0) { + if (s.charAt(i) == "-" && this.signum() == 0) { + mi = true; + } + continue; + } + w = b * w + x; + if (++j >= cs) { + this.dMultiply(d); + this.dAddOffset(w, 0); + j = 0; + w = 0; + } + } + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); + } + if (mi) { + BigInteger.ZERO.subTo(this, this); + } + }; + // BigInteger.prototype.fromNumber = bnpFromNumber; + // (protected) alternate constructor + BigInteger.prototype.fromNumber = function (a, b, c) { + if ("number" == typeof b) { + // new BigInteger(int,int,RNG) + if (a < 2) { + this.fromInt(1); + } + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) { + // force MSB set + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + } + if (this.isEven()) { + this.dAddOffset(1, 0); + } // force odd + while (!this.isProbablePrime(b)) { + this.dAddOffset(2, 0); + if (this.bitLength() > a) { + this.subTo(BigInteger.ONE.shiftLeft(a - 1), this); + } + } + } + } + else { + // new BigInteger(int,RNG) + var x = []; + var t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) { + x[0] &= ((1 << t) - 1); + } + else { + x[0] = 0; + } + this.fromString(x, 256); + } + }; + // BigInteger.prototype.bitwiseTo = bnpBitwiseTo; + // (protected) r = this op a (bitwise) + BigInteger.prototype.bitwiseTo = function (a, op, r) { + var i; + var f; + var m = Math.min(a.t, this.t); + for (i = 0; i < m; ++i) { + r[i] = op(this[i], a[i]); + } + if (a.t < this.t) { + f = a.s & this.DM; + for (i = m; i < this.t; ++i) { + r[i] = op(this[i], f); + } + r.t = this.t; + } + else { + f = this.s & this.DM; + for (i = m; i < a.t; ++i) { + r[i] = op(f, a[i]); + } + r.t = a.t; + } + r.s = op(this.s, a.s); + r.clamp(); + }; + // BigInteger.prototype.changeBit = bnpChangeBit; + // (protected) this op (1<>= this.DB; + } + if (a.t < this.t) { + c += a.s; + while (i < this.t) { + c += this[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += this.s; + } + else { + c += this.s; + while (i < a.t) { + c += a[i]; + r[i++] = c & this.DM; + c >>= this.DB; + } + c += a.s; + } + r.s = (c < 0) ? -1 : 0; + if (c > 0) { + r[i++] = c; + } + else if (c < -1) { + r[i++] = this.DV + c; + } + r.t = i; + r.clamp(); + }; + // BigInteger.prototype.dMultiply = bnpDMultiply; + // (protected) this *= n, this >= 0, 1 < n < DV + BigInteger.prototype.dMultiply = function (n) { + this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); + ++this.t; + this.clamp(); + }; + // BigInteger.prototype.dAddOffset = bnpDAddOffset; + // (protected) this += n << w words, this >= 0 + BigInteger.prototype.dAddOffset = function (n, w) { + if (n == 0) { + return; + } + while (this.t <= w) { + this[this.t++] = 0; + } + this[w] += n; + while (this[w] >= this.DV) { + this[w] -= this.DV; + if (++w >= this.t) { + this[this.t++] = 0; + } + ++this[w]; + } + }; + // BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; + // (protected) r = lower n words of "this * a", a.t <= n + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyLowerTo = function (a, n, r) { + var i = Math.min(this.t + a.t, n); + r.s = 0; // assumes a,this >= 0 + r.t = i; + while (i > 0) { + r[--i] = 0; + } + for (var j = r.t - this.t; i < j; ++i) { + r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); + } + for (var j = Math.min(a.t, n); i < j; ++i) { + this.am(0, a[i], r, i, 0, n - i); + } + r.clamp(); + }; + // BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; + // (protected) r = "this * a" without lower n words, n > 0 + // "this" should be the larger one if appropriate. + BigInteger.prototype.multiplyUpperTo = function (a, n, r) { + --n; + var i = r.t = this.t + a.t - n; + r.s = 0; // assumes a,this >= 0 + while (--i >= 0) { + r[i] = 0; + } + for (i = Math.max(n - this.t, 0); i < a.t; ++i) { + r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); + } + r.clamp(); + r.drShiftTo(1, r); + }; + // BigInteger.prototype.modInt = bnpModInt; + // (protected) this % n, n < 2^26 + BigInteger.prototype.modInt = function (n) { + if (n <= 0) { + return 0; + } + var d = this.DV % n; + var r = (this.s < 0) ? n - 1 : 0; + if (this.t > 0) { + if (d == 0) { + r = this[0] % n; + } + else { + for (var i = this.t - 1; i >= 0; --i) { + r = (d * r + this[i]) % n; + } + } + } + return r; + }; + // BigInteger.prototype.millerRabin = bnpMillerRabin; + // (protected) true if probably prime (HAC 4.24, Miller-Rabin) + BigInteger.prototype.millerRabin = function (t) { + var n1 = this.subtract(BigInteger.ONE); + var k = n1.getLowestSetBit(); + if (k <= 0) { + return false; + } + var r = n1.shiftRight(k); + t = (t + 1) >> 1; + if (t > lowprimes.length) { + t = lowprimes.length; + } + var a = nbi(); + for (var i = 0; i < t; ++i) { + // Pick bases at random, instead of starting at 2 + a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]); + var y = a.modPow(r, this); + if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + var j = 1; + while (j++ < k && y.compareTo(n1) != 0) { + y = y.modPowInt(2, this); + if (y.compareTo(BigInteger.ONE) == 0) { + return false; + } + } + if (y.compareTo(n1) != 0) { + return false; + } + } + } + return true; + }; + // BigInteger.prototype.square = bnSquare; + // (public) this^2 + BigInteger.prototype.square = function () { + var r = nbi(); + this.squareTo(r); + return r; + }; + //#region ASYNC + // Public API method + BigInteger.prototype.gcda = function (a, callback) { + var x = (this.s < 0) ? this.negate() : this.clone(); + var y = (a.s < 0) ? a.negate() : a.clone(); + if (x.compareTo(y) < 0) { + var t = x; + x = y; + y = t; + } + var i = x.getLowestSetBit(); + var g = y.getLowestSetBit(); + if (g < 0) { + callback(x); + return; + } + if (i < g) { + g = i; + } + if (g > 0) { + x.rShiftTo(g, x); + y.rShiftTo(g, y); + } + // Workhorse of the algorithm, gets called 200 - 800 times per 512 bit keygen. + var gcda1 = function () { + if ((i = x.getLowestSetBit()) > 0) { + x.rShiftTo(i, x); + } + if ((i = y.getLowestSetBit()) > 0) { + y.rShiftTo(i, y); + } + if (x.compareTo(y) >= 0) { + x.subTo(y, x); + x.rShiftTo(1, x); + } + else { + y.subTo(x, y); + y.rShiftTo(1, y); + } + if (!(x.signum() > 0)) { + if (g > 0) { + y.lShiftTo(g, y); + } + setTimeout(function () { callback(y); }, 0); // escape + } + else { + setTimeout(gcda1, 0); + } + }; + setTimeout(gcda1, 10); + }; + // (protected) alternate constructor + BigInteger.prototype.fromNumberAsync = function (a, b, c, callback) { + if ("number" == typeof b) { + if (a < 2) { + this.fromInt(1); + } + else { + this.fromNumber(a, c); + if (!this.testBit(a - 1)) { + this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this); + } + if (this.isEven()) { + this.dAddOffset(1, 0); + } + var bnp_1 = this; + var bnpfn1_1 = function () { + bnp_1.dAddOffset(2, 0); + if (bnp_1.bitLength() > a) { + bnp_1.subTo(BigInteger.ONE.shiftLeft(a - 1), bnp_1); + } + if (bnp_1.isProbablePrime(b)) { + setTimeout(function () { callback(); }, 0); // escape + } + else { + setTimeout(bnpfn1_1, 0); + } + }; + setTimeout(bnpfn1_1, 0); + } + } + else { + var x = []; + var t = a & 7; + x.length = (a >> 3) + 1; + b.nextBytes(x); + if (t > 0) { + x[0] &= ((1 << t) - 1); + } + else { + x[0] = 0; + } + this.fromString(x, 256); + } + }; + return BigInteger; +}()); +//#region REDUCERS +//#region NullExp +var NullExp = /** @class */ (function () { + function NullExp() { + } + // NullExp.prototype.convert = nNop; + NullExp.prototype.convert = function (x) { + return x; + }; + // NullExp.prototype.revert = nNop; + NullExp.prototype.revert = function (x) { + return x; + }; + // NullExp.prototype.mulTo = nMulTo; + NullExp.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + }; + // NullExp.prototype.sqrTo = nSqrTo; + NullExp.prototype.sqrTo = function (x, r) { + x.squareTo(r); + }; + return NullExp; +}()); +// Modular reduction using "classic" algorithm +var Classic = /** @class */ (function () { + function Classic(m) { + this.m = m; + } + // Classic.prototype.convert = cConvert; + Classic.prototype.convert = function (x) { + if (x.s < 0 || x.compareTo(this.m) >= 0) { + return x.mod(this.m); + } + else { + return x; + } + }; + // Classic.prototype.revert = cRevert; + Classic.prototype.revert = function (x) { + return x; + }; + // Classic.prototype.reduce = cReduce; + Classic.prototype.reduce = function (x) { + x.divRemTo(this.m, null, x); + }; + // Classic.prototype.mulTo = cMulTo; + Classic.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + // Classic.prototype.sqrTo = cSqrTo; + Classic.prototype.sqrTo = function (x, r) { + x.squareTo(r); + this.reduce(r); + }; + return Classic; +}()); +//#endregion +//#region Montgomery +// Montgomery reduction +var Montgomery = /** @class */ (function () { + function Montgomery(m) { + this.m = m; + this.mp = m.invDigit(); + this.mpl = this.mp & 0x7fff; + this.mph = this.mp >> 15; + this.um = (1 << (m.DB - 15)) - 1; + this.mt2 = 2 * m.t; + } + // Montgomery.prototype.convert = montConvert; + // xR mod m + Montgomery.prototype.convert = function (x) { + var r = nbi(); + x.abs().dlShiftTo(this.m.t, r); + r.divRemTo(this.m, null, r); + if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) { + this.m.subTo(r, r); + } + return r; + }; + // Montgomery.prototype.revert = montRevert; + // x/R mod m + Montgomery.prototype.revert = function (x) { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + }; + // Montgomery.prototype.reduce = montReduce; + // x = x/R mod m (HAC 14.32) + Montgomery.prototype.reduce = function (x) { + while (x.t <= this.mt2) { + // pad x so am has enough room later + x[x.t++] = 0; + } + for (var i = 0; i < this.m.t; ++i) { + // faster way of calculating u0 = x[i]*mp mod DV + var j = x[i] & 0x7fff; + var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM; + // use am to combine the multiply-shift-add into one call + j = i + this.m.t; + x[j] += this.m.am(0, u0, x, i, 0, this.m.t); + // propagate carry + while (x[j] >= x.DV) { + x[j] -= x.DV; + x[++j]++; + } + } + x.clamp(); + x.drShiftTo(this.m.t, x); + if (x.compareTo(this.m) >= 0) { + x.subTo(this.m, x); + } + }; + // Montgomery.prototype.mulTo = montMulTo; + // r = "xy/R mod m"; x,y != r + Montgomery.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + // Montgomery.prototype.sqrTo = montSqrTo; + // r = "x^2/R mod m"; x != r + Montgomery.prototype.sqrTo = function (x, r) { + x.squareTo(r); + this.reduce(r); + }; + return Montgomery; +}()); +//#endregion Montgomery +//#region Barrett +// Barrett modular reduction +var Barrett = /** @class */ (function () { + function Barrett(m) { + this.m = m; + // setup Barrett + this.r2 = nbi(); + this.q3 = nbi(); + BigInteger.ONE.dlShiftTo(2 * m.t, this.r2); + this.mu = this.r2.divide(m); + } + // Barrett.prototype.convert = barrettConvert; + Barrett.prototype.convert = function (x) { + if (x.s < 0 || x.t > 2 * this.m.t) { + return x.mod(this.m); + } + else if (x.compareTo(this.m) < 0) { + return x; + } + else { + var r = nbi(); + x.copyTo(r); + this.reduce(r); + return r; + } + }; + // Barrett.prototype.revert = barrettRevert; + Barrett.prototype.revert = function (x) { + return x; + }; + // Barrett.prototype.reduce = barrettReduce; + // x = x mod m (HAC 14.42) + Barrett.prototype.reduce = function (x) { + x.drShiftTo(this.m.t - 1, this.r2); + if (x.t > this.m.t + 1) { + x.t = this.m.t + 1; + x.clamp(); + } + this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3); + this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2); + while (x.compareTo(this.r2) < 0) { + x.dAddOffset(1, this.m.t + 1); + } + x.subTo(this.r2, x); + while (x.compareTo(this.m) >= 0) { + x.subTo(this.m, x); + } + }; + // Barrett.prototype.mulTo = barrettMulTo; + // r = x*y mod m; x,y != r + Barrett.prototype.mulTo = function (x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); + }; + // Barrett.prototype.sqrTo = barrettSqrTo; + // r = x^2 mod m; x != r + Barrett.prototype.sqrTo = function (x, r) { + x.squareTo(r); + this.reduce(r); + }; + return Barrett; +}()); +//#endregion +//#endregion REDUCERS +// return new, unset BigInteger +function nbi() { return new BigInteger(null); } +function parseBigInt(str, r) { + return new BigInteger(str, r); +} +// am: Compute w_j += (x*this_i), propagate carries, +// c is initial carry, returns final carry. +// c < 3*dvalue, x < 2*dvalue, this_i < dvalue +// We need to select the fastest one that works in this environment. +// am1: use a single mult and divide to get the high bits, +// max digit bits should be 26 because +// max internal value = 2*dvalue^2-2*dvalue (< 2^53) +function am1(i, x, w, j, c, n) { + while (--n >= 0) { + var v = x * this[i++] + w[j] + c; + c = Math.floor(v / 0x4000000); + w[j++] = v & 0x3ffffff; + } + return c; +} +// am2 avoids a big mult-and-extract completely. +// Max digit bits should be <= 30 because we do bitwise ops +// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) +function am2(i, x, w, j, c, n) { + var xl = x & 0x7fff; + var xh = x >> 15; + while (--n >= 0) { + var l = this[i] & 0x7fff; + var h = this[i++] >> 15; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); + c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); + w[j++] = l & 0x3fffffff; + } + return c; +} +// Alternately, set max digit bits to 28 since some +// browsers slow down when dealing with 32-bit numbers. +function am3(i, x, w, j, c, n) { + var xl = x & 0x3fff; + var xh = x >> 14; + while (--n >= 0) { + var l = this[i] & 0x3fff; + var h = this[i++] >> 14; + var m = xh * l + h * xl; + l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; + c = (l >> 28) + (m >> 14) + xh * h; + w[j++] = l & 0xfffffff; + } + return c; +} +// if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { +// BigInteger.prototype.am = am2; +// dbits = 30; +// } +// else if (j_lm && (navigator.appName != "Netscape")) { +// BigInteger.prototype.am = am1; +// dbits = 26; +// } +// else { // Mozilla/Netscape seems to prefer am3 +// BigInteger.prototype.am = am3; +// dbits = 28; +// } +BigInteger.prototype.am = am1; +dbits = 26; + +BigInteger.prototype.DB = dbits; +BigInteger.prototype.DM = ((1 << dbits) - 1); +BigInteger.prototype.DV = (1 << dbits); +var BI_FP = 52; +BigInteger.prototype.FV = Math.pow(2, BI_FP); +BigInteger.prototype.F1 = BI_FP - dbits; +BigInteger.prototype.F2 = 2 * dbits - BI_FP; +// Digit conversions +var BI_RC = []; +var rr; +var vv; +rr = "0".charCodeAt(0); +for (vv = 0; vv <= 9; ++vv) { + BI_RC[rr++] = vv; +} +rr = "a".charCodeAt(0); +for (vv = 10; vv < 36; ++vv) { + BI_RC[rr++] = vv; +} +rr = "A".charCodeAt(0); +for (vv = 10; vv < 36; ++vv) { + BI_RC[rr++] = vv; +} +function intAt(s, i) { + var c = BI_RC[s.charCodeAt(i)]; + return (c == null) ? -1 : c; +} +// return bigint initialized to value +function nbv(i) { + var r = nbi(); + r.fromInt(i); + return r; +} +// returns bit length of the integer x +function nbits(x) { + var r = 1; + var t; + if ((t = x >>> 16) != 0) { + x = t; + r += 16; + } + if ((t = x >> 8) != 0) { + x = t; + r += 8; + } + if ((t = x >> 4) != 0) { + x = t; + r += 4; + } + if ((t = x >> 2) != 0) { + x = t; + r += 2; + } + if ((t = x >> 1) != 0) { + x = t; + r += 1; + } + return r; +} +// "constants" +BigInteger.ZERO = nbv(0); +BigInteger.ONE = nbv(1); + +// prng4.js - uses Arcfour as a PRNG +var Arcfour = /** @class */ (function () { + function Arcfour() { + this.i = 0; + this.j = 0; + this.S = []; + } + // Arcfour.prototype.init = ARC4init; + // Initialize arcfour context from key, an array of ints, each from [0..255] + Arcfour.prototype.init = function (key) { + var i; + var j; + var t; + for (i = 0; i < 256; ++i) { + this.S[i] = i; + } + j = 0; + for (i = 0; i < 256; ++i) { + j = (j + this.S[i] + key[i % key.length]) & 255; + t = this.S[i]; + this.S[i] = this.S[j]; + this.S[j] = t; + } + this.i = 0; + this.j = 0; + }; + // Arcfour.prototype.next = ARC4next; + Arcfour.prototype.next = function () { + var t; + this.i = (this.i + 1) & 255; + this.j = (this.j + this.S[this.i]) & 255; + t = this.S[this.i]; + this.S[this.i] = this.S[this.j]; + this.S[this.j] = t; + return this.S[(t + this.S[this.i]) & 255]; + }; + return Arcfour; +}()); +// Plug in your RNG constructor here +function prng_newstate() { + return new Arcfour(); +} +// Pool size must be a multiple of 4 and greater than 32. +// An array of bytes the size of the pool will be passed to init() +var rng_psize = 256; + +// Random number generator - requires a PRNG backend, e.g. prng4.js +var rng_state; +var rng_pool = null; +var rng_pptr; +// Initialize the pool with junk if needed. +if (rng_pool == null) { + rng_pool = []; + rng_pptr = 0; + var t = void 0; + if (window.crypto && window.crypto.getRandomValues) { + // Extract entropy (2048 bits) from RNG if available + var z = new Uint32Array(256); + window.crypto.getRandomValues(z); + for (t = 0; t < z.length; ++t) { + rng_pool[rng_pptr++] = z[t] & 255; + } + } + // Use mouse events for entropy, if we do not have enough entropy by the time + // we need it, entropy will be generated by Math.random. + var onMouseMoveListener_1 = function (ev) { + this.count = this.count || 0; + if (this.count >= 256 || rng_pptr >= rng_psize) { + if (window.removeEventListener) { + window.removeEventListener("mousemove", onMouseMoveListener_1, false); + } + else if (window.detachEvent) { + window.detachEvent("onmousemove", onMouseMoveListener_1); + } + return; + } + try { + var mouseCoordinates = ev.x + ev.y; + rng_pool[rng_pptr++] = mouseCoordinates & 255; + this.count += 1; + } + catch (e) { + // Sometimes Firefox will deny permission to access event properties for some reason. Ignore. + } + }; + if (window.addEventListener) { + window.addEventListener("mousemove", onMouseMoveListener_1, false); + } + else if (window.attachEvent) { + window.attachEvent("onmousemove", onMouseMoveListener_1); + } +} +function rng_get_byte() { + if (rng_state == null) { + rng_state = prng_newstate(); + // At this point, we may not have collected enough entropy. If not, fall back to Math.random + while (rng_pptr < rng_psize) { + var random = Math.floor(65536 * Math.random()); + rng_pool[rng_pptr++] = random & 255; + } + rng_state.init(rng_pool); + for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) { + rng_pool[rng_pptr] = 0; + } + rng_pptr = 0; + } + // TODO: allow reseeding after first request + return rng_state.next(); +} +var SecureRandom = /** @class */ (function () { + function SecureRandom() { + } + SecureRandom.prototype.nextBytes = function (ba) { + for (var i = 0; i < ba.length; ++i) { + ba[i] = rng_get_byte(); + } + }; + return SecureRandom; +}()); + +// Depends on jsbn.js and rng.js +// function linebrk(s,n) { +// var ret = ""; +// var i = 0; +// while(i + n < s.length) { +// ret += s.substring(i,i+n) + "\n"; +// i += n; +// } +// return ret + s.substring(i,s.length); +// } +// function byte2Hex(b) { +// if(b < 0x10) +// return "0" + b.toString(16); +// else +// return b.toString(16); +// } +function pkcs1pad1(s, n) { + if (n < s.length + 22) { + console.error("Message too long for RSA"); + return null; + } + var len = n - s.length - 6; + var filler = ""; + for (var f = 0; f < len; f += 2) { + filler += "ff"; + } + var m = "0001" + filler + "00" + s; + return parseBigInt(m, 16); +} +// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint +function pkcs1pad2(s, n) { + if (n < s.length + 11) { // TODO: fix for utf-8 + console.error("Message too long for RSA"); + return null; + } + var ba = []; + var i = s.length - 1; + while (i >= 0 && n > 0) { + var c = s.charCodeAt(i--); + if (c < 128) { // encode using utf-8 + ba[--n] = c; + } + else if ((c > 127) && (c < 2048)) { + ba[--n] = (c & 63) | 128; + ba[--n] = (c >> 6) | 192; + } + else { + ba[--n] = (c & 63) | 128; + ba[--n] = ((c >> 6) & 63) | 128; + ba[--n] = (c >> 12) | 224; + } + } + ba[--n] = 0; + var rng = new SecureRandom(); + var x = []; + while (n > 2) { // random non-zero pad + x[0] = 0; + while (x[0] == 0) { + rng.nextBytes(x); + } + ba[--n] = x[0]; + } + ba[--n] = 2; + ba[--n] = 0; + return new BigInteger(ba); +} +// "empty" RSA key constructor +var RSAKey = /** @class */ (function () { + function RSAKey() { + this.n = null; + this.e = 0; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.coeff = null; + } + //#region PROTECTED + // protected + // RSAKey.prototype.doPublic = RSADoPublic; + // Perform raw public operation on "x": return x^e (mod n) + RSAKey.prototype.doPublic = function (x) { + return x.modPowInt(this.e, this.n); + }; + // RSAKey.prototype.doPrivate = RSADoPrivate; + // Perform raw private operation on "x": return x^d (mod n) + RSAKey.prototype.doPrivate = function (x) { + if (this.p == null || this.q == null) { + return x.modPow(this.d, this.n); + } + // TODO: re-calculate any missing CRT params + var xp = x.mod(this.p).modPow(this.dmp1, this.p); + var xq = x.mod(this.q).modPow(this.dmq1, this.q); + while (xp.compareTo(xq) < 0) { + xp = xp.add(this.p); + } + return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); + }; + //#endregion PROTECTED + //#region PUBLIC + // RSAKey.prototype.setPublic = RSASetPublic; + // Set the public key fields N and e from hex strings + RSAKey.prototype.setPublic = function (N, E) { + if (N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N, 16); + this.e = parseInt(E, 16); + } + else { + console.error("Invalid RSA public key"); + } + }; + // RSAKey.prototype.encrypt = RSAEncrypt; + // Return the PKCS#1 RSA encryption of "text" as an even-length hex string + RSAKey.prototype.encrypt = function (text) { + var m = pkcs1pad2(text, (this.n.bitLength() + 7) >> 3); + if (m == null) { + return null; + } + var c = this.doPublic(m); + if (c == null) { + return null; + } + var h = c.toString(16); + if ((h.length & 1) == 0) { + return h; + } + else { + return "0" + h; + } + }; + // RSAKey.prototype.setPrivate = RSASetPrivate; + // Set the private key fields N, e, and d from hex strings + RSAKey.prototype.setPrivate = function (N, E, D) { + if (N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N, 16); + this.e = parseInt(E, 16); + this.d = parseBigInt(D, 16); + } + else { + console.error("Invalid RSA private key"); + } + }; + // RSAKey.prototype.setPrivateEx = RSASetPrivateEx; + // Set the private key fields N, e, d and CRT params from hex strings + RSAKey.prototype.setPrivateEx = function (N, E, D, P, Q, DP, DQ, C) { + if (N != null && E != null && N.length > 0 && E.length > 0) { + this.n = parseBigInt(N, 16); + this.e = parseInt(E, 16); + this.d = parseBigInt(D, 16); + this.p = parseBigInt(P, 16); + this.q = parseBigInt(Q, 16); + this.dmp1 = parseBigInt(DP, 16); + this.dmq1 = parseBigInt(DQ, 16); + this.coeff = parseBigInt(C, 16); + } + else { + console.error("Invalid RSA private key"); + } + }; + // RSAKey.prototype.generate = RSAGenerate; + // Generate a new random private key B bits long, using public expt E + RSAKey.prototype.generate = function (B, E) { + var rng = new SecureRandom(); + var qs = B >> 1; + this.e = parseInt(E, 16); + var ee = new BigInteger(E, 16); + for (;;) { + for (;;) { + this.p = new BigInteger(B - qs, 1, rng); + if (this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) { + break; + } + } + for (;;) { + this.q = new BigInteger(qs, 1, rng); + if (this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) { + break; + } + } + if (this.p.compareTo(this.q) <= 0) { + var t = this.p; + this.p = this.q; + this.q = t; + } + var p1 = this.p.subtract(BigInteger.ONE); + var q1 = this.q.subtract(BigInteger.ONE); + var phi = p1.multiply(q1); + if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { + this.n = this.p.multiply(this.q); + this.d = ee.modInverse(phi); + this.dmp1 = this.d.mod(p1); + this.dmq1 = this.d.mod(q1); + this.coeff = this.q.modInverse(this.p); + break; + } + } + }; + // RSAKey.prototype.decrypt = RSADecrypt; + // Return the PKCS#1 RSA decryption of "ctext". + // "ctext" is an even-length hex string and the output is a plain string. + RSAKey.prototype.decrypt = function (ctext) { + var c = parseBigInt(ctext, 16); + var m = this.doPrivate(c); + if (m == null) { + return null; + } + return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3); + }; + // Generate a new random private key B bits long, using public expt E + RSAKey.prototype.generateAsync = function (B, E, callback) { + var rng = new SecureRandom(); + var qs = B >> 1; + this.e = parseInt(E, 16); + var ee = new BigInteger(E, 16); + var rsa = this; + // These functions have non-descript names because they were originally for(;;) loops. + // I don't know about cryptography to give them better names than loop1-4. + var loop1 = function () { + var loop4 = function () { + if (rsa.p.compareTo(rsa.q) <= 0) { + var t = rsa.p; + rsa.p = rsa.q; + rsa.q = t; + } + var p1 = rsa.p.subtract(BigInteger.ONE); + var q1 = rsa.q.subtract(BigInteger.ONE); + var phi = p1.multiply(q1); + if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) { + rsa.n = rsa.p.multiply(rsa.q); + rsa.d = ee.modInverse(phi); + rsa.dmp1 = rsa.d.mod(p1); + rsa.dmq1 = rsa.d.mod(q1); + rsa.coeff = rsa.q.modInverse(rsa.p); + setTimeout(function () { callback(); }, 0); // escape + } + else { + setTimeout(loop1, 0); + } + }; + var loop3 = function () { + rsa.q = nbi(); + rsa.q.fromNumberAsync(qs, 1, rng, function () { + rsa.q.subtract(BigInteger.ONE).gcda(ee, function (r) { + if (r.compareTo(BigInteger.ONE) == 0 && rsa.q.isProbablePrime(10)) { + setTimeout(loop4, 0); + } + else { + setTimeout(loop3, 0); + } + }); + }); + }; + var loop2 = function () { + rsa.p = nbi(); + rsa.p.fromNumberAsync(B - qs, 1, rng, function () { + rsa.p.subtract(BigInteger.ONE).gcda(ee, function (r) { + if (r.compareTo(BigInteger.ONE) == 0 && rsa.p.isProbablePrime(10)) { + setTimeout(loop3, 0); + } + else { + setTimeout(loop2, 0); + } + }); + }); + }; + setTimeout(loop2, 0); + }; + setTimeout(loop1, 0); + }; + RSAKey.prototype.sign = function (text, digestMethod, digestName) { + var header = getDigestHeader(digestName); + var digest = header + digestMethod(text).toString(); + var m = pkcs1pad1(digest, this.n.bitLength() / 4); + if (m == null) { + return null; + } + var c = this.doPrivate(m); + if (c == null) { + return null; + } + var h = c.toString(16); + if ((h.length & 1) == 0) { + return h; + } + else { + return "0" + h; + } + }; + RSAKey.prototype.verify = function (text, signature, digestMethod) { + var c = parseBigInt(signature, 16); + var m = this.doPublic(c); + if (m == null) { + return null; + } + var unpadded = m.toString(16).replace(/^1f+00/, ""); + var digest = removeDigestHeader(unpadded); + return digest == digestMethod(text).toString(); + }; + return RSAKey; +}()); +// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext +function pkcs1unpad2(d, n) { + var b = d.toByteArray(); + var i = 0; + while (i < b.length && b[i] == 0) { + ++i; + } + if (b.length - i != n - 1 || b[i] != 2) { + return null; + } + ++i; + while (b[i] != 0) { + if (++i >= b.length) { + return null; + } + } + var ret = ""; + while (++i < b.length) { + var c = b[i] & 255; + if (c < 128) { // utf-8 decode + ret += String.fromCharCode(c); + } + else if ((c > 191) && (c < 224)) { + ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63)); + ++i; + } + else { + ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63)); + i += 2; + } + } + return ret; +} +// https://tools.ietf.org/html/rfc3447#page-43 +var DIGEST_HEADERS = { + md2: "3020300c06082a864886f70d020205000410", + md5: "3020300c06082a864886f70d020505000410", + sha1: "3021300906052b0e03021a05000414", + sha224: "302d300d06096086480165030402040500041c", + sha256: "3031300d060960864801650304020105000420", + sha384: "3041300d060960864801650304020205000430", + sha512: "3051300d060960864801650304020305000440", + ripemd160: "3021300906052b2403020105000414", +}; +function getDigestHeader(name) { + return DIGEST_HEADERS[name] || ""; +} +function removeDigestHeader(str) { + for (var name_1 in DIGEST_HEADERS) { + if (DIGEST_HEADERS.hasOwnProperty(name_1)) { + var header = DIGEST_HEADERS[name_1]; + var len = header.length; + if (str.substr(0, len) == header) { + return str.substr(len); + } + } + } + return str; +} +// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string +// function RSAEncryptB64(text) { +// var h = this.encrypt(text); +// if(h) return hex2b64(h); else return null; +// } +// public +// RSAKey.prototype.encrypt_b64 = RSAEncryptB64; + +/*! +Copyright (c) 2011, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.9.0 +*/ +var YAHOO = {}; +YAHOO.lang = { + /** + * Utility to set up the prototype, constructor and superclass properties to + * support an inheritance strategy that can chain constructors and methods. + * Static members will not be inherited. + * + * @method extend + * @static + * @param {Function} subc the object to modify + * @param {Function} superc the object to inherit + * @param {Object} overrides additional properties/methods to add to the + * subclass prototype. These will override the + * matching items obtained from the superclass + * if present. + */ + extend: function(subc, superc, overrides) { + if (! superc || ! subc) { + throw new Error("YAHOO.lang.extend failed, please check that " + + "all dependencies are included."); + } + + var F = function() {}; + F.prototype = superc.prototype; + subc.prototype = new F(); + subc.prototype.constructor = subc; + subc.superclass = superc.prototype; + + if (superc.prototype.constructor == Object.prototype.constructor) { + superc.prototype.constructor = superc; + } + + if (overrides) { + var i; + for (i in overrides) { + subc.prototype[i] = overrides[i]; + } + + /* + * IE will not enumerate native functions in a derived object even if the + * function was overridden. This is a workaround for specific functions + * we care about on the Object prototype. + * @property _IEEnumFix + * @param {Function} r the object to receive the augmentation + * @param {Function} s the object that supplies the properties to augment + * @static + * @private + */ + var _IEEnumFix = function() {}, + ADD = ["toString", "valueOf"]; + try { + if (/MSIE/.test(navigator.userAgent)) { + _IEEnumFix = function(r, s) { + for (i = 0; i < ADD.length; i = i + 1) { + var fname = ADD[i], f = s[fname]; + if (typeof f === 'function' && f != Object.prototype[fname]) { + r[fname] = f; + } + } + }; + } + } catch (ex) {} _IEEnumFix(subc.prototype, overrides); + } + } +}; + +/* asn1-1.0.13.js (c) 2013-2017 Kenji Urushima | kjur.github.com/jsrsasign/license + */ + +/** + * @fileOverview + * @name asn1-1.0.js + * @author Kenji Urushima kenji.urushima@gmail.com + * @version asn1 1.0.13 (2017-Jun-02) + * @since jsrsasign 2.1 + * @license MIT License + */ + +/** + * kjur's class library name space + *

+ * This name space provides following name spaces: + *

    + *
  • {@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder
  • + *
  • {@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL
  • + *
  • {@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature + * class and utilities
  • + *
+ *

+ * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2. + * @name KJUR + * @namespace kjur's class library name space + */ +var KJUR = {}; + +/** + * kjur's ASN.1 class library name space + *

+ * This is ITU-T X.690 ASN.1 DER encoder class library and + * class structure and methods is very similar to + * org.bouncycastle.asn1 package of + * well known BouncyCaslte Cryptography Library. + *

PROVIDING ASN.1 PRIMITIVES

+ * Here are ASN.1 DER primitive classes. + *
    + *
  • 0x01 {@link KJUR.asn1.DERBoolean}
  • + *
  • 0x02 {@link KJUR.asn1.DERInteger}
  • + *
  • 0x03 {@link KJUR.asn1.DERBitString}
  • + *
  • 0x04 {@link KJUR.asn1.DEROctetString}
  • + *
  • 0x05 {@link KJUR.asn1.DERNull}
  • + *
  • 0x06 {@link KJUR.asn1.DERObjectIdentifier}
  • + *
  • 0x0a {@link KJUR.asn1.DEREnumerated}
  • + *
  • 0x0c {@link KJUR.asn1.DERUTF8String}
  • + *
  • 0x12 {@link KJUR.asn1.DERNumericString}
  • + *
  • 0x13 {@link KJUR.asn1.DERPrintableString}
  • + *
  • 0x14 {@link KJUR.asn1.DERTeletexString}
  • + *
  • 0x16 {@link KJUR.asn1.DERIA5String}
  • + *
  • 0x17 {@link KJUR.asn1.DERUTCTime}
  • + *
  • 0x18 {@link KJUR.asn1.DERGeneralizedTime}
  • + *
  • 0x30 {@link KJUR.asn1.DERSequence}
  • + *
  • 0x31 {@link KJUR.asn1.DERSet}
  • + *
+ *

OTHER ASN.1 CLASSES

+ *
    + *
  • {@link KJUR.asn1.ASN1Object}
  • + *
  • {@link KJUR.asn1.DERAbstractString}
  • + *
  • {@link KJUR.asn1.DERAbstractTime}
  • + *
  • {@link KJUR.asn1.DERAbstractStructured}
  • + *
  • {@link KJUR.asn1.DERTaggedObject}
  • + *
+ *

SUB NAME SPACES

+ *
    + *
  • {@link KJUR.asn1.cades} - CAdES long term signature format
  • + *
  • {@link KJUR.asn1.cms} - Cryptographic Message Syntax
  • + *
  • {@link KJUR.asn1.csr} - Certificate Signing Request (CSR/PKCS#10)
  • + *
  • {@link KJUR.asn1.tsp} - RFC 3161 Timestamping Protocol Format
  • + *
  • {@link KJUR.asn1.x509} - RFC 5280 X.509 certificate and CRL
  • + *
+ *

+ * NOTE: Please ignore method summary and document of this namespace. + * This caused by a bug of jsdoc2. + * @name KJUR.asn1 + * @namespace + */ +if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {}; + +/** + * ASN1 utilities class + * @name KJUR.asn1.ASN1Util + * @class ASN1 utilities class + * @since asn1 1.0.2 + */ +KJUR.asn1.ASN1Util = new function() { + this.integerToByteHex = function(i) { + var h = i.toString(16); + if ((h.length % 2) == 1) h = '0' + h; + return h; + }; + this.bigIntToMinTwosComplementsHex = function(bigIntegerValue) { + var h = bigIntegerValue.toString(16); + if (h.substr(0, 1) != '-') { + if (h.length % 2 == 1) { + h = '0' + h; + } else { + if (! h.match(/^[0-7]/)) { + h = '00' + h; + } + } + } else { + var hPos = h.substr(1); + var xorLen = hPos.length; + if (xorLen % 2 == 1) { + xorLen += 1; + } else { + if (! h.match(/^[0-7]/)) { + xorLen += 2; + } + } + var hMask = ''; + for (var i = 0; i < xorLen; i++) { + hMask += 'f'; + } + var biMask = new BigInteger(hMask, 16); + var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE); + h = biNeg.toString(16).replace(/^-/, ''); + } + return h; + }; + /** + * get PEM string from hexadecimal data and header string + * @name getPEMStringFromHex + * @memberOf KJUR.asn1.ASN1Util + * @function + * @param {String} dataHex hexadecimal string of PEM body + * @param {String} pemHeader PEM header string (ex. 'RSA PRIVATE KEY') + * @return {String} PEM formatted string of input data + * @description + * This method converts a hexadecimal string to a PEM string with + * a specified header. Its line break will be CRLF("\r\n"). + * @example + * var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY'); + * // value of pem will be: + * -----BEGIN PRIVATE KEY----- + * YWFh + * -----END PRIVATE KEY----- + */ + this.getPEMStringFromHex = function(dataHex, pemHeader) { + return hextopem(dataHex, pemHeader); + }; + + /** + * generate ASN1Object specifed by JSON parameters + * @name newObject + * @memberOf KJUR.asn1.ASN1Util + * @function + * @param {Array} param JSON parameter to generate ASN1Object + * @return {KJUR.asn1.ASN1Object} generated object + * @since asn1 1.0.3 + * @description + * generate any ASN1Object specified by JSON param + * including ASN.1 primitive or structured. + * Generally 'param' can be described as follows: + *
+ * {TYPE-OF-ASNOBJ: ASN1OBJ-PARAMETER} + *
+ * 'TYPE-OF-ASN1OBJ' can be one of following symbols: + *
    + *
  • 'bool' - DERBoolean
  • + *
  • 'int' - DERInteger
  • + *
  • 'bitstr' - DERBitString
  • + *
  • 'octstr' - DEROctetString
  • + *
  • 'null' - DERNull
  • + *
  • 'oid' - DERObjectIdentifier
  • + *
  • 'enum' - DEREnumerated
  • + *
  • 'utf8str' - DERUTF8String
  • + *
  • 'numstr' - DERNumericString
  • + *
  • 'prnstr' - DERPrintableString
  • + *
  • 'telstr' - DERTeletexString
  • + *
  • 'ia5str' - DERIA5String
  • + *
  • 'utctime' - DERUTCTime
  • + *
  • 'gentime' - DERGeneralizedTime
  • + *
  • 'seq' - DERSequence
  • + *
  • 'set' - DERSet
  • + *
  • 'tag' - DERTaggedObject
  • + *
+ * @example + * newObject({'prnstr': 'aaa'}); + * newObject({'seq': [{'int': 3}, {'prnstr': 'aaa'}]}) + * // ASN.1 Tagged Object + * newObject({'tag': {'tag': 'a1', + * 'explicit': true, + * 'obj': {'seq': [{'int': 3}, {'prnstr': 'aaa'}]}}}); + * // more simple representation of ASN.1 Tagged Object + * newObject({'tag': ['a1', + * true, + * {'seq': [ + * {'int': 3}, + * {'prnstr': 'aaa'}]} + * ]}); + */ + this.newObject = function(param) { + var _KJUR = KJUR, + _KJUR_asn1 = _KJUR.asn1, + _DERBoolean = _KJUR_asn1.DERBoolean, + _DERInteger = _KJUR_asn1.DERInteger, + _DERBitString = _KJUR_asn1.DERBitString, + _DEROctetString = _KJUR_asn1.DEROctetString, + _DERNull = _KJUR_asn1.DERNull, + _DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier, + _DEREnumerated = _KJUR_asn1.DEREnumerated, + _DERUTF8String = _KJUR_asn1.DERUTF8String, + _DERNumericString = _KJUR_asn1.DERNumericString, + _DERPrintableString = _KJUR_asn1.DERPrintableString, + _DERTeletexString = _KJUR_asn1.DERTeletexString, + _DERIA5String = _KJUR_asn1.DERIA5String, + _DERUTCTime = _KJUR_asn1.DERUTCTime, + _DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime, + _DERSequence = _KJUR_asn1.DERSequence, + _DERSet = _KJUR_asn1.DERSet, + _DERTaggedObject = _KJUR_asn1.DERTaggedObject, + _newObject = _KJUR_asn1.ASN1Util.newObject; + + var keys = Object.keys(param); + if (keys.length != 1) + throw "key of param shall be only one."; + var key = keys[0]; + + if (":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:".indexOf(":" + key + ":") == -1) + throw "undefined key: " + key; + + if (key == "bool") return new _DERBoolean(param[key]); + if (key == "int") return new _DERInteger(param[key]); + if (key == "bitstr") return new _DERBitString(param[key]); + if (key == "octstr") return new _DEROctetString(param[key]); + if (key == "null") return new _DERNull(param[key]); + if (key == "oid") return new _DERObjectIdentifier(param[key]); + if (key == "enum") return new _DEREnumerated(param[key]); + if (key == "utf8str") return new _DERUTF8String(param[key]); + if (key == "numstr") return new _DERNumericString(param[key]); + if (key == "prnstr") return new _DERPrintableString(param[key]); + if (key == "telstr") return new _DERTeletexString(param[key]); + if (key == "ia5str") return new _DERIA5String(param[key]); + if (key == "utctime") return new _DERUTCTime(param[key]); + if (key == "gentime") return new _DERGeneralizedTime(param[key]); + + if (key == "seq") { + var paramList = param[key]; + var a = []; + for (var i = 0; i < paramList.length; i++) { + var asn1Obj = _newObject(paramList[i]); + a.push(asn1Obj); + } + return new _DERSequence({'array': a}); + } + + if (key == "set") { + var paramList = param[key]; + var a = []; + for (var i = 0; i < paramList.length; i++) { + var asn1Obj = _newObject(paramList[i]); + a.push(asn1Obj); + } + return new _DERSet({'array': a}); + } + + if (key == "tag") { + var tagParam = param[key]; + if (Object.prototype.toString.call(tagParam) === '[object Array]' && + tagParam.length == 3) { + var obj = _newObject(tagParam[2]); + return new _DERTaggedObject({tag: tagParam[0], + explicit: tagParam[1], + obj: obj}); + } else { + var newParam = {}; + if (tagParam.explicit !== undefined) + newParam.explicit = tagParam.explicit; + if (tagParam.tag !== undefined) + newParam.tag = tagParam.tag; + if (tagParam.obj === undefined) + throw "obj shall be specified for 'tag'."; + newParam.obj = _newObject(tagParam.obj); + return new _DERTaggedObject(newParam); + } + } + }; + + /** + * get encoded hexadecimal string of ASN1Object specifed by JSON parameters + * @name jsonToASN1HEX + * @memberOf KJUR.asn1.ASN1Util + * @function + * @param {Array} param JSON parameter to generate ASN1Object + * @return hexadecimal string of ASN1Object + * @since asn1 1.0.4 + * @description + * As for ASN.1 object representation of JSON object, + * please see {@link newObject}. + * @example + * jsonToASN1HEX({'prnstr': 'aaa'}); + */ + this.jsonToASN1HEX = function(param) { + var asn1Obj = this.newObject(param); + return asn1Obj.getEncodedHex(); + }; +}; + +/** + * get dot noted oid number string from hexadecimal value of OID + * @name oidHexToInt + * @memberOf KJUR.asn1.ASN1Util + * @function + * @param {String} hex hexadecimal value of object identifier + * @return {String} dot noted string of object identifier + * @since jsrsasign 4.8.3 asn1 1.0.7 + * @description + * This static method converts from hexadecimal string representation of + * ASN.1 value of object identifier to oid number string. + * @example + * KJUR.asn1.ASN1Util.oidHexToInt('550406') → "2.5.4.6" + */ +KJUR.asn1.ASN1Util.oidHexToInt = function(hex) { + var s = ""; + var i01 = parseInt(hex.substr(0, 2), 16); + var i0 = Math.floor(i01 / 40); + var i1 = i01 % 40; + var s = i0 + "." + i1; + + var binbuf = ""; + for (var i = 2; i < hex.length; i += 2) { + var value = parseInt(hex.substr(i, 2), 16); + var bin = ("00000000" + value.toString(2)).slice(- 8); + binbuf = binbuf + bin.substr(1, 7); + if (bin.substr(0, 1) == "0") { + var bi = new BigInteger(binbuf, 2); + s = s + "." + bi.toString(10); + binbuf = ""; + } + } + return s; +}; + +/** + * get hexadecimal value of object identifier from dot noted oid value + * @name oidIntToHex + * @memberOf KJUR.asn1.ASN1Util + * @function + * @param {String} oidString dot noted string of object identifier + * @return {String} hexadecimal value of object identifier + * @since jsrsasign 4.8.3 asn1 1.0.7 + * @description + * This static method converts from object identifier value string. + * to hexadecimal string representation of it. + * @example + * KJUR.asn1.ASN1Util.oidIntToHex("2.5.4.6") → "550406" + */ +KJUR.asn1.ASN1Util.oidIntToHex = function(oidString) { + var itox = function(i) { + var h = i.toString(16); + if (h.length == 1) h = '0' + h; + return h; + }; + + var roidtox = function(roid) { + var h = ''; + var bi = new BigInteger(roid, 10); + var b = bi.toString(2); + var padLen = 7 - b.length % 7; + if (padLen == 7) padLen = 0; + var bPad = ''; + for (var i = 0; i < padLen; i++) bPad += '0'; + b = bPad + b; + for (var i = 0; i < b.length - 1; i += 7) { + var b8 = b.substr(i, 7); + if (i != b.length - 7) b8 = '1' + b8; + h += itox(parseInt(b8, 2)); + } + return h; + }; + + if (! oidString.match(/^[0-9.]+$/)) { + throw "malformed oid string: " + oidString; + } + var h = ''; + var a = oidString.split('.'); + var i0 = parseInt(a[0]) * 40 + parseInt(a[1]); + h += itox(i0); + a.splice(0, 2); + for (var i = 0; i < a.length; i++) { + h += roidtox(a[i]); + } + return h; +}; + + +// ******************************************************************** +// Abstract ASN.1 Classes +// ******************************************************************** + +// ******************************************************************** + +/** + * base class for ASN.1 DER encoder object + * @name KJUR.asn1.ASN1Object + * @class base class for ASN.1 DER encoder object + * @property {Boolean} isModified flag whether internal data was changed + * @property {String} hTLV hexadecimal string of ASN.1 TLV + * @property {String} hT hexadecimal string of ASN.1 TLV tag(T) + * @property {String} hL hexadecimal string of ASN.1 TLV length(L) + * @property {String} hV hexadecimal string of ASN.1 TLV value(V) + * @description + */ +KJUR.asn1.ASN1Object = function() { + var hV = ''; + + /** + * get hexadecimal ASN.1 TLV length(L) bytes from TLV value(V) + * @name getLengthHexFromValue + * @memberOf KJUR.asn1.ASN1Object# + * @function + * @return {String} hexadecimal string of ASN.1 TLV length(L) + */ + this.getLengthHexFromValue = function() { + if (typeof this.hV == "undefined" || this.hV == null) { + throw "this.hV is null or undefined."; + } + if (this.hV.length % 2 == 1) { + throw "value hex must be even length: n=" + hV.length + ",v=" + this.hV; + } + var n = this.hV.length / 2; + var hN = n.toString(16); + if (hN.length % 2 == 1) { + hN = "0" + hN; + } + if (n < 128) { + return hN; + } else { + var hNlen = hN.length / 2; + if (hNlen > 15) { + throw "ASN.1 length too long to represent by 8x: n = " + n.toString(16); + } + var head = 128 + hNlen; + return head.toString(16) + hN; + } + }; + + /** + * get hexadecimal string of ASN.1 TLV bytes + * @name getEncodedHex + * @memberOf KJUR.asn1.ASN1Object# + * @function + * @return {String} hexadecimal string of ASN.1 TLV + */ + this.getEncodedHex = function() { + if (this.hTLV == null || this.isModified) { + this.hV = this.getFreshValueHex(); + this.hL = this.getLengthHexFromValue(); + this.hTLV = this.hT + this.hL + this.hV; + this.isModified = false; + //alert("first time: " + this.hTLV); + } + return this.hTLV; + }; + + /** + * get hexadecimal string of ASN.1 TLV value(V) bytes + * @name getValueHex + * @memberOf KJUR.asn1.ASN1Object# + * @function + * @return {String} hexadecimal string of ASN.1 TLV value(V) bytes + */ + this.getValueHex = function() { + this.getEncodedHex(); + return this.hV; + }; + + this.getFreshValueHex = function() { + return ''; + }; +}; + +// == BEGIN DERAbstractString ================================================ +/** + * base class for ASN.1 DER string classes + * @name KJUR.asn1.DERAbstractString + * @class base class for ASN.1 DER string classes + * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) + * @property {String} s internal string of value + * @extends KJUR.asn1.ASN1Object + * @description + *
+ * As for argument 'params' for constructor, you can specify one of + * following properties: + *
    + *
  • str - specify initial ASN.1 value(V) by a string
  • + *
  • hex - specify initial ASN.1 value(V) by a hexadecimal string
  • + *
+ * NOTE: 'params' can be omitted. + */ +KJUR.asn1.DERAbstractString = function(params) { + KJUR.asn1.DERAbstractString.superclass.constructor.call(this); + + /** + * get string value of this string object + * @name getString + * @memberOf KJUR.asn1.DERAbstractString# + * @function + * @return {String} string value of this string object + */ + this.getString = function() { + return this.s; + }; + + /** + * set value by a string + * @name setString + * @memberOf KJUR.asn1.DERAbstractString# + * @function + * @param {String} newS value by a string to set + */ + this.setString = function(newS) { + this.hTLV = null; + this.isModified = true; + this.s = newS; + this.hV = stohex(this.s); + }; + + /** + * set value by a hexadecimal string + * @name setStringHex + * @memberOf KJUR.asn1.DERAbstractString# + * @function + * @param {String} newHexString value by a hexadecimal string to set + */ + this.setStringHex = function(newHexString) { + this.hTLV = null; + this.isModified = true; + this.s = null; + this.hV = newHexString; + }; + + this.getFreshValueHex = function() { + return this.hV; + }; + + if (typeof params != "undefined") { + if (typeof params == "string") { + this.setString(params); + } else if (typeof params['str'] != "undefined") { + this.setString(params['str']); + } else if (typeof params['hex'] != "undefined") { + this.setStringHex(params['hex']); + } + } +}; +YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object); +// == END DERAbstractString ================================================ + +// == BEGIN DERAbstractTime ================================================== +/** + * base class for ASN.1 DER Generalized/UTCTime class + * @name KJUR.asn1.DERAbstractTime + * @class base class for ASN.1 DER Generalized/UTCTime class + * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'}) + * @extends KJUR.asn1.ASN1Object + * @description + * @see KJUR.asn1.ASN1Object - superclass + */ +KJUR.asn1.DERAbstractTime = function(params) { + KJUR.asn1.DERAbstractTime.superclass.constructor.call(this); + + // --- PRIVATE METHODS -------------------- + this.localDateToUTC = function(d) { + utc = d.getTime() + (d.getTimezoneOffset() * 60000); + var utcDate = new Date(utc); + return utcDate; + }; + + /* + * format date string by Data object + * @name formatDate + * @memberOf KJUR.asn1.AbstractTime; + * @param {Date} dateObject + * @param {string} type 'utc' or 'gen' + * @param {boolean} withMillis flag for with millisections or not + * @description + * 'withMillis' flag is supported from asn1 1.0.6. + */ + this.formatDate = function(dateObject, type, withMillis) { + var pad = this.zeroPadding; + var d = this.localDateToUTC(dateObject); + var year = String(d.getFullYear()); + if (type == 'utc') year = year.substr(2, 2); + var month = pad(String(d.getMonth() + 1), 2); + var day = pad(String(d.getDate()), 2); + var hour = pad(String(d.getHours()), 2); + var min = pad(String(d.getMinutes()), 2); + var sec = pad(String(d.getSeconds()), 2); + var s = year + month + day + hour + min + sec; + if (withMillis === true) { + var millis = d.getMilliseconds(); + if (millis != 0) { + var sMillis = pad(String(millis), 3); + sMillis = sMillis.replace(/[0]+$/, ""); + s = s + "." + sMillis; + } + } + return s + "Z"; + }; + + this.zeroPadding = function(s, len) { + if (s.length >= len) return s; + return new Array(len - s.length + 1).join('0') + s; + }; + + // --- PUBLIC METHODS -------------------- + /** + * get string value of this string object + * @name getString + * @memberOf KJUR.asn1.DERAbstractTime# + * @function + * @return {String} string value of this time object + */ + this.getString = function() { + return this.s; + }; + + /** + * set value by a string + * @name setString + * @memberOf KJUR.asn1.DERAbstractTime# + * @function + * @param {String} newS value by a string to set such like "130430235959Z" + */ + this.setString = function(newS) { + this.hTLV = null; + this.isModified = true; + this.s = newS; + this.hV = stohex(newS); + }; + + /** + * set value by a Date object + * @name setByDateValue + * @memberOf KJUR.asn1.DERAbstractTime# + * @function + * @param {Integer} year year of date (ex. 2013) + * @param {Integer} month month of date between 1 and 12 (ex. 12) + * @param {Integer} day day of month + * @param {Integer} hour hours of date + * @param {Integer} min minutes of date + * @param {Integer} sec seconds of date + */ + this.setByDateValue = function(year, month, day, hour, min, sec) { + var dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0)); + this.setByDate(dateObject); + }; + + this.getFreshValueHex = function() { + return this.hV; + }; +}; +YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object); +// == END DERAbstractTime ================================================== + +// == BEGIN DERAbstractStructured ============================================ +/** + * base class for ASN.1 DER structured class + * @name KJUR.asn1.DERAbstractStructured + * @class base class for ASN.1 DER structured class + * @property {Array} asn1Array internal array of ASN1Object + * @extends KJUR.asn1.ASN1Object + * @description + * @see KJUR.asn1.ASN1Object - superclass + */ +KJUR.asn1.DERAbstractStructured = function(params) { + KJUR.asn1.DERAbstractString.superclass.constructor.call(this); + + /** + * set value by array of ASN1Object + * @name setByASN1ObjectArray + * @memberOf KJUR.asn1.DERAbstractStructured# + * @function + * @param {array} asn1ObjectArray array of ASN1Object to set + */ + this.setByASN1ObjectArray = function(asn1ObjectArray) { + this.hTLV = null; + this.isModified = true; + this.asn1Array = asn1ObjectArray; + }; + + /** + * append an ASN1Object to internal array + * @name appendASN1Object + * @memberOf KJUR.asn1.DERAbstractStructured# + * @function + * @param {ASN1Object} asn1Object to add + */ + this.appendASN1Object = function(asn1Object) { + this.hTLV = null; + this.isModified = true; + this.asn1Array.push(asn1Object); + }; + + this.asn1Array = new Array(); + if (typeof params != "undefined") { + if (typeof params['array'] != "undefined") { + this.asn1Array = params['array']; + } + } +}; +YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object); + + +// ******************************************************************** +// ASN.1 Object Classes +// ******************************************************************** + +// ******************************************************************** +/** + * class for ASN.1 DER Boolean + * @name KJUR.asn1.DERBoolean + * @class class for ASN.1 DER Boolean + * @extends KJUR.asn1.ASN1Object + * @description + * @see KJUR.asn1.ASN1Object - superclass + */ +KJUR.asn1.DERBoolean = function() { + KJUR.asn1.DERBoolean.superclass.constructor.call(this); + this.hT = "01"; + this.hTLV = "0101ff"; +}; +YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object); + +// ******************************************************************** +/** + * class for ASN.1 DER Integer + * @name KJUR.asn1.DERInteger + * @class class for ASN.1 DER Integer + * @extends KJUR.asn1.ASN1Object + * @description + *
+ * As for argument 'params' for constructor, you can specify one of + * following properties: + *
    + *
  • int - specify initial ASN.1 value(V) by integer value
  • + *
  • bigint - specify initial ASN.1 value(V) by BigInteger object
  • + *
  • hex - specify initial ASN.1 value(V) by a hexadecimal string
  • + *
+ * NOTE: 'params' can be omitted. + */ +KJUR.asn1.DERInteger = function(params) { + KJUR.asn1.DERInteger.superclass.constructor.call(this); + this.hT = "02"; + + /** + * set value by Tom Wu's BigInteger object + * @name setByBigInteger + * @memberOf KJUR.asn1.DERInteger# + * @function + * @param {BigInteger} bigIntegerValue to set + */ + this.setByBigInteger = function(bigIntegerValue) { + this.hTLV = null; + this.isModified = true; + this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue); + }; + + /** + * set value by integer value + * @name setByInteger + * @memberOf KJUR.asn1.DERInteger + * @function + * @param {Integer} integer value to set + */ + this.setByInteger = function(intValue) { + var bi = new BigInteger(String(intValue), 10); + this.setByBigInteger(bi); + }; + + /** + * set value by integer value + * @name setValueHex + * @memberOf KJUR.asn1.DERInteger# + * @function + * @param {String} hexadecimal string of integer value + * @description + *
+ * NOTE: Value shall be represented by minimum octet length of + * two's complement representation. + * @example + * new KJUR.asn1.DERInteger(123); + * new KJUR.asn1.DERInteger({'int': 123}); + * new KJUR.asn1.DERInteger({'hex': '1fad'}); + */ + this.setValueHex = function(newHexString) { + this.hV = newHexString; + }; + + this.getFreshValueHex = function() { + return this.hV; + }; + + if (typeof params != "undefined") { + if (typeof params['bigint'] != "undefined") { + this.setByBigInteger(params['bigint']); + } else if (typeof params['int'] != "undefined") { + this.setByInteger(params['int']); + } else if (typeof params == "number") { + this.setByInteger(params); + } else if (typeof params['hex'] != "undefined") { + this.setValueHex(params['hex']); + } + } +}; +YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object); + +// ******************************************************************** +/** + * class for ASN.1 DER encoded BitString primitive + * @name KJUR.asn1.DERBitString + * @class class for ASN.1 DER encoded BitString primitive + * @extends KJUR.asn1.ASN1Object + * @description + *
+ * As for argument 'params' for constructor, you can specify one of + * following properties: + *
    + *
  • bin - specify binary string (ex. '10111')
  • + *
  • array - specify array of boolean (ex. [true,false,true,true])
  • + *
  • hex - specify hexadecimal string of ASN.1 value(V) including unused bits
  • + *
  • obj - specify {@link KJUR.asn1.ASN1Util.newObject} + * argument for "BitString encapsulates" structure.
  • + *
+ * NOTE1: 'params' can be omitted.
+ * NOTE2: 'obj' parameter have been supported since + * asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).
+ * @example + * // default constructor + * o = new KJUR.asn1.DERBitString(); + * // initialize with binary string + * o = new KJUR.asn1.DERBitString({bin: "1011"}); + * // initialize with boolean array + * o = new KJUR.asn1.DERBitString({array: [true,false,true,true]}); + * // initialize with hexadecimal string (04 is unused bits) + * o = new KJUR.asn1.DEROctetString({hex: "04bac0"}); + * // initialize with ASN1Util.newObject argument for encapsulated + * o = new KJUR.asn1.DERBitString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}}); + * // above generates a ASN.1 data like this: + * // BIT STRING, encapsulates { + * // SEQUENCE { + * // INTEGER 3 + * // PrintableString 'aaa' + * // } + * // } + */ +KJUR.asn1.DERBitString = function(params) { + if (params !== undefined && typeof params.obj !== "undefined") { + var o = KJUR.asn1.ASN1Util.newObject(params.obj); + params.hex = "00" + o.getEncodedHex(); + } + KJUR.asn1.DERBitString.superclass.constructor.call(this); + this.hT = "03"; + + /** + * set ASN.1 value(V) by a hexadecimal string including unused bits + * @name setHexValueIncludingUnusedBits + * @memberOf KJUR.asn1.DERBitString# + * @function + * @param {String} newHexStringIncludingUnusedBits + */ + this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) { + this.hTLV = null; + this.isModified = true; + this.hV = newHexStringIncludingUnusedBits; + }; + + /** + * set ASN.1 value(V) by unused bit and hexadecimal string of value + * @name setUnusedBitsAndHexValue + * @memberOf KJUR.asn1.DERBitString# + * @function + * @param {Integer} unusedBits + * @param {String} hValue + */ + this.setUnusedBitsAndHexValue = function(unusedBits, hValue) { + if (unusedBits < 0 || 7 < unusedBits) { + throw "unused bits shall be from 0 to 7: u = " + unusedBits; + } + var hUnusedBits = "0" + unusedBits; + this.hTLV = null; + this.isModified = true; + this.hV = hUnusedBits + hValue; + }; + + /** + * set ASN.1 DER BitString by binary string
+ * @name setByBinaryString + * @memberOf KJUR.asn1.DERBitString# + * @function + * @param {String} binaryString binary value string (i.e. '10111') + * @description + * Its unused bits will be calculated automatically by length of + * 'binaryValue'.
+ * NOTE: Trailing zeros '0' will be ignored. + * @example + * o = new KJUR.asn1.DERBitString(); + * o.setByBooleanArray("01011"); + */ + this.setByBinaryString = function(binaryString) { + binaryString = binaryString.replace(/0+$/, ''); + var unusedBits = 8 - binaryString.length % 8; + if (unusedBits == 8) unusedBits = 0; + for (var i = 0; i <= unusedBits; i++) { + binaryString += '0'; + } + var h = ''; + for (var i = 0; i < binaryString.length - 1; i += 8) { + var b = binaryString.substr(i, 8); + var x = parseInt(b, 2).toString(16); + if (x.length == 1) x = '0' + x; + h += x; + } + this.hTLV = null; + this.isModified = true; + this.hV = '0' + unusedBits + h; + }; + + /** + * set ASN.1 TLV value(V) by an array of boolean
+ * @name setByBooleanArray + * @memberOf KJUR.asn1.DERBitString# + * @function + * @param {array} booleanArray array of boolean (ex. [true, false, true]) + * @description + * NOTE: Trailing falses will be ignored in the ASN.1 DER Object. + * @example + * o = new KJUR.asn1.DERBitString(); + * o.setByBooleanArray([false, true, false, true, true]); + */ + this.setByBooleanArray = function(booleanArray) { + var s = ''; + for (var i = 0; i < booleanArray.length; i++) { + if (booleanArray[i] == true) { + s += '1'; + } else { + s += '0'; + } + } + this.setByBinaryString(s); + }; + + /** + * generate an array of falses with specified length
+ * @name newFalseArray + * @memberOf KJUR.asn1.DERBitString + * @function + * @param {Integer} nLength length of array to generate + * @return {array} array of boolean falses + * @description + * This static method may be useful to initialize boolean array. + * @example + * o = new KJUR.asn1.DERBitString(); + * o.newFalseArray(3) → [false, false, false] + */ + this.newFalseArray = function(nLength) { + var a = new Array(nLength); + for (var i = 0; i < nLength; i++) { + a[i] = false; + } + return a; + }; + + this.getFreshValueHex = function() { + return this.hV; + }; + + if (typeof params != "undefined") { + if (typeof params == "string" && params.toLowerCase().match(/^[0-9a-f]+$/)) { + this.setHexValueIncludingUnusedBits(params); + } else if (typeof params['hex'] != "undefined") { + this.setHexValueIncludingUnusedBits(params['hex']); + } else if (typeof params['bin'] != "undefined") { + this.setByBinaryString(params['bin']); + } else if (typeof params['array'] != "undefined") { + this.setByBooleanArray(params['array']); + } + } +}; +YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object); + +// ******************************************************************** +/** + * class for ASN.1 DER OctetString
+ * @name KJUR.asn1.DEROctetString + * @class class for ASN.1 DER OctetString + * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) + * @extends KJUR.asn1.DERAbstractString + * @description + * This class provides ASN.1 OctetString simple type.
+ * Supported "params" attributes are: + *
    + *
  • str - to set a string as a value
  • + *
  • hex - to set a hexadecimal string as a value
  • + *
  • obj - to set a encapsulated ASN.1 value by JSON object + * which is defined in {@link KJUR.asn1.ASN1Util.newObject}
  • + *
+ * NOTE: A parameter 'obj' have been supported + * for "OCTET STRING, encapsulates" structure. + * since asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25). + * @see KJUR.asn1.DERAbstractString - superclass + * @example + * // default constructor + * o = new KJUR.asn1.DEROctetString(); + * // initialize with string + * o = new KJUR.asn1.DEROctetString({str: "aaa"}); + * // initialize with hexadecimal string + * o = new KJUR.asn1.DEROctetString({hex: "616161"}); + * // initialize with ASN1Util.newObject argument + * o = new KJUR.asn1.DEROctetString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}}); + * // above generates a ASN.1 data like this: + * // OCTET STRING, encapsulates { + * // SEQUENCE { + * // INTEGER 3 + * // PrintableString 'aaa' + * // } + * // } + */ +KJUR.asn1.DEROctetString = function(params) { + if (params !== undefined && typeof params.obj !== "undefined") { + var o = KJUR.asn1.ASN1Util.newObject(params.obj); + params.hex = o.getEncodedHex(); + } + KJUR.asn1.DEROctetString.superclass.constructor.call(this, params); + this.hT = "04"; +}; +YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString); + +// ******************************************************************** +/** + * class for ASN.1 DER Null + * @name KJUR.asn1.DERNull + * @class class for ASN.1 DER Null + * @extends KJUR.asn1.ASN1Object + * @description + * @see KJUR.asn1.ASN1Object - superclass + */ +KJUR.asn1.DERNull = function() { + KJUR.asn1.DERNull.superclass.constructor.call(this); + this.hT = "05"; + this.hTLV = "0500"; +}; +YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object); + +// ******************************************************************** +/** + * class for ASN.1 DER ObjectIdentifier + * @name KJUR.asn1.DERObjectIdentifier + * @class class for ASN.1 DER ObjectIdentifier + * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'}) + * @extends KJUR.asn1.ASN1Object + * @description + *
+ * As for argument 'params' for constructor, you can specify one of + * following properties: + *
    + *
  • oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)
  • + *
  • hex - specify initial ASN.1 value(V) by a hexadecimal string
  • + *
+ * NOTE: 'params' can be omitted. + */ +KJUR.asn1.DERObjectIdentifier = function(params) { + var itox = function(i) { + var h = i.toString(16); + if (h.length == 1) h = '0' + h; + return h; + }; + var roidtox = function(roid) { + var h = ''; + var bi = new BigInteger(roid, 10); + var b = bi.toString(2); + var padLen = 7 - b.length % 7; + if (padLen == 7) padLen = 0; + var bPad = ''; + for (var i = 0; i < padLen; i++) bPad += '0'; + b = bPad + b; + for (var i = 0; i < b.length - 1; i += 7) { + var b8 = b.substr(i, 7); + if (i != b.length - 7) b8 = '1' + b8; + h += itox(parseInt(b8, 2)); + } + return h; + }; + + KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this); + this.hT = "06"; + + /** + * set value by a hexadecimal string + * @name setValueHex + * @memberOf KJUR.asn1.DERObjectIdentifier# + * @function + * @param {String} newHexString hexadecimal value of OID bytes + */ + this.setValueHex = function(newHexString) { + this.hTLV = null; + this.isModified = true; + this.s = null; + this.hV = newHexString; + }; + + /** + * set value by a OID string
+ * @name setValueOidString + * @memberOf KJUR.asn1.DERObjectIdentifier# + * @function + * @param {String} oidString OID string (ex. 2.5.4.13) + * @example + * o = new KJUR.asn1.DERObjectIdentifier(); + * o.setValueOidString("2.5.4.13"); + */ + this.setValueOidString = function(oidString) { + if (! oidString.match(/^[0-9.]+$/)) { + throw "malformed oid string: " + oidString; + } + var h = ''; + var a = oidString.split('.'); + var i0 = parseInt(a[0]) * 40 + parseInt(a[1]); + h += itox(i0); + a.splice(0, 2); + for (var i = 0; i < a.length; i++) { + h += roidtox(a[i]); + } + this.hTLV = null; + this.isModified = true; + this.s = null; + this.hV = h; + }; + + /** + * set value by a OID name + * @name setValueName + * @memberOf KJUR.asn1.DERObjectIdentifier# + * @function + * @param {String} oidName OID name (ex. 'serverAuth') + * @since 1.0.1 + * @description + * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'. + * Otherwise raise error. + * @example + * o = new KJUR.asn1.DERObjectIdentifier(); + * o.setValueName("serverAuth"); + */ + this.setValueName = function(oidName) { + var oid = KJUR.asn1.x509.OID.name2oid(oidName); + if (oid !== '') { + this.setValueOidString(oid); + } else { + throw "DERObjectIdentifier oidName undefined: " + oidName; + } + }; + + this.getFreshValueHex = function() { + return this.hV; + }; + + if (params !== undefined) { + if (typeof params === "string") { + if (params.match(/^[0-2].[0-9.]+$/)) { + this.setValueOidString(params); + } else { + this.setValueName(params); + } + } else if (params.oid !== undefined) { + this.setValueOidString(params.oid); + } else if (params.hex !== undefined) { + this.setValueHex(params.hex); + } else if (params.name !== undefined) { + this.setValueName(params.name); + } + } +}; +YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object); + +// ******************************************************************** +/** + * class for ASN.1 DER Enumerated + * @name KJUR.asn1.DEREnumerated + * @class class for ASN.1 DER Enumerated + * @extends KJUR.asn1.ASN1Object + * @description + *
+ * As for argument 'params' for constructor, you can specify one of + * following properties: + *
    + *
  • int - specify initial ASN.1 value(V) by integer value
  • + *
  • hex - specify initial ASN.1 value(V) by a hexadecimal string
  • + *
+ * NOTE: 'params' can be omitted. + * @example + * new KJUR.asn1.DEREnumerated(123); + * new KJUR.asn1.DEREnumerated({int: 123}); + * new KJUR.asn1.DEREnumerated({hex: '1fad'}); + */ +KJUR.asn1.DEREnumerated = function(params) { + KJUR.asn1.DEREnumerated.superclass.constructor.call(this); + this.hT = "0a"; + + /** + * set value by Tom Wu's BigInteger object + * @name setByBigInteger + * @memberOf KJUR.asn1.DEREnumerated# + * @function + * @param {BigInteger} bigIntegerValue to set + */ + this.setByBigInteger = function(bigIntegerValue) { + this.hTLV = null; + this.isModified = true; + this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue); + }; + + /** + * set value by integer value + * @name setByInteger + * @memberOf KJUR.asn1.DEREnumerated# + * @function + * @param {Integer} integer value to set + */ + this.setByInteger = function(intValue) { + var bi = new BigInteger(String(intValue), 10); + this.setByBigInteger(bi); + }; + + /** + * set value by integer value + * @name setValueHex + * @memberOf KJUR.asn1.DEREnumerated# + * @function + * @param {String} hexadecimal string of integer value + * @description + *
+ * NOTE: Value shall be represented by minimum octet length of + * two's complement representation. + */ + this.setValueHex = function(newHexString) { + this.hV = newHexString; + }; + + this.getFreshValueHex = function() { + return this.hV; + }; + + if (typeof params != "undefined") { + if (typeof params['int'] != "undefined") { + this.setByInteger(params['int']); + } else if (typeof params == "number") { + this.setByInteger(params); + } else if (typeof params['hex'] != "undefined") { + this.setValueHex(params['hex']); + } + } +}; +YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object); + +// ******************************************************************** +/** + * class for ASN.1 DER UTF8String + * @name KJUR.asn1.DERUTF8String + * @class class for ASN.1 DER UTF8String + * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) + * @extends KJUR.asn1.DERAbstractString + * @description + * @see KJUR.asn1.DERAbstractString - superclass + */ +KJUR.asn1.DERUTF8String = function(params) { + KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params); + this.hT = "0c"; +}; +YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString); + +// ******************************************************************** +/** + * class for ASN.1 DER NumericString + * @name KJUR.asn1.DERNumericString + * @class class for ASN.1 DER NumericString + * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) + * @extends KJUR.asn1.DERAbstractString + * @description + * @see KJUR.asn1.DERAbstractString - superclass + */ +KJUR.asn1.DERNumericString = function(params) { + KJUR.asn1.DERNumericString.superclass.constructor.call(this, params); + this.hT = "12"; +}; +YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString); + +// ******************************************************************** +/** + * class for ASN.1 DER PrintableString + * @name KJUR.asn1.DERPrintableString + * @class class for ASN.1 DER PrintableString + * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) + * @extends KJUR.asn1.DERAbstractString + * @description + * @see KJUR.asn1.DERAbstractString - superclass + */ +KJUR.asn1.DERPrintableString = function(params) { + KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params); + this.hT = "13"; +}; +YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString); + +// ******************************************************************** +/** + * class for ASN.1 DER TeletexString + * @name KJUR.asn1.DERTeletexString + * @class class for ASN.1 DER TeletexString + * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) + * @extends KJUR.asn1.DERAbstractString + * @description + * @see KJUR.asn1.DERAbstractString - superclass + */ +KJUR.asn1.DERTeletexString = function(params) { + KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params); + this.hT = "14"; +}; +YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString); + +// ******************************************************************** +/** + * class for ASN.1 DER IA5String + * @name KJUR.asn1.DERIA5String + * @class class for ASN.1 DER IA5String + * @param {Array} params associative array of parameters (ex. {'str': 'aaa'}) + * @extends KJUR.asn1.DERAbstractString + * @description + * @see KJUR.asn1.DERAbstractString - superclass + */ +KJUR.asn1.DERIA5String = function(params) { + KJUR.asn1.DERIA5String.superclass.constructor.call(this, params); + this.hT = "16"; +}; +YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString); + +// ******************************************************************** +/** + * class for ASN.1 DER UTCTime + * @name KJUR.asn1.DERUTCTime + * @class class for ASN.1 DER UTCTime + * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'}) + * @extends KJUR.asn1.DERAbstractTime + * @description + *
+ * As for argument 'params' for constructor, you can specify one of + * following properties: + *
    + *
  • str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')
  • + *
  • hex - specify initial ASN.1 value(V) by a hexadecimal string
  • + *
  • date - specify Date object.
  • + *
+ * NOTE: 'params' can be omitted. + *

EXAMPLES

+ * @example + * d1 = new KJUR.asn1.DERUTCTime(); + * d1.setString('130430125959Z'); + * + * d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'}); + * d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))}); + * d4 = new KJUR.asn1.DERUTCTime('130430125959Z'); + */ +KJUR.asn1.DERUTCTime = function(params) { + KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params); + this.hT = "17"; + + /** + * set value by a Date object
+ * @name setByDate + * @memberOf KJUR.asn1.DERUTCTime# + * @function + * @param {Date} dateObject Date object to set ASN.1 value(V) + * @example + * o = new KJUR.asn1.DERUTCTime(); + * o.setByDate(new Date("2016/12/31")); + */ + this.setByDate = function(dateObject) { + this.hTLV = null; + this.isModified = true; + this.date = dateObject; + this.s = this.formatDate(this.date, 'utc'); + this.hV = stohex(this.s); + }; + + this.getFreshValueHex = function() { + if (typeof this.date == "undefined" && typeof this.s == "undefined") { + this.date = new Date(); + this.s = this.formatDate(this.date, 'utc'); + this.hV = stohex(this.s); + } + return this.hV; + }; + + if (params !== undefined) { + if (params.str !== undefined) { + this.setString(params.str); + } else if (typeof params == "string" && params.match(/^[0-9]{12}Z$/)) { + this.setString(params); + } else if (params.hex !== undefined) { + this.setStringHex(params.hex); + } else if (params.date !== undefined) { + this.setByDate(params.date); + } + } +}; +YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime); + +// ******************************************************************** +/** + * class for ASN.1 DER GeneralizedTime + * @name KJUR.asn1.DERGeneralizedTime + * @class class for ASN.1 DER GeneralizedTime + * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'}) + * @property {Boolean} withMillis flag to show milliseconds or not + * @extends KJUR.asn1.DERAbstractTime + * @description + *
+ * As for argument 'params' for constructor, you can specify one of + * following properties: + *
    + *
  • str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')
  • + *
  • hex - specify initial ASN.1 value(V) by a hexadecimal string
  • + *
  • date - specify Date object.
  • + *
  • millis - specify flag to show milliseconds (from 1.0.6)
  • + *
+ * NOTE1: 'params' can be omitted. + * NOTE2: 'withMillis' property is supported from asn1 1.0.6. + */ +KJUR.asn1.DERGeneralizedTime = function(params) { + KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params); + this.hT = "18"; + this.withMillis = false; + + /** + * set value by a Date object + * @name setByDate + * @memberOf KJUR.asn1.DERGeneralizedTime# + * @function + * @param {Date} dateObject Date object to set ASN.1 value(V) + * @example + * When you specify UTC time, use 'Date.UTC' method like this:
+ * o1 = new DERUTCTime(); + * o1.setByDate(date); + * + * date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59 + */ + this.setByDate = function(dateObject) { + this.hTLV = null; + this.isModified = true; + this.date = dateObject; + this.s = this.formatDate(this.date, 'gen', this.withMillis); + this.hV = stohex(this.s); + }; + + this.getFreshValueHex = function() { + if (this.date === undefined && this.s === undefined) { + this.date = new Date(); + this.s = this.formatDate(this.date, 'gen', this.withMillis); + this.hV = stohex(this.s); + } + return this.hV; + }; + + if (params !== undefined) { + if (params.str !== undefined) { + this.setString(params.str); + } else if (typeof params == "string" && params.match(/^[0-9]{14}Z$/)) { + this.setString(params); + } else if (params.hex !== undefined) { + this.setStringHex(params.hex); + } else if (params.date !== undefined) { + this.setByDate(params.date); + } + if (params.millis === true) { + this.withMillis = true; + } + } +}; +YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime); + +// ******************************************************************** +/** + * class for ASN.1 DER Sequence + * @name KJUR.asn1.DERSequence + * @class class for ASN.1 DER Sequence + * @extends KJUR.asn1.DERAbstractStructured + * @description + *
+ * As for argument 'params' for constructor, you can specify one of + * following properties: + *
    + *
  • array - specify array of ASN1Object to set elements of content
  • + *
+ * NOTE: 'params' can be omitted. + */ +KJUR.asn1.DERSequence = function(params) { + KJUR.asn1.DERSequence.superclass.constructor.call(this, params); + this.hT = "30"; + this.getFreshValueHex = function() { + var h = ''; + for (var i = 0; i < this.asn1Array.length; i++) { + var asn1Obj = this.asn1Array[i]; + h += asn1Obj.getEncodedHex(); + } + this.hV = h; + return this.hV; + }; +}; +YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured); + +// ******************************************************************** +/** + * class for ASN.1 DER Set + * @name KJUR.asn1.DERSet + * @class class for ASN.1 DER Set + * @extends KJUR.asn1.DERAbstractStructured + * @description + *
+ * As for argument 'params' for constructor, you can specify one of + * following properties: + *
    + *
  • array - specify array of ASN1Object to set elements of content
  • + *
  • sortflag - flag for sort (default: true). ASN.1 BER is not sorted in 'SET OF'.
  • + *
+ * NOTE1: 'params' can be omitted.
+ * NOTE2: sortflag is supported since 1.0.5. + */ +KJUR.asn1.DERSet = function(params) { + KJUR.asn1.DERSet.superclass.constructor.call(this, params); + this.hT = "31"; + this.sortFlag = true; // item shall be sorted only in ASN.1 DER + this.getFreshValueHex = function() { + var a = new Array(); + for (var i = 0; i < this.asn1Array.length; i++) { + var asn1Obj = this.asn1Array[i]; + a.push(asn1Obj.getEncodedHex()); + } + if (this.sortFlag == true) a.sort(); + this.hV = a.join(''); + return this.hV; + }; + + if (typeof params != "undefined") { + if (typeof params.sortflag != "undefined" && + params.sortflag == false) + this.sortFlag = false; + } +}; +YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured); + +// ******************************************************************** +/** + * class for ASN.1 DER TaggedObject + * @name KJUR.asn1.DERTaggedObject + * @class class for ASN.1 DER TaggedObject + * @extends KJUR.asn1.ASN1Object + * @description + *
+ * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object. + * For example, if you find '[1]' tag in a ASN.1 dump, + * 'tagNoHex' will be 'a1'. + *
+ * As for optional argument 'params' for constructor, you can specify *ANY* of + * following properties: + *
    + *
  • explicit - specify true if this is explicit tag otherwise false + * (default is 'true').
  • + *
  • tag - specify tag (default is 'a0' which means [0])
  • + *
  • obj - specify ASN1Object which is tagged
  • + *
+ * @example + * d1 = new KJUR.asn1.DERUTF8String({'str':'a'}); + * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1}); + * hex = d2.getEncodedHex(); + */ +KJUR.asn1.DERTaggedObject = function(params) { + KJUR.asn1.DERTaggedObject.superclass.constructor.call(this); + this.hT = "a0"; + this.hV = ''; + this.isExplicit = true; + this.asn1Object = null; + + /** + * set value by an ASN1Object + * @name setString + * @memberOf KJUR.asn1.DERTaggedObject# + * @function + * @param {Boolean} isExplicitFlag flag for explicit/implicit tag + * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag + * @param {ASN1Object} asn1Object ASN.1 to encapsulate + */ + this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) { + this.hT = tagNoHex; + this.isExplicit = isExplicitFlag; + this.asn1Object = asn1Object; + if (this.isExplicit) { + this.hV = this.asn1Object.getEncodedHex(); + this.hTLV = null; + this.isModified = true; + } else { + this.hV = null; + this.hTLV = asn1Object.getEncodedHex(); + this.hTLV = this.hTLV.replace(/^../, tagNoHex); + this.isModified = false; + } + }; + + this.getFreshValueHex = function() { + return this.hV; + }; + + if (typeof params != "undefined") { + if (typeof params['tag'] != "undefined") { + this.hT = params['tag']; + } + if (typeof params['explicit'] != "undefined") { + this.isExplicit = params['explicit']; + } + if (typeof params['obj'] != "undefined") { + this.asn1Object = params['obj']; + this.setASN1Object(this.isExplicit, this.hT, this.asn1Object); + } + } +}; +YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object); + +/** + * Create a new JSEncryptRSAKey that extends Tom Wu's RSA key object. + * This object is just a decorator for parsing the key parameter + * @param {string|Object} key - The key in string format, or an object containing + * the parameters needed to build a RSAKey object. + * @constructor + */ +var JSEncryptRSAKey = /** @class */ (function (_super) { + __extends(JSEncryptRSAKey, _super); + function JSEncryptRSAKey(key) { + var _this = _super.call(this) || this; + // Call the super constructor. + // RSAKey.call(this); + // If a key key was provided. + if (key) { + // If this is a string... + if (typeof key === "string") { + _this.parseKey(key); + } + else if (JSEncryptRSAKey.hasPrivateKeyProperty(key) || + JSEncryptRSAKey.hasPublicKeyProperty(key)) { + // Set the values for the key. + _this.parsePropertiesFrom(key); + } + } + return _this; + } + /** + * Method to parse a pem encoded string containing both a public or private key. + * The method will translate the pem encoded string in a der encoded string and + * will parse private key and public key parameters. This method accepts public key + * in the rsaencryption pkcs #1 format (oid: 1.2.840.113549.1.1.1). + * + * @todo Check how many rsa formats use the same format of pkcs #1. + * + * The format is defined as: + * PublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * PublicKey BIT STRING + * } + * Where AlgorithmIdentifier is: + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, the OID of the enc algorithm + * parameters ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1) + * } + * and PublicKey is a SEQUENCE encapsulated in a BIT STRING + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + * it's possible to examine the structure of the keys obtained from openssl using + * an asn.1 dumper as the one used here to parse the components: http://lapo.it/asn1js/ + * @argument {string} pem the pem encoded string, can include the BEGIN/END header/footer + * @private + */ + JSEncryptRSAKey.prototype.parseKey = function (pem) { + try { + var modulus = 0; + var public_exponent = 0; + var reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/; + var der = reHex.test(pem) ? Hex.decode(pem) : Base64.unarmor(pem); + var asn1 = ASN1.decode(der); + // Fixes a bug with OpenSSL 1.0+ private keys + if (asn1.sub.length === 3) { + asn1 = asn1.sub[2].sub[0]; + } + if (asn1.sub.length === 9) { + // Parse the private key. + modulus = asn1.sub[1].getHexStringValue(); // bigint + this.n = parseBigInt(modulus, 16); + public_exponent = asn1.sub[2].getHexStringValue(); // int + this.e = parseInt(public_exponent, 16); + var private_exponent = asn1.sub[3].getHexStringValue(); // bigint + this.d = parseBigInt(private_exponent, 16); + var prime1 = asn1.sub[4].getHexStringValue(); // bigint + this.p = parseBigInt(prime1, 16); + var prime2 = asn1.sub[5].getHexStringValue(); // bigint + this.q = parseBigInt(prime2, 16); + var exponent1 = asn1.sub[6].getHexStringValue(); // bigint + this.dmp1 = parseBigInt(exponent1, 16); + var exponent2 = asn1.sub[7].getHexStringValue(); // bigint + this.dmq1 = parseBigInt(exponent2, 16); + var coefficient = asn1.sub[8].getHexStringValue(); // bigint + this.coeff = parseBigInt(coefficient, 16); + } + else if (asn1.sub.length === 2) { + // Parse the public key. + var bit_string = asn1.sub[1]; + var sequence = bit_string.sub[0]; + modulus = sequence.sub[0].getHexStringValue(); + this.n = parseBigInt(modulus, 16); + public_exponent = sequence.sub[1].getHexStringValue(); + this.e = parseInt(public_exponent, 16); + } + else { + return false; + } + return true; + } + catch (ex) { + return false; + } + }; + /** + * Translate rsa parameters in a hex encoded string representing the rsa key. + * + * The translation follow the ASN.1 notation : + * RSAPrivateKey ::= SEQUENCE { + * version Version, + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * } + * @returns {string} DER Encoded String representing the rsa private key + * @private + */ + JSEncryptRSAKey.prototype.getPrivateBaseKey = function () { + var options = { + array: [ + new KJUR.asn1.DERInteger({ int: 0 }), + new KJUR.asn1.DERInteger({ bigint: this.n }), + new KJUR.asn1.DERInteger({ int: this.e }), + new KJUR.asn1.DERInteger({ bigint: this.d }), + new KJUR.asn1.DERInteger({ bigint: this.p }), + new KJUR.asn1.DERInteger({ bigint: this.q }), + new KJUR.asn1.DERInteger({ bigint: this.dmp1 }), + new KJUR.asn1.DERInteger({ bigint: this.dmq1 }), + new KJUR.asn1.DERInteger({ bigint: this.coeff }) + ] + }; + var seq = new KJUR.asn1.DERSequence(options); + return seq.getEncodedHex(); + }; + /** + * base64 (pem) encoded version of the DER encoded representation + * @returns {string} pem encoded representation without header and footer + * @public + */ + JSEncryptRSAKey.prototype.getPrivateBaseKeyB64 = function () { + return hex2b64(this.getPrivateBaseKey()); + }; + /** + * Translate rsa parameters in a hex encoded string representing the rsa public key. + * The representation follow the ASN.1 notation : + * PublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * PublicKey BIT STRING + * } + * Where AlgorithmIdentifier is: + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, the OID of the enc algorithm + * parameters ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1) + * } + * and PublicKey is a SEQUENCE encapsulated in a BIT STRING + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + * @returns {string} DER Encoded String representing the rsa public key + * @private + */ + JSEncryptRSAKey.prototype.getPublicBaseKey = function () { + var first_sequence = new KJUR.asn1.DERSequence({ + array: [ + new KJUR.asn1.DERObjectIdentifier({ oid: "1.2.840.113549.1.1.1" }), + new KJUR.asn1.DERNull() + ] + }); + var second_sequence = new KJUR.asn1.DERSequence({ + array: [ + new KJUR.asn1.DERInteger({ bigint: this.n }), + new KJUR.asn1.DERInteger({ int: this.e }) + ] + }); + var bit_string = new KJUR.asn1.DERBitString({ + hex: "00" + second_sequence.getEncodedHex() + }); + var seq = new KJUR.asn1.DERSequence({ + array: [ + first_sequence, + bit_string + ] + }); + return seq.getEncodedHex(); + }; + /** + * base64 (pem) encoded version of the DER encoded representation + * @returns {string} pem encoded representation without header and footer + * @public + */ + JSEncryptRSAKey.prototype.getPublicBaseKeyB64 = function () { + return hex2b64(this.getPublicBaseKey()); + }; + /** + * wrap the string in block of width chars. The default value for rsa keys is 64 + * characters. + * @param {string} str the pem encoded string without header and footer + * @param {Number} [width=64] - the length the string has to be wrapped at + * @returns {string} + * @private + */ + JSEncryptRSAKey.wordwrap = function (str, width) { + width = width || 64; + if (!str) { + return str; + } + var regex = "(.{1," + width + "})( +|$\n?)|(.{1," + width + "})"; + return str.match(RegExp(regex, "g")).join("\n"); + }; + /** + * Retrieve the pem encoded private key + * @returns {string} the pem encoded private key with header/footer + * @public + */ + JSEncryptRSAKey.prototype.getPrivateKey = function () { + var key = "-----BEGIN RSA PRIVATE KEY-----\n"; + key += JSEncryptRSAKey.wordwrap(this.getPrivateBaseKeyB64()) + "\n"; + key += "-----END RSA PRIVATE KEY-----"; + return key; + }; + /** + * Retrieve the pem encoded public key + * @returns {string} the pem encoded public key with header/footer + * @public + */ + JSEncryptRSAKey.prototype.getPublicKey = function () { + var key = "-----BEGIN PUBLIC KEY-----\n"; + key += JSEncryptRSAKey.wordwrap(this.getPublicBaseKeyB64()) + "\n"; + key += "-----END PUBLIC KEY-----"; + return key; + }; + /** + * Check if the object contains the necessary parameters to populate the rsa modulus + * and public exponent parameters. + * @param {Object} [obj={}] - An object that may contain the two public key + * parameters + * @returns {boolean} true if the object contains both the modulus and the public exponent + * properties (n and e) + * @todo check for types of n and e. N should be a parseable bigInt object, E should + * be a parseable integer number + * @private + */ + JSEncryptRSAKey.hasPublicKeyProperty = function (obj) { + obj = obj || {}; + return (obj.hasOwnProperty("n") && + obj.hasOwnProperty("e")); + }; + /** + * Check if the object contains ALL the parameters of an RSA key. + * @param {Object} [obj={}] - An object that may contain nine rsa key + * parameters + * @returns {boolean} true if the object contains all the parameters needed + * @todo check for types of the parameters all the parameters but the public exponent + * should be parseable bigint objects, the public exponent should be a parseable integer number + * @private + */ + JSEncryptRSAKey.hasPrivateKeyProperty = function (obj) { + obj = obj || {}; + return (obj.hasOwnProperty("n") && + obj.hasOwnProperty("e") && + obj.hasOwnProperty("d") && + obj.hasOwnProperty("p") && + obj.hasOwnProperty("q") && + obj.hasOwnProperty("dmp1") && + obj.hasOwnProperty("dmq1") && + obj.hasOwnProperty("coeff")); + }; + /** + * Parse the properties of obj in the current rsa object. Obj should AT LEAST + * include the modulus and public exponent (n, e) parameters. + * @param {Object} obj - the object containing rsa parameters + * @private + */ + JSEncryptRSAKey.prototype.parsePropertiesFrom = function (obj) { + this.n = obj.n; + this.e = obj.e; + if (obj.hasOwnProperty("d")) { + this.d = obj.d; + this.p = obj.p; + this.q = obj.q; + this.dmp1 = obj.dmp1; + this.dmq1 = obj.dmq1; + this.coeff = obj.coeff; + } + }; + return JSEncryptRSAKey; +}(RSAKey)); + +/** + * + * @param {Object} [options = {}] - An object to customize JSEncrypt behaviour + * possible parameters are: + * - default_key_size {number} default: 1024 the key size in bit + * - default_public_exponent {string} default: '010001' the hexadecimal representation of the public exponent + * - log {boolean} default: false whether log warn/error or not + * @constructor + */ +var JSEncrypt = /** @class */ (function () { + function JSEncrypt(options) { + options = options || {}; + this.default_key_size = parseInt(options.default_key_size, 10) || 1024; + this.default_public_exponent = options.default_public_exponent || "010001"; // 65537 default openssl public exponent for rsa key type + this.log = options.log || false; + // The private and public key. + this.key = null; + } + /** + * Method to set the rsa key parameter (one method is enough to set both the public + * and the private key, since the private key contains the public key paramenters) + * Log a warning if logs are enabled + * @param {Object|string} key the pem encoded string or an object (with or without header/footer) + * @public + */ + JSEncrypt.prototype.setKey = function (key) { + if (this.log && this.key) { + console.warn("A key was already set, overriding existing."); + } + this.key = new JSEncryptRSAKey(key); + }; + /** + * Proxy method for setKey, for api compatibility + * @see setKey + * @public + */ + JSEncrypt.prototype.setPrivateKey = function (privkey) { + // Create the key. + this.setKey(privkey); + }; + /** + * Proxy method for setKey, for api compatibility + * @see setKey + * @public + */ + JSEncrypt.prototype.setPublicKey = function (pubkey) { + // Sets the public key. + this.setKey(pubkey); + }; + /** + * Proxy method for RSAKey object's decrypt, decrypt the string using the private + * components of the rsa key object. Note that if the object was not set will be created + * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor + * @param {string} str base64 encoded crypted string to decrypt + * @return {string} the decrypted string + * @public + */ + JSEncrypt.prototype.decrypt = function (str) { + // Return the decrypted string. + try { + return this.getKey().decrypt(b64tohex(str)); + } + catch (ex) { + return false; + } + }; + /** + * Proxy method for RSAKey object's encrypt, encrypt the string using the public + * components of the rsa key object. Note that if the object was not set will be created + * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor + * @param {string} str the string to encrypt + * @return {string} the encrypted string encoded in base64 + * @public + */ + JSEncrypt.prototype.encrypt = function (str) { + // Return the encrypted string. + try { + return hex2b64(this.getKey().encrypt(str)); + } + catch (ex) { + return false; + } + }; + /** + * Proxy method for RSAKey object's sign. + * @param {string} str the string to sign + * @param {function} digestMethod hash method + * @param {string} digestName the name of the hash algorithm + * @return {string} the signature encoded in base64 + * @public + */ + JSEncrypt.prototype.sign = function (str, digestMethod, digestName) { + // return the RSA signature of 'str' in 'hex' format. + try { + return hex2b64(this.getKey().sign(str, digestMethod, digestName)); + } + catch (ex) { + return false; + } + }; + /** + * Proxy method for RSAKey object's verify. + * @param {string} str the string to verify + * @param {string} signature the signature encoded in base64 to compare the string to + * @param {function} digestMethod hash method + * @return {boolean} whether the data and signature match + * @public + */ + JSEncrypt.prototype.verify = function (str, signature, digestMethod) { + // Return the decrypted 'digest' of the signature. + try { + return this.getKey().verify(str, b64tohex(signature), digestMethod); + } + catch (ex) { + return false; + } + }; + /** + * Getter for the current JSEncryptRSAKey object. If it doesn't exists a new object + * will be created and returned + * @param {callback} [cb] the callback to be called if we want the key to be generated + * in an async fashion + * @returns {JSEncryptRSAKey} the JSEncryptRSAKey object + * @public + */ + JSEncrypt.prototype.getKey = function (cb) { + // Only create new if it does not exist. + if (!this.key) { + // Get a new private key. + this.key = new JSEncryptRSAKey(); + if (cb && {}.toString.call(cb) === "[object Function]") { + this.key.generateAsync(this.default_key_size, this.default_public_exponent, cb); + return; + } + // Generate the key. + this.key.generate(this.default_key_size, this.default_public_exponent); + } + return this.key; + }; + /** + * Returns the pem encoded representation of the private key + * If the key doesn't exists a new key will be created + * @returns {string} pem encoded representation of the private key WITH header and footer + * @public + */ + JSEncrypt.prototype.getPrivateKey = function () { + // Return the private representation of this key. + return this.getKey().getPrivateKey(); + }; + /** + * Returns the pem encoded representation of the private key + * If the key doesn't exists a new key will be created + * @returns {string} pem encoded representation of the private key WITHOUT header and footer + * @public + */ + JSEncrypt.prototype.getPrivateKeyB64 = function () { + // Return the private representation of this key. + return this.getKey().getPrivateBaseKeyB64(); + }; + /** + * Returns the pem encoded representation of the public key + * If the key doesn't exists a new key will be created + * @returns {string} pem encoded representation of the public key WITH header and footer + * @public + */ + JSEncrypt.prototype.getPublicKey = function () { + // Return the private representation of this key. + return this.getKey().getPublicKey(); + }; + /** + * Returns the pem encoded representation of the public key + * If the key doesn't exists a new key will be created + * @returns {string} pem encoded representation of the public key WITHOUT header and footer + * @public + */ + JSEncrypt.prototype.getPublicKeyB64 = function () { + // Return the private representation of this key. + return this.getKey().getPublicBaseKeyB64(); + }; + JSEncrypt.version = "3.0.0-rc.1"; + return JSEncrypt; +}()); + +window.JSEncrypt = JSEncrypt; + +exports.JSEncrypt = JSEncrypt; +exports.default = JSEncrypt; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/d2d_app/client/js/myApps.js b/d2d_app/client/js/myApps.js new file mode 100755 index 0000000..9ea6114 --- /dev/null +++ b/d2d_app/client/js/myApps.js @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +"use strict"; +import { UpdateWebClip } from './app.js'; +import Actions from './actions.js'; + +const serverPort = 9000; +const serverURL = window.location.protocol + '//' + window.location.hostname; +const actions = new Actions(); +const NEW_WINDOW_TIMEOUT = 1000; +const myappsmodule = {}; + +(function () { + var xhr; + function emptyElement(elm) { + while (elm.firstChild) { + elm.removeChild(elm.firstChild); + } + return elm; + } + /** + * Open app in new window + * @param {Object} response + * @private + */ + function openAppWindow(response) { + document.getElementById("page-main").style.display = "none"; + var timer = setTimeout(function () { + clearTimeout(timer); + document.getElementById("page-main").style.display = "block"; + window.open(serverURL + ':' + response.port + '/app', 'newWindow'); + }, NEW_WINDOW_TIMEOUT); + }; + + function showListView(dataArray) { + var formResult = document.getElementById("d2dApps"), + imgResult = document.getElementById("d2dAppList"), + formObj, + imgObj, + textObj, + objTable, + objRow, + i, + d2dApp, + icon; + + emptyElement(imgResult); + + objTable = document.createElement("div"); + objTable.className = "result-table"; + + if (dataArray.length > 0) { + for (i = 0; i < dataArray.length; i++) { + formObj = document.createElement("div"); + imgObj = document.createElement("img"); + textObj = document.createElement("p"); + formObj.style.textAlign = "center"; + d2dApp = dataArray[i]['d2dApp']; + if (d2dApp.hasOwnProperty("appName")) { + if (d2dApp.iconPath) { + icon = d2dApp.iconPath.substring(d2dApp.iconPath.indexOf('/',10)+1); + imgObj.src = `/d2dIcon/${icon}`; + } else { + imgObj.src = `./images/icon.png`; + } + imgObj.className = "app-icon-img"; + imgObj.alt = d2dApp.appName; + textObj.style.display = "block"; + textObj.style.margin = "0 auto"; + textObj.style.fontSize = "14px"; + textObj.innerHTML = d2dApp.appName; + } + imgObj.addEventListener("click", actions.launchAppOnTV( + d2dApp.appPkgID, + d2dApp.appAppID, + function (response) { + openAppWindow(response); + })); + formObj.appendChild(imgObj); + formObj.appendChild(textObj); + + imgResult.appendChild(formObj); + } + formResult.appendChild(imgResult); + } else { + objRow = document.createElement("div"); + objRow.className = "result-table-error"; + objRow.appendChild(document.createTextNode("No Data")); + objTable.appendChild(objRow); + } + } + + function showList() { + xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === xhr.DONE) { + if (xhr.status === 200 || xhr.status === 201) { + showListView(JSON.parse(xhr.responseText)); + } else { + console.error(xhr.responseText); + } + } + }; + xhr.open('GET', serverURL + ':' + serverPort + '/appList'); + xhr.send(); + } + + function init() { + var eventSource = new EventSource(serverURL + ':' + serverPort + '/updateAppList'); + eventSource.addEventListener('message', evt => { + showListView(JSON.parse(evt.data)); + UpdateWebClip(JSON.parse(evt.data)); + }, false); + eventSource.addEventListener('open', evt => { + console.log("Connected to..."); + }, false); + eventSource.addEventListener('error', evt => { + if (evt.target.readyState == EventSource.CLOSED) { + console.log("Disconnected from..."); + } else if (evt.target.readyState == EventSource.CONNECTING) { + console.log('Connecting to...'); + } + }, false); + showList(); + } + window.onload = init; + myappsmodule.openAppWindow = openAppWindow; +}()); + +export function openAppWindow(response) { + myappsmodule.openAppWindow(response); +}; + diff --git a/d2d_app/client/js/pincode.js b/d2d_app/client/js/pincode.js new file mode 100755 index 0000000..c1a49fe --- /dev/null +++ b/d2d_app/client/js/pincode.js @@ -0,0 +1,99 @@ +const serverPort = 9000; +const serverURL = window.location.protocol + '//' + window.location.hostname; + +var publicKey; +var input = ''; +var dots = document.querySelectorAll('.dot'), numbers = document.querySelectorAll('.number'); + +function preloadKey() { + var xhr = new XMLHttpRequest(); + xhr.onload = function () { + if (xhr.status === 200 || xhr.status === 201) { + publicKey = xhr.responseText; + if (publicKey) { + init(); + } else { + console.error('[WT] Failed to get public key.'); + } + } else { + console.error(xhr.responseText); + } + }; + xhr.open('GET', serverURL + ':' + serverPort + '/publicKey'); + xhr.send(); +} + +function init() { + dots = Array.prototype.slice.call(dots); + numbers = Array.prototype.slice.call(numbers); + numbers.forEach(function (number, index) { + number.addEventListener('click', function () { + number.className += ' grow'; + if (number.innerHTML === '0') { + input += 0; + } else { + input += index + 1; + } + dots[input.length - 1].className += ' active'; + if (input.length >= 4) { + sendPinCode(input); + + setTimeout(function () { + dots.forEach(function (dot, index) { + dot.className = 'dot'; + }); + input = ''; + }, 900); + setTimeout(function () { + document.body.className = ''; + }, 1000); + } + setTimeout(function () { + number.className = 'number'; + }, 1000); + }); + }); +} + +function sendPinCode(data) { + var encrypt = new JSEncrypt(); + encrypt.setPublicKey(publicKey); + var xhr = new XMLHttpRequest(); + xhr.onload = function () { + if (xhr.status === 200 || xhr.status === 201) { + console.log(`result : ${xhr.responseText}`); + chkPinCode(xhr.responseText === 'true' ? true : false); + } else { + console.error(xhr.responseText); + } + }; + xhr.open('POST', serverURL + ':' + serverPort + '/pinCodeToServer'); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.send(encrypt.encrypt(data)); +} + +function chkPinCode(returnVal) { + if (returnVal) { + dots.forEach(function (dot, index) { + dot.className += ' correct'; + }); + document.body.className += ' correct'; + setTimeout(function () { + loginForm.submit(); + //pinCode(); + }, 1000); + } else { + dots.forEach(function (dot, index) { + dot.className += ' wrong'; + }); + document.body.className += ' wrong'; + } +} + +function pinCode() { + window.location.href = serverURL + ':' + serverPort + '/client/client.html'; +} + +window.onload = function () { + preloadKey(); +}; diff --git a/d2d_app/client/lib/tau/LICENSE.Flora b/d2d_app/client/lib/tau/LICENSE.Flora new file mode 100644 index 0000000..4ab7e53 --- /dev/null +++ b/d2d_app/client/lib/tau/LICENSE.Flora @@ -0,0 +1,206 @@ +Flora License + +Version 1.1, April, 2013 + +http://floralicense.org/license/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and +all other entities that control, are controlled by, or are +under common control with that entity. For the purposes of +this definition, "control" means (i) the power, direct or indirect, +to cause the direction or management of such entity, +whether by contract or otherwise, or (ii) ownership of fifty percent (50%) +or more of the outstanding shares, or (iii) beneficial ownership of +such entity. + +"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, +and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice +that is included in or attached to the work (an example is provided +in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, +as a whole, an original work of authorship. For the purposes of this License, +Derivative Works shall not include works that remain separable from, +or merely link (or bind by name) to the interfaces of, the Work and +Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or +Derivative Works thereof, that is intentionally submitted to Licensor +for inclusion in the Work by the copyright owner or by an individual or +Legal Entity authorized to submit on behalf of the copyright owner. +For the purposes of this definition, "submitted" means any form of +electronic, verbal, or written communication sent to the Licensor or +its representatives, including but not limited to communication on +electronic mailing lists, source code control systems, and issue +tracking systems that are managed by, or on behalf of, the Licensor +for the purpose of discussing and improving the Work, but excluding +communication that is conspicuously marked or otherwise designated +in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Tizen Compliance Specification +and passes the Tizen Compliance Tests as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work +solely as incorporated into a Tizen Certified Platform, where such +license applies only to those patent claims licensable by such +Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work solely +as incorporated into a Tizen Certified Platform to which such +Contribution(s) was submitted. If You institute patent litigation +against any entity (including a cross-claim or counterclaim +in a lawsuit) alleging that the Work or a Contribution incorporated +within the Work constitutes direct or contributory patent infringement, +then any patent licenses granted to You under this License for that +Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. You must retain, in the Source form of any Derivative Works that + You distribute, all copyright, patent, trademark, and attribution + notices from the Source form of the Work, excluding those notices + that do not pertain to any part of the Derivative Works; and + 4. If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable + copy of the attribution notices contained within such NOTICE file, + excluding those notices that do not pertain to any part of + the Derivative Works, in at least one of the following places: + within a NOTICE text file distributed as part of the Derivative Works; + within the Source form or documentation, if provided along with the + Derivative Works; or, within a display generated by the Derivative Works, + if and wherever such third-party notices normally appear. + The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum + to the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. You may add Your own + copyright statement to Your modifications and may provide additional or + different license terms and conditions for use, reproduction, or + distribution of Your modifications, or for any such Derivative Works + as a whole, provided Your use, reproduction, and distribution of + the Work otherwise complies with the conditions stated in this License + and your own copyright statement or terms and conditions do not conflict + the conditions stated in the License including section 3. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Flora License to your work + +To apply the Flora License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "[]" +replaced with your own identifying information. (Don't include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same "printed page" as the copyright notice for easier +identification within third-party archives. + + Copyright 2015 Samsung Electronics Co., Ltd. + + Licensed under the Flora License, Version 1.1 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/d2d_app/client/lib/tau/VERSION b/d2d_app/client/lib/tau/VERSION new file mode 100644 index 0000000..c813fe1 --- /dev/null +++ b/d2d_app/client/lib/tau/VERSION @@ -0,0 +1 @@ +1.2.5 diff --git a/d2d_app/client/lib/tau/animation/tau.animation.js b/d2d_app/client/lib/tau/animation/tau.animation.js new file mode 100644 index 0000000..c6bb11a --- /dev/null +++ b/d2d_app/client/lib/tau/animation/tau.animation.js @@ -0,0 +1,4077 @@ +(function(window) { +(!window.tau) && (window.tau = {}); +var ns = window.tau.animation = {}; +(function(window, ns) { + ( function () { + + var lastTime = 0; + var vendors = [ 'ms', 'moz', 'webkit', 'o' ]; + + for ( var x = 0; x < vendors.length && !window.requestAnimationFrame; ++ x ) { + + window.requestAnimationFrame = window[ vendors[ x ] + 'RequestAnimationFrame' ]; + window.cancelAnimationFrame = window[ vendors[ x ] + 'CancelAnimationFrame' ] || window[ vendors[ x ] + 'CancelRequestAnimationFrame' ]; + + } + + if ( window.requestAnimationFrame === undefined ) { + + window.requestAnimationFrame = function ( callback ) { + + var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) ); + var id = window.setTimeout( function() { callback( currTime + timeToCall ); }, timeToCall ); + lastTime = currTime + timeToCall; + return id; + + }; + + } + + window.cancelAnimationFrame = window.cancelAnimationFrame || function ( id ) { window.clearTimeout( id ) }; + + }() ); + + (function init(window, ns) { + window.Uint8Array.prototype.setValue = function() { + for (var i = 0, len = this.length; i < len; i++) { + if (arguments[i] === undefined) { + return; + } else { + this[i] = arguments[i]; + } + } + + }; + + /** + * Gets time based on window time system + * @method getTime + * @return {Object} + * @member ns + * @static + */ + ns.getTime = (function() { + if (window.performance) { + if (window.performance.now) { + return function() { + return window.performance.now() + }; + } else { + if (window.performance.webkitNow) { + return function() { + return window.performance.webkitNow() + }; + } else { + return function() { + return new Date().getTime() + }; + } + } + } else { + return function() { + return new Date().getTime() + }; + } + })(); + + + + })(window, ns); + + + var base = { + + /** + * Enum value for type of animation + * @variable ENUM + * @member ns.base + * @private + */ + ENUM: { + NODETYPE: { + GROUP: 1, + ANIMATION: 2 + }, + GROUPTYPE: { + SEQUENCE: 4, + PARALLEL: 8 + } + }, + + /** + * Calls given function every element of array + * @method forEach + * @param {Object} a + * @param {Function} f + * @return {Object} + * @member ns.base + * @public + */ + forEach: function(a, f) { + for (var i = 0, il = (a && a.length); i < il; i++) { + var o = a[i]; + f(o, i); + } + }, + + /** + * Returns copied object from the source + * @method copy + * @param {Object} src + * @param {Object} dst + * @return {Object} + * @member ns.base + * @private + */ + copy: function(src, dst) { + dst = dst || {}; + + for (var key in src) { + if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') { + dst[key] = src[key]; +// if(typeof(src.length) !== 'undefined') { +// this.copy(src[key], dst[key]); +// } else { +// dst[key] = src[key]; +// } + } + } + + return dst; + }, + + /** + * Returns copied array from the source + * @method arrayCopy + * @param {Object} src + * @param {Object} dst + * @return {Object} + * @member ns.base + * @private + */ + arrayCopy: function(src, dst) { + var i, l = src.length; + + if (l !== undefined) { + if (dst === undefined) { + if (src instanceof Uint8Array) { + dst = new Uint8Array(l) + } else { + dst = []; + } + } + + for (i = 0; i < l; i++) { + if(typeof src[i] !== 'string' && src[i].length !== undefined) { + dst[i] = ns.base.arrayCopy(src[i]); + } else { + dst[i] = src[i]; + } + } + + } else { + dst = src; + } + + return dst; + }, + + /** + * Returns copied object from the source. DeepCopy checks all type of property in source such as object, string, number, and so on. + * @method deepCopy + * @param {Object} src + * @param {Object} dst + * @return {Object} + * @member ns.base + * @private + */ + deepCopy: function(src, dst, filter) { + if (typeof(src) == 'object') { + dst = dst || {}; + if (typeof(src.length) != 'undefined') { + if (src instanceof Array) { + dst = new Array(); + } else if (src instanceof Uint8Array) { + dst = new Uint8Array(src.length); + } + } + + for (var objInd in src) { + if (typeof(src[objInd]) == 'object') { + dst[objInd] = this.deepCopy(src[objInd]); + } else if (typeof(src[objInd]) == 'string') { + dst[objInd] = src[objInd]; + } else if (typeof(src[objInd]) == 'number') { + dst[objInd] = src[objInd]; + } else if (typeof(src[objInd]) == 'boolean') { + ((src[objInd] == true) ? dst[objInd] = true : dst[objInd] = false); + } + } + } else { + dst = src; + } + return dst; + }, + + /** + * Returns SingleTon object. This function provide usage of SingleTon pattern. + * @method singleTon + * @param {Object} SingletonObject + * @return {Object} + * @member ns.base + * @private + */ + singleTon: function(SingletonObject) { + var _singleton = {}; + + _singleton.getInstance = function() { + if (this._singleton === undefined) { + this._singleton = new SingletonObject; + } + return this._singleton; + }; + + return _singleton; + }, + + /** + * Returns true or false based on whether the type of parameter is number or not. + * @method isNumber + * @param {Number} n + * @return {Boolean} + * @member ns.base + * @public + */ + isNumber: function(n) { + return (typeof n === 'number') + }, + + /** + * Returns true or false based on whether the type of parameter is function or not. + * @method isFunction + * @param {Number} value + * @return {Boolean} + * @member ns.base + * @public + */ + isFunction: function(value) { + return (typeof value === 'function'); + }, + + /** + * Returns true or false based on whether the parameter is object or not. + * @method isObject + * @param {Number} value + * @return {Boolean} + * @member ns.base + * @public + */ + isObject: function(value) { + return (value instanceof Object); + }, + + /** + * Returns true or false based on whether the parameter is array or not. + * @method isArray + * @param {Number} value + * @return {Boolean} + * @member ns.base + * @public + */ + isArray: function(value) { + return (value instanceof Array); + }, + + // TODO: deprecated - use ns.$ + selector: function(str) { + var s = str.slice(0, 1), + c = str.slice(1), result; + + if(s === '.') { + result = document.getElementsByClassName(c); + } else if(s === '#') { + result = document.getElementById(c); + } + return result; + } + }; + + base.WeakMap = function() { + // private references holders + this.keys = []; + this.values = []; + this.i = 0; + }; + + // WeakMap#delete(key:void*):void + base.WeakMap.prototype.del = function(key) { + if (this.has(key)) { + this.keys.splice(this.i, 1); + this.values.splice(this.i, 1); + } + return -1 < this.i; + }; + + base.WeakMap.prototype.get = function(key, d3fault) { + return this.has(key) ? this.values[this.i] : d3fault; + }; + + base.WeakMap.prototype.has = function(key) { + if (key !== Object(key)) + throw new TypeError("not a non-null object"); + this.i = Array.prototype.indexOf.call(this.keys, key); + return -1 < this.i; + }; + + base.WeakMap.prototype.set = function(key, value) { + this.has(key) ? this.values[this.i] = value : this.values[this.keys.push(key) - 1] = value; + }; + + base.WeakMap.prototype.getKey = function() { + return this.keys; + }; + + var initializing = false, fnTest = /xyz/.test(function() { + xyz; + }) ? /\b_super\b/ : /.*/; + + // The base Class implementation (does nothing) + base.Class = function() { + }; + + // Create a new Class that inherits from this class + base.Class.extend = function(prop) { + var _super = this.prototype; + var _static = prop.static; + // Instantiate a base class (but only create the instance, + // don't run the init constructor) + initializing = true; + var prototype = new this(); + initializing = false; + + // Copy the properties over onto the new prototype + for (var name in prop) { + if (name !== 'static') { + // Check if we're overwriting an existing function + prototype[name] = typeof prop[name] == "function" && + typeof _super[name] == "function" && fnTest.test(prop[name]) ? + (function(name, fn) { + return function() { + var tmp = this._super; + + // Add a new ._super() method that is the same method + // but on the super-class + this._super = _super[name]; + + // The method only need to be bound temporarily, so we + // remove it when we're done executing + var ret = fn.apply(this, arguments); + this._super = tmp; + + return ret; + }; + })(name, prop[name]) : + prop[name]; + } + + } + + // The dummy class constructor + function Class() { + // All construction is actually done in the init method + if (!initializing && this._init) + return this._init.apply(this, arguments); + } + + // Populate our constructed prototype object + Class.prototype = prototype; + + // Enforce the constructor to be what we expect + Class.prototype.constructor = Class; + + // And make this class extendable + Class.extend = arguments.callee; + + if (_static) { + for (var p in _static) { + if (_static.hasOwnProperty(p)) { + Class[p] = _static[p]; + } + } + } + + return Class; + }; + + ns.base = base; + +})(window, ns); + + + + + + + + +(function(window, ns) { + 'use strict'; + + var Ticker = ns.base.Class.extend({ + _init: function() { + + this.now = ns.getTime; + this._frameId = null; // requeatAnimatoinFrame ID + + this.animators = []; + this.animatorIdx = 0; + }, + + /** + * On requestAnimationFrame with tick. + * @method tickOn + * @member ns.Ticker + * @private + */ + tickOn: function() { + var self = this; + + (function loop() { + self._frameId = window.requestAnimationFrame(loop); + var i, + time = ns.getTime(); + + for(i = 0; i < self.animatorIdx; i++) { + self.animators[i].tick(time); + } + })(); + }, + + /** + * Off requestAnimationFrame by cancelAnimationFrame. + * @method tickOn + * @member ns.Ticker + * @private + */ + tickOff: function() { + if(this._frameId) { + window.cancelAnimationFrame(this._frameId); + this._frameId = null; + } + }, + + /** + * Triggers Ticker's status by on + * @event __on + * @member ns.Ticker + * @private + */ + __on : function(e) { + if(this.animators.indexOf(e) < 0) { // TODO : change map ? + //this.animators.push(e); + this.animators[this.animatorIdx] = e; + this.animatorIdx++; + + if(this._frameId === null) { + this.tickOn(); + } + } + }, + + /** + * Triggers Ticker's status by off + * @event __off + * @member ns.Ticker + * @private + */ + __off : function(e) { + var idx = this.animators.indexOf(e); + if(idx >= 0) { + + this.animators.splice(idx, 1); + this.animatorIdx--; + + if(this.animatorIdx === 0) { + this.tickOff(); + } + } + } + }); + + /* + * Ticks with requestAnimationFrame + */ + ns.Ticker = ns.base.singleTon(Ticker); +})(window, ns); + +(function(window, ns) { + 'use strict'; // jshint ignore:line + + var p; + function Ease() { + this.regExpCubicBezier = /cubic-bezier\s*\(\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*\)/; + } + + function cubicBezier(x1, y1, x2, y2) { + return function(t) { + var rp = 1 - t, rp3 = 3 * rp, p2 = t * t, p3 = p2 * t, a1 = rp3 * t * rp, a2 = rp3 * p2; + return a1 * y1 + a2 * y2 + p3; + }; + } + + function calcBounceOut(t) { + if (t < 1 / 2.75) { + return (7.5625 * t * t); + } else if (t < 2 / 2.75) { + return (7.5625 * (t -= 1.5 / 2.75) * t + 0.75); + } else if (t < 2.5 / 2.75) { + return (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375); + } else { + return (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375); + } + } + + p = Ease.prototype; + p.ease = cubicBezier(0.25, 0.1, 0.25, 1); + + p.easeOut = cubicBezier(0, 0, 0.58, 1); + + p.easeInOut = cubicBezier(0.42, 0, 0.58, 1); + + p.easeIn = cubicBezier(0.42, 0, 1, 1); + + p.sineIn = cubicBezier(0.47, 0, 0.745, 0.715); + + p.sineOut = cubicBezier(0.39, 0.575, 0.565, 1); + + p.sineInOut = cubicBezier(0.445, 0.05, 0.55, 0.95); + + p.expoIn = cubicBezier(0.95, 0.05, 0.795, 0.035); + + p.expoOut = cubicBezier(0.19, 1, 0.22, 1); + + p.expoInOut = cubicBezier(1, 0, 0, 1); + + p.circIn = cubicBezier(0.6, 0.04, 0.98, 0.335); + + p.circOut = cubicBezier(0.075, 0.82, 0.165, 1); + + p.circInOut = cubicBezier(0.785, 0.135, 0.15, 0.86); + + p.backIn = cubicBezier(0.6, -0.28, 0.735, 0.045); + + p.backOut = cubicBezier(0.175, 0.885, 0.32, 1.275); + + p.backInOut = cubicBezier(0.68, -0.55, 0.265, 1.55); + + p.zoomInDown = cubicBezier(0.55, 0.055, 0.675, 0.19); + + p.bounce1 = cubicBezier(0.215, 0.610, 0.355, 1.000); + p.bounce2 = cubicBezier(0.755, 0.050, 0.855, 0.060); + + // http://gizma.com/easing/ + p.linear = function(t) { + return t; + }; + + p.cubicIn = function(t) { + return t * t * t; + }; + + p.cubicOut = function(t) { + return (--t) * t * t + 1; + }; + + p.cubicInOut = function(t) { + return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; + }; + + p.quadIn = function(t) { + return t * t; + }; + + p.quadOut = function(t) { + return t * (2 - t); + }; + + p.quadInOut = function(t) { + return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t; + }; + + p.quartIn = function(t) { + return t * t * t * t; + }; + + p.quartOut = function(t) { + return 1 - (--t) * t * t * t; + }; + + p.quartInOut = function(t) { + return t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t; + }; + + p.quintIn = function(t) { + return t * t * t * t * t; + }; + + p.quintOut = function(t) { + return 1 + (--t) * t * t * t * t; + }; + + p.quintInOut = function(t) { + return t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t; + }; + + p.bounceOut = function(t) { + return calcBounceOut(t); + }; + + p.bounceIn = function(t) { + return 1 - Ease.prototype.bounceOut(1 - t); + }; + + p.bounceInOut = function(t) { + if (t < 0.5) { + return Ease.prototype.bounceIn(t * 2) * 0.5; + } + return Ease.prototype.bounceOut(t * 2 - 1) * 0.5 + 0.5; + }; + + var pi2 = Math.PI * 2; + var defaultS = 0.3 / pi2 * Math.asin(1); + + p.elasticIn = function(t) { + if (t === 0 || t === 1) { + return t; + } + return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - defaultS) * pi2 / 0.3)); + }; + + p.elasticOut = function(t) { + if (t === 0 || t === 1) { + return t; + } + return (Math.pow(2, -10 * t) * Math.sin((t - defaultS) * pi2 / 0.3) + 1); + }; + + p.elasticInOut = function(t) { + if ((t *= 2) < 1) { + return -0.5 * (Math.pow(2, 10 * (t -= 1)) * Math.sin((t - defaultS) * pi2 / 0.3)); + } + return Math.pow(2, -10 * (t -= 1)) * Math.sin((t - defaultS) * pi2 / 0.3) * 0.5 + 1; + }; + /* + * Provides ease functions + */ + ns.Ease = ns.base.singleTon(Ease); +})(window, ns); +/* + * # Tween Animator + * + * Provides Tween and animate javascript properties. + * + * @example + * var box = document.getElementById('box'); + * var tween = new ns.Tween({width: 100, height:100}, {width: 200, height: 250}, { + * duration: 1000, + * onUpdate: function() { + * box.style.width = this.width + 'px'; + * box.style.height = this.height + 'px'; + * } + * }); + * tween.play() + * + * @class ns.TweenAnimator + */ +(function(window, ns) { + 'use strict'; + + var Ticker = ns.Ticker.getInstance(), + Ease = ns.Ease.getInstance(), + // enum + STATE = { + STOP: 'stop', + PAUSE: 'pause', + RUN: 'running' + }, + DIRECTION = { + FORWARD: true, + REVERSE: false + }; + + var createTweens = function() { + var idx = 0, + length = 0, + tweens = []; + + return { + add: function(tween) { + tweens[length] = tween; + length++; + }, + + next: function() { + + if (idx < length) { + idx++; + return tweens[idx - 1]; + } else { + return false; + } + }, + + cur: function() { + return idx; + }, + + rewind: function() { + idx = 0; + }, + + get: function(i) { + return (i === undefined ? tweens : tweens[i]); + }, + + length: function() { + return length; + }, + + hasNext: function() { + return idx < length; + }, + + clear: function() { + if (length !== 0 && idx <= length) { + tweens.splice(0, idx) + } + idx = 0; + length = tweens.length; + }, + + allClear: function() { + tweens = []; + idx = length = 0; + } + + } + }; + + var createEvent = function() { + var listeners = [], + length = 0; + + return { + on: function(f) { + listeners[length] = f; + length++; + }, + + onFront: function(f) { + listeners.unshift(f); + length++; + }, + + emit: function() { + for (var i = 0; i < length; i++) { + listeners[i].apply(null, arguments); + } + }, + + remove: function(f) { + for (var i = 0; i < length; i++) { + if (listeners[i] === f) { + listeners[i].splice(i, 1); + length--; + } + } + }, + + getLength: function() { + return length; + }, + + removeAll: function() { + listeners = []; + length = 0; + } + } + }; + + var TweenAnimator = ns.base.Class.extend({ + _init: function(fromTo, option) { + + this.tweenQueue = createTweens(); + this.tweenInfo = null; + + // state + this._direction = DIRECTION.FORWARD; + this._state = STATE.STOP; + this._isTick = false; + this.isTweenInfo = false; + + fromTo && this.add(fromTo, option); + + // time value + this._startTime = this._lastTime = this._playTime = this._previousTime = 0; + this._totalTime = this._duration + this._delay; + //this._progress = 0; + + // check to change direction + this._changedDirection = false; + + // tween queue cache + this._isCache = false; // don't save tween object + }, + + /** + * Called by Ticker every frame + * @method tick + * @param {number} tick time + * @member ns.TweenAnimator + * @private + */ + tick: function(delta) { + + if (this._state === STATE.RUN) { + var now = delta, + runTime = now - this._playTime; + + this._previousTime = now; + + if (runTime < 0) { + return; + } else if (runTime <= this._duration) { + this.tweenInfo.progress = runTime / (this._duration || 1); + + this._update(); + } else { + + if (this.tweenInfo.progress !== 1) { + this.tweenInfo.progress = 1; + this._update(); + } + if (now >= this._lastTime) { + this._complete(); + } + } + } + }, + + /** + * Start tween animation + * @method play + * @member ns.TweenAnimator + * @public + */ + play: function() { + if (this._state === STATE.RUN) { + return; + } + + if (this._state === STATE.PAUSE) { + if (this._direction !== DIRECTION.FORWARD) { + this._direction = DIRECTION.FORWARD; + this._changedDirection = true; + } + this.resume(); + + } else { + this._direction = DIRECTION.FORWARD; + this._play(); + } + }, + + /** + * Start tween animation to the reverse direction. + * @method reverse + * @member ns.TweenAnimator + * @public + */ + reverse: function() { + if (this._state === STATE.RUN) { + return; + } + + if (this._state === STATE.PAUSE) { + if (this._direction !== DIRECTION.REVERSE) { + this._direction = DIRECTION.REVERSE; + this._changedDirection = true; + } + this.resume(); + + } else { + this._direction = DIRECTION.REVERSE; + this._play(); + } + }, + + /** + * Stop tween animation. + * @method stop + * @member ns.TweenAnimator + * @public + */ + stop: function() { + if (this._state !== STATE.STOP) { + this._stopTween(); + this.tweenQueue.allClear(); + // TODO : call complete callback? + } + }, + + /** + * Pause tween animation. + * @method pause + * @member ns.TweenAnimator + * @public + */ + pause: function() { + if (this._state === STATE.RUN) { + this._state = STATE.PAUSE; + } + + }, + + /** + * Resume tween animation if it is paused. + * @method resume + * @param {string} direction + * @member ns.TweenAnimator + * @public + */ + resume: function(direction) { + var cur = ns.getTime(); + + if (this._state === STATE.PAUSE) { + + if (this._changedDirection || (direction !== undefined && direction !== this._direction)) { + if (direction !== undefined) { + this._direction = direction; + } + this._lastTime = cur + this._previousTime - this._playTime; + this._playTime = this._lastTime - this._duration; + this._startTime = this._playTime - this._delay; + + this._changedDirection = false; + } else { + var elapsedTime = cur - this._previousTime; + this._startTime += elapsedTime; + this._playTime += elapsedTime; + this._lastTime += elapsedTime; + } + + this._state = STATE.RUN; + } + + }, + + /** + * Jump to a specific time + * @method seek + * @param {number} specific time + * @member ns.TweenAnimator + * @public + */ + seek: function(n) { + var seekTime = n * this._totalTime - this._delay; + if (seekTime >= 0) { + this._update(seekTime / this._duration); + } + }, + + /** + * Get value of seek time + * @method getSeek + * @param {number} seek time + * @return {number} value + * @member ns.TweenAnimator + * @private + */ + getSeek: function(p, type) { + var i, name, l, p, + n = this.tweenInfo.name, + t = this.tweenInfo.to, + f = this.tweenInfo.from; + + if (type) { + p = p * this._totalTime - this._delay + } + + for (i = 0; name = n[i]; i++) { + + if (this.cur[name] && (l = this.cur[name].length)) { + (this.cur[name] === undefined) && (this.cur[name] = []); + this._calculateTween(this.cur[name], t[name], f[name], p); + + } else { + this.cur[name] = (t[name] - f[name]) * this._ease(p) + f[name]; + } + + } + + return this.cur; + }, + + /** + * Set start time of tween + * @method setStartTime + * @param {number} start time + * @member ns.TweenAnimator + * @private + */ + setStartTime: function(time) { + this._startTime = time; + //this._playTime = this._startTime + (this._direction ? this._delay : 0); + //this._lastTime = this._playTime + this._duration + (this._direction ? 0 : this._delay); + }, + + /** + * Replay tween animation + * @method replay + * @member ns.TweenAnimator + * @private + */ + replay: function() { + this._update(0); + this._start(); + }, + + /** + * Set duration of tween + * @method duration + * @param {number} + * @member ns.TweenAnimator + * @private + */ + duration: function(n) { + this._duration = ns.base.isNumber(n) ? n : 1000; + }, + + /** + * Set delay of tween + * @method delay + * @param {number} + * @member ns.TweenAnimator + * @private + */ + delay: function(n) { + this._delay = ns.base.isNumber(n) ? n : 0; + }, + + /** + * Set ease of tween + * @method ease + * @param {string} + * @member ns.TweenAnimator + * @private + */ + ease: function(f) { + this._ease = ns.base.isFunction(Ease[f]) ? Ease[f] : Ease.linear; + }, + + /** + * Set loop of tween + * @method loop + * @param {number} + * @member ns.TweenAnimator + * @private + */ + loop: function(n) { + this._loop = ns.base.isNumber(n) ? n : 1; + }, + + /** + * Add tween object + * @method add + * @param {object} fromTo from and to value object + * @param {object} option value object including duration, delay, ease ans so on. + * @member ns.TweenAnimator + * @public + */ + add: function(fromTo, option) { + var tween; + + if (option === undefined) { + tween = fromTo; + tween.startCallback = createEvent(); + tween.completeCallback = createEvent(); + tween.progress = 0; + } else { + tween = { + fromTo: {}, + name: [], + progress: 0, + startCallback: createEvent(), + completeCallback: createEvent() + }; + + tween.option = option; + } + + tween.option.onStart && tween.startCallback.on(tween.option.onStart); + tween.option.onComplete && tween.completeCallback.on(tween.option.onComplete); + + this.tweenQueue.add(tween); + + if (this.tweenQueue.length() === 1) { + this.tweenQueue.next(); + this.initTween(tween); + this.isTweenInfo = true; + } + + return tween; + }, + + /** + * Shift to next tween object. + * @method nextTween + * @return {object | boolean} tween object or false if not. + * @member ns.TweenAnimator + * @private + */ + + setRender: function(f) { + this.render = f; + }, + + setUpdateTarget: function(target) { + this.cur = target; + }, + + getState: function() { + return this._state; + }, + + getCurrentTweenInfo: function() { + return this.tweenInfo; + }, + + nextTweenInfo: function() { + return this.tweenQueue.next(); + }, + + getLastTweenInfo: function() { + return this.tweenQueue.get(this.tweenQueue.length() - 1); + }, + + getFirstTweenInfo: function() { + return this.tweenQueue.get(0); + }, + /** + * Initialize cur tween object. + * @method initTween + * @param {object} tweenInfo object + * @member ns.TweenAnimator + * @private + */ + initTween: function(tweenInfo) { + var option = tweenInfo.option; + + this.tweenInfo = tweenInfo; + this.cur = (this.cur !== undefined) ? this.cur : (option._cur !== undefined) ? option._cur : {}; + + this.option = option; + + // user event + this._onUpdate = option.onUpdate; // only one update callback exists because it affect performance. + + // tween option value + if (ns.base.isObject(option)) { + this.duration(option.duration); + this.ease(option.ease); + this.delay(option.delay); + this.loop(option.loop); + + this._reverseDelay = option.reverseDelay || 0; + + } else { + this._duration = 1000; + this._delay = 0; + this._loop = 1; + this._ease = Ease.linear; + this._reverseDelay = 0; + } + this._loopCnt = this._loop; + + }, + + tweenQueueCache: function(flag) { + (typeof flag === 'boolean') && (this._isCache = flag); + }, + + /** + * If state is stop, start tween. or If it is pause, resume tween. + * @method _play + * @member ns.TweenAnimator + * @private + */ + _play: function() { + if (this._state === STATE.PAUSE) { + this.resume(); + } else if (this._state === STATE.STOP) { + this._start(); + } + }, + + /** + * Calculate start, play and last time. And start tick. + * @method _start + * @member ns.TweenAnimator + * @private + */ + _start: function() { + this._state = STATE.RUN; + + this._startTime = this._startTime || ns.getTime(); + this._playTime = this._startTime + (this._direction ? this._delay : 0); + this._lastTime = this._playTime + this._duration + (this._direction ? 0 : this._delay) + this._reverseDelay; + + //this._onStart && this._onStart(); + this.tweenInfo.startCallback.emit(); + + if (!this._isTick) { + Ticker.__on(this); + this._isTick = true; + } + }, + + /** + * Update tween value every frame. + * @method _update + * @param {number} progress + * @member ns.TweenAnimator + * @private + */ + _update: function(e) { + var i, name, l, + n = this.tweenInfo.name, + ft = this.tweenInfo.fromTo; + + this.tweenInfo.progress = (e !== undefined) ? + e : (this._direction === DIRECTION.REVERSE ? 1 - this.tweenInfo.progress : this.tweenInfo.progress); + + // render + for (i = 0; name = n[i]; i++) { + if (ft[name][0] && (l = ft[name][0].length)) { + (this.cur[name] === undefined) && (this.cur[name] = []); + this._calculateTween(this.cur[name], ft[name][0], ft[name][1]); + + } else { + this.cur[name] = (ft[name][1] - ft[name][0]) * this._ease(this.tweenInfo.progress) + ft[name][0]; + } + } + + this.render && this.render.call(this.cur, this.tweenInfo); + this._onUpdate && this._onUpdate.call(this.cur, this.tweenInfo); + }, + + /** + * Calculate tween value. + * @method _calculateTween + * @param {number} current value + * @param {number} from value + * @param {number} to value + * @param {number} progress + * @member ns.TweenAnimator + * @private + */ + _calculateTween: function(c, f, t, p) { + var i, l; + (p === undefined) && (p = this.tweenInfo.progress); + + for (i = 0, l = t.length; i < l; i++) { + if (typeof t[i] === 'number') { + c[i] = (t[i] - f[i]) * this._ease(p) + f[i]; + } else if (typeof t[i] === 'string') { + c[i] = t[i]; + } else { + (c[i] === undefined) && (c[i] = []); + this._calculateTween(c[i], f[i], t[i]); + } + } + }, + + /** + * If tween completed, call this function. + * @method _complete + * @member ns.TweenAnimator + * @private + */ + _complete: function() { + var nextTween; + this.setStartTime(null); + this.isTweenInfo = false; + this.tweenInfo.completeCallback.emit(); + + // loop check + if (--this._loopCnt > 0) { + this.replay(); + } else { + // search next tweenInfo + if (!this.isTweenInfo && (nextTween = this.tweenQueue.next())) { + this.initTween(nextTween); + + if (!this._isCache) { + this.tweenQueue.clear(); + } + + this._start(); + } else { + if (this.isTweenInfo) { + this._start(); + } else { + // finish tween + this._stopTween(); + + if (this.option._stackTweensFlag) { + this.tweenQueue.rewind(); + nextTween = this.tweenQueue.next(); + this.initTween(nextTween); + } else { + this.tweenQueue.allClear(); + } + } + + } + } + + }, + + /** + * Stop tween object and stop tick. + * @method _stopTween + * @member ns.TweenAnimator + * @private + */ + _stopTween: function() { + this._state = STATE.STOP; + this._startTime = null; + Ticker.__off(this); + this._isTick = false; + } + + }); + + ns.TweenAnimator = ns.Tween = TweenAnimator; +})(window, ns); +(function(window, ns, base) { + 'use strict'; + + var Transform = ns.base.Class.extend({ + _init: function() { + this.init(); + }, + + /** + * Initialize transform values + * @method init + * @member ns.Transform.init + * @private + */ + init: function() { + this.translateX = 0; + this.translateY = 0; + this.translateZ = 0; + + this.rotateX = 0; + this.rotateY = 0; + this.rotateZ = 0; + + this.skewX = 0; + this.skewY = 0; + + this.scaleX = 1; + this.scaleY = 1; + }, + + /** + * Copy transform values + * @method copy + * @param {object} source transform value + * @member ns.Transform.copy + * @private + */ + copy: function(t) { + this.translateX = t.translateX; + this.translateY = t.translateY; + this.translateZ = t.translateZ; + + this.rotateX = t.rotateX; + this.rotateY = t.rotateY; + this.rotateZ = t.rotateZ; + + this.skewX = t.skewX; + this.skewY = t.skewY; + + this.scaleX = t.scaleX; + this.scaleY = t.scaleY; + }, + + /** + * Set transform array values + * @method set + * @param {array} source transform array value + * @member ns.Transform.set + * @private + */ + set: function(t) { + if(t instanceof Array) { + // translate, rotate, scale, skew + this.translateX = base.isNumber(t[0]) ? t[0] : 0; + this.translateY = base.isNumber(t[1]) ? t[1] : 0; + this.translateZ = base.isNumber(t[2]) ? t[2] : 0; + + this.rotateX = base.isNumber(t[3]) ? t[3] : 0; + this.rotateY = base.isNumber(t[4]) ? t[4] : 0; + this.rotateZ = base.isNumber(t[5]) ? t[5] : 0; + + this.scaleX = base.isNumber(t[6]) ? t[6] : 1; + this.scaleY = base.isNumber(t[7]) ? t[7] : 1; + + this.skewX = base.isNumber(t[8]) ? t[8] : 0; + this.skewY = base.isNumber(t[9]) ? t[9] : 0; + } + } + }); + + /* + * Sets or Initialize webkitTransform property + */ + ns.Transform = Transform; + +})(window, ns, ns.base); + +(function(window, ns, base) { + 'use strict'; + + var colorTable = { + aqua: new Uint8Array([0, 255, 255]), + lime: new Uint8Array([0, 255, 0]), + silver: new Uint8Array([192, 192, 192]), + black: new Uint8Array([0, 0, 0]), + maroon: new Uint8Array([128, 0, 0]), + teal: new Uint8Array([0, 128, 128]), + blue: new Uint8Array([0, 0, 255]), + navy: new Uint8Array([0, 0, 128]), + white: new Uint8Array([255, 255, 255]), + fuchsia: new Uint8Array([255, 0, 255]), + olive: new Uint8Array([128, 128, 0]), + yellow: new Uint8Array([255, 255, 0]), + orange: new Uint8Array([255, 165, 0]), + gray: new Uint8Array([128, 128, 128]), + purple: new Uint8Array([128, 0, 128]), + green: new Uint8Array([0, 128, 0]), + red: new Uint8Array([255, 0, 0]), + pink: new Uint8Array([255, 192, 203]), + cyan: new Uint8Array([0, 255, 255]), + transparent: new Uint8Array([255, 255, 255, 0]) + }; + + var CSSPropertyParser = base.Class.extend({ + + _init: function() { + var self = this; + + // px & unit + var pxType = ['borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', + 'marginTop', 'marginRight', 'marginBottom', 'marginLeft', + 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', + 'width', 'height', 'top', 'left', + 'clipTop', 'clipBottom', 'clipRight', 'clipLeft', + 'fontSize', 'lineHeight']; + pxType.forEach(function(type) { + self[type] = self._unit.bind(self); + }); + + var backgroundType = ['backgroundPosition', 'backgroundSize']; + backgroundType.forEach(function(type) { + self[type] = self._arrayUnit.bind(self); + + }); + + // border + var borderType = ['border', 'borderTop', 'borderRight', 'borderLeft', 'borderBottom']; + borderType.forEach(function(type) { + self[type] = function _border(str) { + var result = {}, temp; + + temp = self._blank(str); + + result[type + 'Width'] = temp[0]; + result[type + 'Style'] = temp[1] === 'none' ? 'solid' : temp[1]; // TODO: 유효성 체크 + result[type + 'Color'] = temp[2]; + + return result; + }; + }); + + // color + var colorType = ['backgroundColor', 'color', + 'borderColor', 'borderTopColor', 'borderRightColor', 'borderLeftColor', 'borderBottomColor']; + + colorType.forEach(function(type) { + self[type] = self._color; + }); + + //margin & padding + var blankType = ['margin', 'padding']; + blankType.forEach(function(type) { + self[type] = function _blank(str) { + var temp = self._blank(str), result = {}; + + if (temp.length === 4) { + result[type + 'Top'] = temp[0]; + result[type + 'Right'] = temp[1]; + result[type + 'Bottom'] = temp[2]; + result[type + 'Left'] = temp[3]; + } else if (temp.length === 3) { + result[type + 'Top'] = temp[0]; + result[type + 'Right'] = temp[1]; + result[type + 'Bottom'] = temp[2]; + result[type + 'Left'] = temp[1]; + } else if (temp.length === 2) { + result[type + 'Top'] = temp[0]; + result[type + 'Right'] = temp[1]; + result[type + 'Bottom'] = temp[0]; + result[type + 'Left'] = temp[1]; + } else if (temp.length === 1) { + result[type + 'Top'] = temp[0]; + result[type + 'Right'] = temp[0]; + result[type + 'Bottom'] = temp[0]; + result[type + 'Left'] = temp[0]; + } + + return result; + } + }); + + //var unitWithString = ['lineHeight', 'fontSize']; + //unitWithString.forEach(function(type){ + // self[type] = function _unitString(str){ + // var result; + // + // result = self._unit(str); + // + // if(isNaN(result.value)) { + // result = str; + // } + // + // return result; + // } + //}); + + var shadowType = ['boxShadow', 'textShadow']; + shadowType.forEach(function(type) { + self[type] = function _shadowString(str) { + + var i, j, length, string, result = [], color, rgbArray = [], len, rgbIdx = 0, + rgbExp = /rgb\([0-9]+[\, |\s]+[0-9]+[\, |\s]+[0-9]+\)/g, shadowLength; + + rgbArray = str.match(rgbExp) || []; + str = str.replace(rgbExp, 'rgb'); + + str = str.split(','); + + for (i = 0, length = str.length; i < length; i++) { + + + if (str[i].match('rgb') && rgbArray[rgbIdx]) { + str[i] = str[i].replace('rgb', rgbArray[rgbIdx]); + rgbIdx++; + } + + + str[i] = self._blank(str[i]); + shadowLength = str[i].length - 1; + // search color + + if ((color = self._color(str[i][0]))) { + str[i].splice(0, 1); + str[i].push(color); + } else { + color = self._color(str[i][shadowLength]); + } + + for (j = 0; j < shadowLength; j++) { + str[i][j] = self._unit(str[i][j]); + } + str[i][j] = color; + } + + + return str; + } + }); + + }, + + opacity: function(v) { + return parseFloat(v); + }, + + clip: function(v) { + var text = v.replace(/\(|\)|,/g, ' ').trim().split(/\s+/g); + + var result = []; + result[0] = text[0]; + + for (var i = 1; i <= 4; i++) { + result[i] = this._unit(text[i]); + } + return result; + }, + + webkitClipPath: function(v) { + var result = [], i, len, + text = v.replace(/\(|\)|,/g, ' ').trim().split(/\s+/g); + + result.push(text[0]); + for (i = 1, len = text.length; i < len; i++) { + result.push(this._unit(text[i])); + } + + return result; + }, + + backgroundImage: function(v) { + return v.replace(/url\(|\)$/ig, ""); + }, + + _arrayUnit: function(v) { + var i, l, result = v.trim().split(' '); + + for (i = 0, l = result.length; i < l; i++) { + result[i] = this._unit(result[i]); + } + return result; + }, + + _unit: function(str) { + if (typeof str === 'string') { + return { + number: this._getFloat(str), + unit: (this._getChar(str) || 'px') + } + } else { + return { + number: str, + unit: 'px' + }; + } + }, + + _color: function(colorValue) { + //console.log(colorValue); + var first, second, third, rgb, length, i, string, result; + if (colorValue === undefined || colorValue === null) { + console.log('invalid color'); + return false; + } + + if (colorTable[colorValue]) { //for string color value such as 'red' + result = colorTable[colorValue]; + } else if (colorValue instanceof Array || colorValue instanceof Uint8Array) { + result = new Uint8Array(colorValue); + } else { + string = colorValue.toLowerCase(); + string = string.trim(); + if (string.charAt(0) === 'r' && string.charAt(1) === 'g' && string.charAt(2) === 'b') { + if (string.charAt(3) === 'a') { + rgb = string.replace(/rgba\(/g, '').replace(/\)/g, '').replace(/(\s*)/g, '').replace(/\,/g, ' ').split(' '); + for (i = 0, length = rgb.length - 1; i < length; i++) { + rgb[i] = parseInt(rgb[i]); + } + rgb[length] = parseFloat(rgb[length]); + } else { + rgb = string.replace(/rgb\(/g, '').replace(/\)/g, '').replace(/(\s*)/g, '').replace(/\,/g, ' ').split(' '); + for (i = 0, length = rgb.length; i < length; i++) { + rgb[i] = parseInt(rgb[i]); + } + } + result = new Uint8Array(rgb); + + } else if (string.charAt(0) === '#') { //for '#XXX' or '#XXXXXX' + if (string.length === 4) { + first = string.charAt(1); + second = string.charAt(2); + third = string.charAt(3); + string = "#" + first + first + second + second + third + third; + } + + string = parseInt(string.substr(1), 16); // remove '#' + result = new Uint8Array(3); + result.setValue(string >> 16, (string >> 8) & 255, string & 255); + } else { + return false; +// console.log(colorValue); + } + } + return result; + }, + + _getChar: function(arg) { + var charArr = arg.match(/[^0-9.-]/g); + var string = ''; + + if (charArr !== null) { + string = charArr.join(''); + } + + string.replace(/\, /g, ''); + + return string; + }, + + _getNum: function(arg) { + return parseInt(arg.match(/^[-]?\d+/g), 10); + }, + + _getFloat: function(arg) { + return parseFloat(arg.match(/^[+-]?\d*(\.?\d*)/g)); + }, + + _blank: function(str) { + return str.trim().replace(/\, /g, ',').split(' '); + } + }); + + /* + * Parses css properties. + */ + ns.CSSPropertyParser = base.singleTon(CSSPropertyParser); + +})(window, ns, ns.base); +(function(window, ns, base) { + 'use strict'; + + var CssStringCreator = base.Class.extend({ + + _init: function() { + this.createColor(); + this.createBorderStyle(); + this.createBlankFunction(); + this.createUnit(); + //this.createUnitWithString(); + this.createShadow(); + }, + + + opacity: function(value) { + return value.opacity; + }, + + WebkitTransform: function(value) { + var string = ''; + string += value.perspective ? ('perspective(' + value.perspective + 'px) ') : ''; + string += 'translate3d(' + value.translateX + 'px, ' + value.translateY + 'px, ' + value.translateZ + 'px) '; + + string += value.rotateX ? ('rotateX(' + value.rotateX + 'deg) ') : ''; + string += value.rotateY ? ('rotateY(' + value.rotateY + 'deg) ') : ''; + string += value.rotateZ ? ('rotateZ(' + value.rotateZ + 'deg) ') : ''; + + string += (value.scaleX !== 1) ? ('scaleX(' + value.scaleX + ') ') : ''; + string += (value.scaleY !== 1) ? ('scaleY(' + value.scaleY + ') ') : ''; + + string += value.skewX ? ('skewX(' + value.skewX + 'deg) ') : ''; + string += value.skewY ? ('skewY(' + value.skewY + 'deg) ') : ''; + + return string; + }, + + createUnit: function() { + var self = this, + type = ['width', 'height', 'top', 'left'], + backgroundType = ['backgroundPosition', 'backgroundSize']; + + function _unit(v, u) { + if (u[this] === 'px') { + return Math.round(v[this]) + u[this]; + } + return v[this] + u[this]; + } + + type.forEach(function(f) { + self[f] = _unit.bind(f) + }); + + backgroundType.forEach(function(f) { + self[f] = _background.bind(f) + }); + + function _background(v, u) { + return v[this][0] + u[this][0] + ' ' + v[this][1] + u[this][1]; + } + }, + + createColor: function() { + var self = this; + var type = ['borderColor', 'borderTopColor', 'borderRightColor', 'borderLeftColor', 'borderBottomColor', + 'backgroundColor', 'color']; + type.forEach(function(f) { + self[f] = self._rgbColor(f); + }); + }, + + createBorderStyle: function() { + var self = this; + + var borderType = ['border', 'borderTop', 'borderRight', 'borderLeft', 'borderBottom']; + var borderWidthType = ['borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderLeftWidth', 'borderBottomWidth']; + var borderStyleType = ['borderStyle', 'borderTopStyle', 'borderRightStyle', 'borderLeftStyle', 'borderBottomStyle']; + + function _border(v, u) { + + var width = this + 'Width', + color = this + 'Color', + style = this + 'Style'; + //console.log(v[color]); + return v[width] + u[width] + ' ' + u[style] + ' rgb(' + + v[color][0] + ', ' + v[color][1] + ', ' + v[color][2] + ')'; + } + + function _borderWidth(v, u) { + return v[this].toFixed(2) + u[this]; + } + + borderType.forEach(function(f) { + self[f] = _border.bind(f) + }); + + borderStyleType.forEach(function(f) { + self[f] = self._direct(f); + }); + + borderWidthType.forEach(function(f) { + self[f] = _borderWidth.bind(f) + }); + }, + + createBlankFunction: function() { + var self = this; + var blank = ['margin', 'padding']; + var blankType = ['marginTop', 'marginRight', 'marginBottom', 'marginLeft', + 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', + 'lineHeight', 'fontSize']; + + blank.forEach(function(f) { + self[f] = _blank.bind(f) + }); + + function _blank(v, u) { + var top = this + 'Top', + right = this + 'Right', + bottom = this + 'Bottom', + left = this + 'Left'; +// console.log(v[top], u[top]); + return v[top] + u[top] + ' ' + v[right] + u[right] + ' ' + v[bottom] + u[bottom] + ' ' + v[left] + u[left]; + } + + blankType.forEach(function(f) { + self[f] = _blanktype.bind(f); + }); + + function _blanktype(v, u) { +// console.log(v[this], u[this]); + return v[this] + u[this]; + } + }, + +// createUnitWithString: function(){ +// var self = this, +// unitType = []; +// +// unitType.forEach(function(f){ +// self[f] = _unit.bind(f) +// }); +// +// function _unit(f) { +// return f[this][0] + f[this][1]; +// } +// }, + + createShadow: function() { + var self = this, + shadowType = ['boxShadow', 'textShadow']; + + shadowType.forEach(function(name) { + self[name] = function(v, u) { + var value = v[name], unit = u[name], i, j, shadowLen, len, str = ''; + for (i = 0, shadowLen = value.length; i < shadowLen; i++) { + + (i !== 0) && (str += ', '); + + for (j = 0, len = value[i].length - 1; j < len; j++) { + str += value[i][j] + unit[i][j] + ' '; + } + + str += 'rgb(' + value[i][j][0] + ',' + value[i][j][1] + ',' + value[i][j][2] + ') '; + + } + //console.log(str); + return str; + } + }); + }, + + //createShadow: function(){ + // var self = this, + // shadowType = ['boxShadow', 'textShadow']; + // + // shadowType.forEach(function(f){ + // self[f] = _shadow.bind(f); + // }); + // + // function _shadow(v){ + // var result = '', i = 0, j = 0, length = 0, len = 0; + // for(j = 0, length = v[this].length; j < length; j++){ + // for(i = 0, len = v[this][j].length; i < len; i++) { + // if(v[this][j][i].length === 2) { + // if(v[this][j][i][1] !== '') { + // result += (v[this][j][i][0] + v[this][j][i][1] + ' '); + // } + // + // } else if(v[this][j][i].length === 3){ + // result += 'rgb(' + (v[this][j][i][0] + ',' + v[this][j][i][1] + ',' + v[this][j][i][2] + ')'); + // } else if(v[this][j][i] === 'inset') { + // result += ' inset'; + // } + // } + // if( (length-1) > j){ + // result += ', '; + // } + // } + // return result; + // } + //}, + + + clip: function(v) { + return v.clip[0] + '(' + v.clip[1][0] + v.clip[1][1] + ' ' + v.clip[2][0] + v.clip[2][1] + + ' ' + v.clip[3][0] + v.clip[3][1] + ' ' + v.clip[4][0] + v.clip[4][1] + ')'; + + }, + +// clip: function(value, unit) { +// var v = value.clip, +// u = unit.clip; +// +// return 'rect(' + v[0] + u[0] + ' ' + v[1] + u[1] + +// ' ' + v[2] + u[2] + ' ' + v[3] + u[3] + ')'; +// +// }, + + webkitClipPath: function(value, unit) { + var v = value.webkitClipPath, + u = unit.webkitClipPath, + s = unit.webkitClipPathStyle, + i, l, style; + + if (s === 'circle') { + // circle(0% at 50% 50%) + return u[0] + '(' + v[0] + u[1] + ' at ' + v[1] + u[2] + ' ' + v[2] + u[3] + ')'; + } else if (s === 'polygon') { + // 'polygon(0 0, 0% 100%, 100% 0)' + style = s + '('; + for (i = 0, l = v.length; i < l; i += 2) { + style += (v[i] + u[i] + ' ' + v[i + 1] + u[i + 1]); + style += (i + 1 !== l - 1) ? ', ' : ')'; + } + return style; + } + }, + + _direct: function(type) { + return function(v) { + return v[type]; + } + }, + _rgbColor: function(type) { + return function(v) { + //console.log(' rgb(' + v[type][0] + ', ' + v[type][1] + ', ' + v[type][2] + ')'); + return 'rgb(' + v[type][0] + ', ' + v[type][1] + ', ' + v[type][2] + ')'; + } + } + }); + + /* + * Creates string based on CSS properties + */ + ns.CssStringCreator = base.singleTon(CssStringCreator); + +})(window, ns, ns.base); +(function(window, ns, base) { + 'use strict'; + + var CssParser = ns.CSSPropertyParser.getInstance(); + + var CssAnimationUtil = base.Class.extend({ + + _init: function() { + + // width unit + var self = this, color, + widthUnit, heightUnit, background, marginPadding, border, shadow; + + color = ['backgroundColor', 'color', + 'borderColor', 'borderTopColor', 'borderRightColor', 'borderLeftColor', 'borderBottomColor']; + + color.forEach(function(name) { + self[name] = function(animation) { + self.settingCssAnimation(name, animation, '_colorType'); + } + }); + + widthUnit = ['width', 'left', 'marginRight', 'marginLeft', 'paddingRight', 'paddingLeft', + 'marginTop', 'marginBottom', 'paddingBottom', 'paddingTop', + 'clipTop', 'clipBottom', 'clipRight', 'clipLeft', + 'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderLeftWidth', 'borderBottomWidth', + 'clipTop', 'clipBottom', 'clipRight', 'clipLeft']; + widthUnit.forEach(function(name) { + self[name] = function(animation) { + self.settingCssAnimation(name, animation, '_unitType', 'width'); + } + }); + + heightUnit = ['height', 'top']; + heightUnit.forEach(function(name) { + self[name] = function(animation) { + self.settingCssAnimation(name, animation, '_unitType', 'height'); + } + }); + + background = ['backgroundPosition', 'backgroundSize']; + background.forEach(function(name) { + self[name] = function(animation) { + self.settingCssAnimation(name, animation, '_backgroundType'); + } + }); + + marginPadding = ['margin', 'padding']; + marginPadding.forEach(function(name) { + self[name] = function(animation) { + var from, to, i; + + if (animation.animationFromTo[name].length === 2) { + from = CssParser[name](animation.animationFromTo[name][0]); + to = CssParser[name](animation.animationFromTo[name][1]); + + for (i in to) { + animation.animationFromTo[i] = [from[i], to[i]]; + self[i](animation); + } + + } else { + to = CssParser[name](animation.animationFromTo[name]); + + for (i in to) { + animation.animationFromTo[i] = to[i]; + self[i](animation); + } + } + } + }); + + border = ['border', 'borderTop', 'borderRight', 'borderLeft', 'borderBottom']; + border.forEach(function(name) { + self[name] = function(animation) { + var from, to; + + if (animation.animationFromTo[name].length === 2) { + from = CssParser[name](animation.animationFromTo[name][0]); + to = CssParser[name](animation.animationFromTo[name][1]); + + animation.animationFromTo[name + 'Width'] = [from[name + 'Width'], to[name + 'Width']]; + animation.animationFromTo[name + 'Color'] = [from[name + 'Color'], to[name + 'Color']]; + } else { + to = CssParser[name](animation.animationFromTo[name]); + + animation.animationFromTo[name + 'Width'] = to[name + 'Width']; + animation.animationFromTo[name + 'Color'] = to[name + 'Color']; + } + + animation.unit[name + 'Style'] = to[name + 'Style']; + + self[name + 'Width'](animation); + self[name + 'Color'](animation); + } + }); + + border = ['border', 'borderTop', 'borderRight', 'borderLeft', 'borderBottom']; + border.forEach(function(name) { + self[name] = function(animation) { + var from, to; + + if (animation.animationFromTo[name].length === 2) { + from = CssParser[name](animation.animationFromTo[name][0]); + to = CssParser[name](animation.animationFromTo[name][1]); + + animation.animationFromTo[name + 'Width'] = [from[name + 'Width'], to[name + 'Width']]; + animation.animationFromTo[name + 'Color'] = [from[name + 'Color'], to[name + 'Color']]; + } else { + to = CssParser[name](animation.animationFromTo[name]); + + animation.animationFromTo[name + 'Width'] = to[name + 'Width']; + animation.animationFromTo[name + 'Color'] = to[name + 'Color']; + } + + animation.unit[name + 'Style'] = to[name + 'Style']; + + self[name + 'Width'](animation); + self[name + 'Color'](animation); + } + }); + + shadow = ['boxShadow', 'textShadow']; + shadow.forEach(function(name) { + self[name] = function(animation) { + self.settingCssAnimation(name, animation, '_shadowType'); + } + }); + + this.webkitClipPath = function(animation) { + this.settingCssAnimation('webkitClipPath', animation, '_webkitClipPathType'); + }; + + this.fontSize = function(animation) { + this.settingCssAnimation('fontSize', animation, '_fontSizeType'); + }; + + this.lineHeight = function(animation) { + this.settingCssAnimation('lineHeight', animation, '_unitType', 'lineHeight'); + }; + + this.opacity = function(animation) { + this.settingCssAnimation('opacity', animation); + }; + + this.WebkitTransform = function(name, animation) { + + var from, to, i, self = this; + + if (typeof animation.animationFromTo[name] === 'object' && animation.animationFromTo[name].length === 2) { + from = animation.animationFromTo[name][0]; + to = animation.animationFromTo[name][1]; + + } else { + from = animation.target.cur[name]; + to = animation.animationFromTo[name]; + } + + if (name === 'translateX' || name === 'translateY' || name === 'translateZ') { + (typeof from === 'string') && (from = this._getTranslateValue(name, animation, from)); + (typeof to === 'string') && (to = this._getTranslateValue(name, animation, to)); + } + + animation.fromTo[name] = [from, to]; + animation.target.from[name] = to; + animation.name.push(name); + }; + }, + + settingCssAnimation: function(name, animation, type, percentCriterion) { + var fromTo; + + // 1. animation parser + fromTo = animation.fromTo[name] = []; + + if (typeof animation.animationFromTo[name] === 'object' && + animation.animationFromTo[name].length === 2) { + fromTo[0] = animation.animationFromTo[name][0]; + fromTo[1] = animation.animationFromTo[name][1]; + } else { + fromTo[0] = window.getComputedStyle(animation.target.dom)[name]; + if (fromTo[0] === '' || fromTo[0] === 'auto' || fromTo[0] === 'none' || fromTo[0] === undefined) { + fromTo[0] = this._exceptGetStyle(animation.target.dom, name); + } + fromTo[1] = animation.animationFromTo[name]; + } + + fromTo[0] = CssParser[name](fromTo[0]); + fromTo[1] = CssParser[name](fromTo[1]); + + // type check + if (type) { + this[type] && this[type](name, animation, percentCriterion); + } + animation.name.push(name); + + //console.log(animation.fromTo[name]); + }, + + unitArray: function(name, animation, percentCriterion) { + var from = [], to = [], unit = [], i, len, f, t, cri, + fromTo = animation.fromTo[name]; + + for (i = 0, len = fromTo[0].length; i < len; i++) { + f = fromTo[0][i]; + t = fromTo[1][i]; + + if (f.unit !== t.unit) { + cri = (typeof percentCriterion === 'object' && percentCriterion[i] ? percentCriterion[i] : percentCriterion); + this._convertUnit(animation.target.dom, f, t, cri, name); + } + + from.push(f.number); + to.push(t.number); + unit.push(t.unit); + } + + animation.fromTo[name] = [from, to]; + animation.unit[name] = unit; + }, + +// TYPE Function + _colorType: function(name, animation) { + animation.target.cur[name] = new Uint8Array(3); + }, + + _fontSizeType: function(name, animation) { + var fromTo = animation.fromTo[name]; + + if (isNaN(fromTo[0].number)) { + this._getStringFontNumber(fromTo[0], animation.target.dom) + } + + if (isNaN(fromTo[1].number)) { + this._getStringFontNumber(fromTo[1], animation.target.dom) + } + + this._unitType(name, animation, 'fontSize'); + }, + + _backgroundType: function(name, animation) { + + if (animation.fromTo[name][0].length === 1) { + animation.fromTo[name][0].push({ + number: 50, + unit: '%' + }); + } + + if (animation.fromTo[name][1].length === 1) { + animation.fromTo[name][1].push({ + number: 50, + unit: '%' + }); + } + + this.unitArray(name, animation, ['width', 'height']); + }, + + _unitType: function(name, animation, criterion) { + var from = animation.fromTo[name][0], + to = animation.fromTo[name][1]; + + if (from.unit !== to.unit) { + this._convertUnit(animation.target.dom, from, to, criterion, name); + } + + animation.unit[name] = to.unit; + animation.target.unit[name] = to.unit; + animation.fromTo[name][0] = from.number; + animation.fromTo[name][1] = to.number; + + //animation.target.from[name] = to[0]; + + return false; + }, + + _webkitClipPathType: function(name, animation) { + var fromTo = animation.fromTo[name]; + + // todo: exception + animation.unit[name + 'Style'] = fromTo[1][0]; + fromTo[0].splice(0, 1); + fromTo[1].splice(0, 1); + + this.unitArray(name, animation, 'width'); + }, + + _shadowType: function(name, animation) { + var from = animation.fromTo[name][0], to = animation.fromTo[name][1], + animationFrom = [], animationTo = [], animationUnit = [], + shadowFrom, shadowTo, + unit, i, j, shadow, len, shadowLen; + + animation.unit[name] = animationUnit; + + for (i = 0, shadowLen = to.length; i < shadowLen; i++) { + + (!from[i]) && (from[i] = []); + shadowFrom = from[i]; + shadowTo = to[i]; + unit = []; + animationUnit.push(unit); + + for (j = 0, len = shadowTo.length - 1; j < len; j++) { + + unit.push(shadowTo[j].unit); + + if (shadowFrom[j] && shadowTo[j].unit !== (shadowFrom[j].unit)) { + this._convertUnit(animation.target.dom, shadowFrom[j], shadowTo[j], 'width', name); + } + + shadowTo[j] = shadowTo[j].number; + + shadowFrom[j] = (shadowFrom[j] ? shadowFrom[j].number : 0); + } + + shadowFrom[len] || (shadowFrom[len] = new Uint8Array(3)); + + } + + animation.cur[name] = base.deepCopy(to); + }, + + //TODO : not parser + _exceptGetStyle: function(dom, style) { + var result, imageUrl, img; + + if (style === 'left') { + result = dom.offsetLeft + 'px'; + } else if (style === 'top') { + result = dom.offsetTop + 'px'; + } else if (style === 'clip') { + result = 'rect(0px 0px 0px 0px)'; + } else if (style === 'boxShadow') { + result = '0px 0px 0px 0px black'; + } else if (style === 'textShadow') { + result = '0px 0px 0px black'; + } else if (style === 'backgroundPosition') { + result = '0px 0px'; + } else if (style === 'backgroundSize') { + imageUrl = this._getStyle(dom, 'backgroundImage'); + window.aa = img = new Image(); + img.src = imageUrl; + + if (img.width && img.height) { + result = img.width + 'px ' + img.height + 'px'; + } else { + result = '0px 0px'; + } + } + + if (result === undefined) { + result = '0px'; + } + + return result; + }, + + // get Style + _getCriterionEm: function(dom, criterion) { + return criterion === 'fontSize' ? 16 : (this._getStyle(dom, 'fontSize').number || 16); + }, + + _getCriterionPercent: function(dom, criterion, style) { + var parent = dom.parentNode, + parentValue, string, size, imgSize; + + if (style === 'lineHeight') { + return (this._getStyle(dom, 'fontSize').number || 16); + } else if (style === 'backgroundPosition') { + + size = this._getStyle(dom, criterion).number; + imgSize = this._getBackgroundImageSize(dom, criterion); + + return size - imgSize + 1; + } else if (style === 'backgroundSize') { + return this._getStyle(dom, criterion).number; + } + + parentValue = CssParser._getFloat(window.getComputedStyle(parent)[criterion]); + while (parentValue === '' && parent !== document.body) { + parent = parent.parentNode; + parentValue = CssParser._getFloat(window.getComputedStyle(parent)[criterion]); + } + + if (parentValue === 0 && (criterion === 'width' || criterion === 'height')) { + string = criterion.substring(0, 1).toUpperCase() + criterion.substring(1); + parentValue = window['inner' + string]; + } + + return parentValue; + }, + + _getStyle: function(dom, style) { + var s = window.getComputedStyle(dom)[style]; + s = CssParser[style](s); + return s; + }, + + _getBackgroundImageSize: function(dom, style) { + var imageUrl, img, + size = this._getStyle(dom, 'backgroundSize'); + + if (size[0].unit === 'auto') { + imageUrl = this._getStyle(dom, 'backgroundImage'); + img = new Image(); + img.src = imageUrl; + + if (style === undefined) { + return [img.width, img.height]; + } + return img[style]; + } else { + return size[(style === 'width' ? 0 : 1)].number; + } + + }, + + _getStringFontNumber: function(value, dom) { + var string = value.unit; + + if (string === 'normal' || string === 'initial') { + value.number = (this._getStyle(dom, 'fontSize').number || 16); + value.unit = 'px'; + } else if (string === 'xx-small') { + value.number = 0.5625; + value.unit = 'em'; + } else if (string === 'x-small') { + value.number = 0.625; + value.unit = 'em'; + } else if (string === 'small') { + value.number = 0.8125; + value.unit = 'em'; + } else if (string === 'medium') { + value.number = 1; + value.unit = 'em'; + } else if (string === 'large') { + value.number = 1.125; + value.unit = 'em'; + } else if (string === 'x-large') { + value.number = 1.5; + value.unit = 'em'; + } else if (string === 'xx-large') { + value.number = 2; + value.unit = 'em'; + } + }, + + _getTranslateValue: function(name, animation, value) { + var translate, result; + + translate = CssParser._unit(value); + if (translate.unit !== 'px') { + if (name === 'translateX' || name === 'translateZ') { + result = this._convertPx(animation.target.dom, translate.number, translate.unit, 'width'); + + } else if (name === 'translateY') { + result = this._convertPx(animation.target.dom, translate.number, translate.unit, 'height'); + } + } else { + result = translate.number; + } + + return result; + }, + + + // Unit Convert //TODO: refactoring + _convertUnit: function(dom, from, to, criterion, style) { + if (to.unit === 'em') { + from.number = this._convertEm(dom, from.number, from.unit, criterion, style); + } else if (to.unit === '%') { + from.number = this._convertPer(dom, from.number, from.unit, criterion, style); + } else if (to.unit === 'px') { + from.number = this._convertPx(dom, from.number, from.unit, criterion, style); + } else if (to.unit === 'cm') { + from.number = this._convertCm(dom, from.number, from.unit, criterion, style); + } else if (to.unit === 'pt') { + from.number = this._convertPt(dom, from.number, from.unit, criterion, style); + } + }, + + _convertEm: function(dom, value, unit, criterion, style) { + var fontSize = this._getCriterionEm(dom, criterion, style); + if (value === 0) { + return 0; + } + + if (unit === 'px') { + return value / fontSize; + } else if (unit === '%') { + return (value / 100 * this._getCriterionPercent(dom, criterion, style)) / fontSize; + } else if (unit === 'cm' || unit === 'pt') { + return this._convertPx(dom, value, unit, criterion, style) / fontSize; + } + + return false; + }, + + _convertPer: function(dom, value, unit, criterion, style) { + var parentValue = this._getCriterionPercent(dom, criterion, style); + + if (value === 0) { + return 0; + } + + if (unit === 'px') { + return value / parentValue * 100; + } else if (unit === 'em') { + return (value * this._getCriterionEm(dom, criterion, style)) / parentValue * 100; + } else if (unit === 'cm' || unit === 'pt') { + return this._convertPx(dom, value, unit, criterion, style) / parentValue * 100; + } + + return false; + }, + + _convertPx: function(dom, value, unit, criterion, style) { + if (value === 0) { + return 0; + } + + if (unit === '%') { + return value / 100 * this._getCriterionPercent(dom, criterion, style); + } else if (unit === 'em') { + return value * (value * this._getCriterionEm(dom, criterion, style)); + } else if (unit === 'cm') { + return value * 37.795; + } else if (unit === 'pt') { + return value * 1.3; + } + + return false; + }, + + _convertCm: function(dom, value, unit, criterion, style) { + var pxValue; + + if (value === 0) { + return 0; + } + + if (unit !== 'px') { + pxValue = this._convertPx(dom, value, unit, criterion, style); + } else { + pxValue = value; + } + + return pxValue * 0.02646; + }, + + _convertPt: function(dom, value, unit, criterion, style) { + var ptValue; + + if (value === 0) { + return 0; + } + + if (unit !== 'px') { + ptValue = this._convertPx(dom, value, unit, criterion, style); + } else { + ptValue = value; + } + + return ptValue * 0.75; + } + + }); + + /* + * Makes CSS properties for animation. If user uses CSS property, the animation is going to make it's properties. + */ + ns.CssAnimationUtil = ns.base.singleTon(CssAnimationUtil); + +})(window, ns, ns.base); +/* + * # Animation Util + * + * Makes utilities for animation such as stagger, option, pre-defined effect, and keyframe. + * This module provide additional feature to help SimpleAnimation. + * Animation Util convert pre-defined effect, keyframe, option. Simple Animation will use based on this information. + * Also, Animation Util check whether stagger is on or not. + * + * @class ns.AnimationUtil + */ +(function(window, ns, base) { + var AnimationUtil = { + + /** + * Returns option for animation. Because option value can be various type, this function make unified expression. + * @method optionAnalyzer + * @param {Object|Number} arg1 + * The arg1 can be option Object as {duration: 1000, ease: 'bounceOut', delay: 100} OR number value that indicate duration + * @param {Object|undefined} arg2 + * The arg2 can be Object as {ease: 'bounceOut', delay: 100} OR undefined + * @return {Object} + * @member ns.AnimationUtil + * @static + */ + optionAnalyzer: function(arg1, arg2) { + var option; + + if (arg1 !== undefined) { + if (typeof arg1 === 'number') { + if (arg2 && typeof arg2 === 'object') { + option = arg2; + } else { + option = {}; + } + option.duration = arg1; + } else if (typeof arg1 === 'object') { + option = arg1; + } + } else { + option = {}; + option.duration = 1000; + } + return option; + }, + + /** + * Checks stagger option that included option of animation. If stagger is set, delay values of all targets are set in serial order automatically. + * @method checkStagger + * @param {Object} targets + * If stagger option is exists, this targets will be applied delay in serial order. + * @param {Object} option + * the option include stagger, drag, ease, and so on. + * @param {Function} callback + * The callback function will be called after this function. Actually, callback handle option value about targets. + * @member ns.AnimationUtil + * @static + */ + checkStagger: function(targets, option, callback) { + var i, len, o; + this.animations = []; + + // stagger + for (i = 0, len = targets.length; i < len; i++) { + o = ns.base.deepCopy(option); + + if (option.stagger) { + o.delay = option.stagger * i + (option.delay || 0); + o.reverseDelay = option.stagger * (len - i); + } + + if (i !== 0 && option.drag) { + o.duration += (option.drag * i); + } + + if (i === 0 && option.onStart) { + o.onStart = option.onStart; + } + /* else if (i === len - 1 && option.onComplete) { + o.onComplete = option.onComplete; + }*/ + + callback(targets[i], o, i); + } + }, + + /** + * Creates Keyframe for animation. If user make keyframe, this function will be called and make appropriate value for animation. + * @method createKeyFrame + * @param {Object} frame + * The frame has keyframe information. Keyframe animation based on frame. + * @param {Object} option + * The Option has ease, delay, duration, and so on. + * @param {Function} callback + * After handling based on frame and option, callback will invoked with result of handling. + * @member ns.AnimationUtil + * @static + */ + createKeyFrame: function(frame, option, callback) { + var i, j, l, preDuration, ft, o, offset = [], frames = []; + + for (i in frame) { + offset.push(parseFloat(i)); + } + + offset.sort(function(a, b) { + return a - b; + }); + preDuration = offset[0]; + + for (i = 0, l = offset.length - 1; i < l; i++) { + o = ns.base.deepCopy(option); + ft = {}; + + for (j in frame[offset[i + 1]]) { + if (frame[offset[i]][j] !== undefined) { + ft[j] = [frame[offset[i]][j], frame[offset[i + 1]][j]] + } else { + ft[j] = frame[offset[i + 1]][j]; + } + } + + o.duration = option.duration * (offset[i + 1] - preDuration); + preDuration = offset[i + 1]; + + if (i === 0) { + + option.onStart && (o.onStart = option.onStart); + option.delay && (o.delay = option.delay); + o.reverseDelay = 0; + + } else { + + option.delay && (o.delay = 0); + option.stagger && (o.delay = 0); + + if (i === l - 1) { + + option.onComplete && (o.onComplete = option.onComplete); + + + } else { + o.reverseDelay = 0; + } + } + +// if(option.stagger) { +// if(i !== 0) { +// o.delay = 0; +// } +// if(i !== l-1) { +// o.reverseDelay = 0; +// } +// } +// console.log(o.delay); + callback(ft, o, i); + } + }, + + /** + * Analyzes effect as pre-defined. This function make keyframe based frame, cubic-bezier based ease, transformOrigin value, visibility. + * @method effectAnalyzer + * @param {Object} target + * @param {String} animation + * The animation is a effect as a String. + * @return {Array} + * @member ns.AnimationUtil + * @static + */ + effectAnalyzer: function(target, animation) { + var predefined, frame, ease, transformOrigin, visibility, + width = ns.CssAnimationUtil.getInstance()._getCriterionPercent(target.dom, 'width'), + height = ns.CssAnimationUtil.getInstance()._getCriterionPercent(target.dom, 'height'); + predefined = animation; + + target.dom.style.opacity = target.dom.style.opacity ? target.dom.style.opacity : 1; + + if (predefined === 'pulse') { + frame = { + 0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY}, + 0.5: {scaleX: 1.05 * target.cur.scaleX, scaleY: 1.05 * target.cur.scaleY}, + 1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY} + }; + } else if (predefined === 'rollIn') { + frame = { + 0: {translateX: -100 + target.cur.translateX, rotateZ: -120 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}, + 1: {translateX: 0 + target.cur.translateX, rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity} + }; + + } else if (predefined === 'rollOut') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 1: {translateX: 200 + target.cur.translateX, rotateZ: 120 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'bounce') { + frame = { + 0: {translateY: 0 + target.cur.translateY}, + 0.2: {translateY: 0 + target.cur.translateY}, + 0.4: {translateY: -30 + target.cur.translateY}, + 0.5: {translateY: 0 + target.cur.translateY}, + 0.7: {translateY: -15 + target.cur.translateY}, + 0.8: {translateY: 0 + target.cur.translateY}, + 0.9: {translateY: -4 + target.cur.translateY}, + 1: {translateY: 0 + target.cur.translateY} + }; + ease = ['bounce1', 'bounce1', 'bounce2', 'bounce1', 'bounce2', 'bounce1', '', 'bounce1']; + transformOrigin = 'center bottom'; + } else if (predefined === 'bounceIn') { + frame = { + 0: {scaleX: 0.3 * target.cur.scaleX, scaleY: 0.3 * target.cur.scaleY}, + 0.2: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY}, + 0.4: {scaleX: 0.9 * target.cur.scaleX, scaleY: 0.9 * target.cur.scaleY}, + 0.6: {scaleX: 1.03 * target.cur.scaleX, scaleY: 1.03 * target.cur.scaleY}, + 0.8: {scaleX: 0.97 * target.cur.scaleX, scaleY: 0.97 * target.cur.scaleY}, + 1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY} + }; + ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1']; + } else if (predefined === 'bounceInDown') { + frame = { + 0: {translateY: -3000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity}, + 0.6: {translateY: 25 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.75: {translateY: -10 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.9: {translateY: 5 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 1: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity} + }; + ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1']; + } else if (predefined === 'bounceInLeft') { + frame = { + 0: {translateX: -3000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity}, + 0.6: {translateX: 25 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 0.75: {translateX: -10 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 0.9: {translateX: 5 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 1: {translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity} + }; + ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1']; + } else if (predefined === 'bounceInRight') { + frame = { + 0: {translateX: 3000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity}, + 0.6: {translateX: -25 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 0.75: {translateX: 10 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 0.9: {translateX: -5 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 1: {translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity} + }; + ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1']; + } else if (predefined === 'bounceInUp') { + frame = { + 0: {translateY: 3000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity}, + 0.6: {translateY: -25 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.75: {translateY: 10 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.9: {translateY: -5 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 1: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity} + }; + ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1']; + } else if (predefined === 'bounceOut') { + frame = { + 0.2: {opacity: 0 * target.dom.style.opacity, scaleX: 0.9 * target.cur.scaleX, scaleY: 0.9 * target.cur.scaleY}, + 0.5: {opacity: 1 * target.dom.style.opacity, scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY}, + 1: {opacity: 0 * target.dom.style.opacity, scaleX: 0.3 * target.cur.scaleX, scaleY: 0.3 * target.cur.scaleY} + }; + } else if (predefined === 'bounceOutDown') { + frame = { + 0: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.1: {translateY: 10 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.45: {translateY: -20 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 1: {translateY: 2000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'bounceOutLeft') { + frame = { + 0: {translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 0.2: {translateX: 20 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 1: {translateX: -2000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'bounceOutRight') { + frame = { + 0: {translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 0.2: {translateX: -20 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 1: {translateX: 2000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'bounceOutUp') { + frame = { + 0: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.2: {translateY: -10 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.45: {translateY: 20 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 1: {translateY: -2000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'zoomIn') { + frame = { + 0: {scaleX: 0.3 * target.cur.scaleX, scaleY: 0.3 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity}, + 0.5: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity} + }; + } else if (predefined === 'zoomInDown') { + frame = { + 0: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity, translateX: 0 + target.cur.translateX, translateY: -1000 + target.cur.translateY}, + 0.6: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX, translateY: 60 + target.cur.translateY}, + 1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX, translateY: 0 + target.cur.translateY} + }; + ease = ['zoomInDown', 'backOut']; + } else if (predefined === 'zoomInLeft') { + frame = { + 0: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity, translateX: -1000 + target.cur.translateX}, + 0.6: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateX: 10 + target.cur.translateX}, + 1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateX} + }; + ease = ['zoomInDown', 'backOut']; + } else if (predefined === 'zoomInRight') { + frame = { + 0: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity, translateX: 1000 + target.cur.translateX, translateY: target.cur.translateY}, + 0.6: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateX: -10 + target.cur.translateX, translateY: target.cur.translateY}, + 1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateY: target.cur.translateY} + }; + ease = ['zoomInDown', 'backOut']; + } else if (predefined === 'zoomInUp') { + frame = { + 0: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity, translateY: 1000 + target.cur.translateY}, + 0.6: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateY: -60 + target.cur.translateY}, + 1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY} + }; + ease = ['zoomInDown', 'backOut']; + } else if (predefined === 'zoomOut') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 0.6: {scaleX: 0.3 * target.cur.scaleX, scaleY: 0.3 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity}, + 1: {opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'zoomOutDown') { + frame = { + 0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.4: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, translateY: -60 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 1: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, translateY: 2000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity} + }; + ease = ['zoomInDown', 'backOut']; + transformOrigin = 'center bottom'; + } else if (predefined === 'zoomOutLeft') { + frame = { + 0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 0.4: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, translateX: 42 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 1: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, translateX: -2000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity} + }; + transformOrigin = 'left center'; + } else if (predefined === 'zoomOutRight') { + frame = { + 0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 0.4: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, translateX: -42 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}, + 1: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, translateX: 2000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity} + }; + transformOrigin = 'right center'; + } else if (predefined === 'zoomOutUp') { + frame = { + 0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 0.4: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, translateY: 60 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}, + 1: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, translateY: -2000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity} + }; + ease = ['zoomInDown', 'backOut']; + transformOrigin = 'center bottom'; + } else if (predefined === 'slideInDown') { + frame = { + 0: {translateY: (height * -1) + target.cur.translateY}, + 1: {translateY: 0 + target.cur.translateY} + }; + visibility = 'visible'; + } else if (predefined === 'slideInLeft') { + frame = { + 0: {translateX: (width * -1) + target.cur.translateX}, + 1: {translateX: 0 + target.cur.translateX} + }; + visibility = 'visible'; + } else if (predefined === 'slideInRight') { + frame = { + 0: {translateX: (width * 1) + target.cur.translateX}, + 1: {translateX: 0 + target.cur.translateX} + }; + visibility = 'visible'; + } else if (predefined === 'slideInUp') { + frame = { + 0: {translateY: (height * 1) + target.cur.translateY}, + 1: {translateY: 0 + target.cur.translateY} + }; + visibility = 'visible'; + } else if (predefined === 'slideOutDown') { + frame = { + 0: {translateY: 0 + target.cur.translateY}, + 1: {translateY: (height * 1) + target.cur.translateY} + }; + visibility = 'hidden'; + } else if (predefined === 'slideOutLeft') { + frame = { + 0: {translateX: 0 + target.cur.translateX}, + 1: {translateX: (width * -1) + target.cur.translateX} + }; + visibility = 'hidden'; + } else if (predefined === 'slideOutRight') { + frame = { + 0: {translateX: 0 + target.cur.translateX}, + 1: {translateX: (width * 1) + target.cur.translateX} + }; + visibility = 'hidden'; + } else if (predefined === 'slideOutUp') { + frame = { + 0: {translateY: 0 + target.cur.translateY}, + 1: {translateY: (height * -1) + target.cur.translateY} + }; + visibility = 'hidden'; + } else if (predefined === 'flash') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 0.25: {opacity: 0 * target.dom.style.opacity}, + 0.5: {opacity: 1 * target.dom.style.opacity}, + 0.75: {opacity: 0 * target.dom.style.opacity}, + 1: {opacity: 1 * target.dom.style.opacity} + }; + } else if (predefined === 'rubberBand') { + frame = { + 0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY}, + 0.3: {scaleX: 1.25 * target.cur.scaleX, scaleY: 0.75 * target.cur.scaleY}, + 0.4: {scaleX: 0.75 * target.cur.scaleX, scaleY: 1.25 * target.cur.scaleY}, + 0.5: {scaleX: 1.15 * target.cur.scaleX, scaleY: 0.85 * target.cur.scaleY}, + 0.65: {scaleX: 0.95 * target.cur.scaleX, scaleY: 1.05 * target.cur.scaleY}, + 0.75: {scaleX: 1.05 * target.cur.scaleX, scaleY: 0.95 * target.cur.scaleY}, + 1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY} + }; + } else if (predefined === 'shake') { + frame = { + 0: {translateX: 0 + target.cur.translateX}, + 0.1: {translateX: -10 + target.cur.translateX}, + 0.2: {translateX: 10 + target.cur.translateX}, + 0.3: {translateX: -10 + target.cur.translateX}, + 0.4: {translateX: 10 + target.cur.translateX}, + 0.5: {translateX: -10 + target.cur.translateX}, + 0.6: {translateX: 10 + target.cur.translateX}, + 0.7: {translateX: -10 + target.cur.translateX}, + 0.8: {translateX: 10 + target.cur.translateX}, + 0.9: {translateX: -10 + target.cur.translateX}, + 1: {translateX: 0 + target.cur.translateX} + }; + } else if (predefined === 'swing') { + frame = { + 0: {rotateZ: 0 + target.cur.rotateZ}, + 0.2: {rotateZ: 15 + target.cur.rotateZ}, + 0.4: {rotateZ: -10 + target.cur.rotateZ}, + 0.6: {rotateZ: 5 + target.cur.rotateZ}, + 0.8: {rotateZ: -5 + target.cur.rotateZ}, + 1: {rotateZ: 0 + target.cur.rotateZ} + }; + transformOrigin = 'top center'; + } else if (predefined === 'tada') { + frame = { + 0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, rotateZ: 0 + target.cur.rotateZ}, + 0.15: {scaleX: 0.9 * target.cur.scaleX, scaleY: 0.9 * target.cur.scaleY, rotateZ: -3 + target.cur.rotateZ}, + 0.3: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: 3 + target.cur.rotateZ}, + 0.4: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: -3 + target.cur.rotateZ}, + 0.5: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: 3 + target.cur.rotateZ}, + 0.6: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: -3 + target.cur.rotateZ}, + 0.7: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: 3 + target.cur.rotateZ}, + 0.8: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: -3 + target.cur.rotateZ}, + 0.9: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: 3 + target.cur.rotateZ}, + 1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, rotateZ: 0 + target.cur.rotateZ} + }; + } else if (predefined === 'wobble') { + frame = { + 0: {translateX: 0 + target.cur.translateX, rotateZ: 0 + target.cur.rotateZ}, + 0.15: {translateX: (width * -0.25) + target.cur.translateX, rotateZ: -5 + target.cur.rotateZ}, + 0.3: {translateX: (width * 0.2) + target.cur.translateX, rotateZ: 3 + target.cur.rotateZ}, + 0.45: {translateX: (width * -0.15) + target.cur.translateX, rotateZ: -3 + target.cur.rotateZ}, + 0.6: {translateX: (width * 0.1) + target.cur.translateX, rotateZ: 2 + target.cur.rotateZ}, + 0.75: {translateX: (width * -0.05) + target.cur.translateX, rotateZ: -1 + target.cur.rotateZ}, + 1: {translateX: 0 + target.cur.translateX, rotateZ: 0 + target.cur.rotateZ} + }; + } else if (predefined === 'jello') { + frame = { + 0: {skewX: 0 + target.cur.skewX, skewY: 0 + target.cur.skewY}, + 0.22: {skewX: -12.5 + target.cur.skewX, skewY: -12.5 + target.cur.skewY}, + 0.33: {skewX: 6.25 + target.cur.skewX, skewY: 6.25 + target.cur.skewY}, + 0.44: {skewX: -3.125 + target.cur.skewX, skewY: -3.125 + target.cur.skewY}, + 0.55: {skewX: 1.5625 + target.cur.skewX, skewY: 1.5625 + target.cur.skewY}, + 0.66: {skewX: -0.78125 + target.cur.skewX, skewY: -0.78125 + target.cur.skewY}, + 0.77: {skewX: 0.390625 + target.cur.skewX, skewY: 0.390625 + target.cur.skewY}, + 0.88: {skewX: -0.1953125 + target.cur.skewX, skewY: -0.1953125 + target.cur.skewY}, + 1: {skewX: 0 + target.cur.skewX, skewY: 0 + target.cur.skewY} + }; + transformOrigin = 'center'; + } else if (predefined === 'fadeIn') { + frame = { + 0: {opacity: 0 * target.dom.style.opacity}, + 1: {opacity: 1 * target.dom.style.opacity} + }; + } else if (predefined === 'fadeInDown') { + frame = { + 0: {translateY: (height * -1) + target.cur.translateY, opacity: 0 * target.dom.style.opacity}, + 1: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity} + }; + } else if (predefined === 'fadeInDownBig') { + frame = { + 0: {opacity: 0 * target.dom.style.opacity, translateY: -2000 + target.cur.translateY}, + 1: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY} + }; + } else if (predefined === 'fadeInLeft') { + frame = { + 0: {opacity: 0 * target.dom.style.opacity, translateX: (width * -1) + target.cur.translateX}, + 1: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX} + }; + } else if (predefined === 'fadeInLeftBig') { + frame = { + 0: {opacity: 0 * target.dom.style.opacity, translateX: -2000 + target.cur.translateX}, + 1: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX} + }; + } else if (predefined === 'fadeInRight') { + frame = { + 0: {opacity: 0 * target.dom.style.opacity, translateX: (width * 1) + target.cur.translateX}, + 1: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX} + }; + } else if (predefined === 'fadeInRightBig') { + frame = { + 0: {opacity: 0 * target.dom.style.opacity, translateX: 2000 + target.cur.translateX}, + 1: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX} + }; + } else if (predefined === 'fadeInUp') { + frame = { + 0: {opacity: 0 * target.dom.style.opacity, translateY: (height * 1) + target.cur.translateY}, + 1: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY} + }; + + } else if (predefined === 'fadeInUpBig') { + frame = { + 0: {opacity: 0 * target.dom.style.opacity, translateY: 2000 + target.cur.translateY}, + 1: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY} + }; + } else if (predefined === 'fadeOut') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 1: {opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'fadeOutDown') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY}, + 1: {opacity: 0 * target.dom.style.opacity, translateY: (height * 1) + target.cur.translateY} + }; + } else if (predefined === 'fadeOutDownBig') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY}, + 1: {opacity: 0 * target.dom.style.opacity, translateY: 2000 + target.cur.translateY} + }; + } else if (predefined === 'fadeOutLeft') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX}, + 1: {opacity: 0 * target.dom.style.opacity, translateX: (width * -1) + target.cur.translateX} + }; + } else if (predefined === 'fadeOutLeftBig') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX}, + 1: {opacity: 0 * target.dom.style.opacity, translateX: -2000 + target.cur.translateX} + }; + } else if (predefined === 'fadeOutRight') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX}, + 1: {opacity: 0 * target.dom.style.opacity, translateX: (width * 1) + target.cur.translateX} + }; + } else if (predefined === 'fadeOutRightBig') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX}, + 1: {opacity: 0 * target.dom.style.opacity, translateX: 2000 + target.cur.translateX} + }; + } else if (predefined === 'fadeOutUp') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY}, + 1: {opacity: 0 * target.dom.style.opacity, translateY: (height * -1) + target.cur.translateY} + }; + } else if (predefined === 'fadeOutUpBig') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY}, + 1: {opacity: 0 * target.dom.style.opacity, translateY: -2000 + target.cur.translateY} + }; + } else if (predefined === 'flip') { + frame = { + 0: {rotateY: -360 + target.cur.rotateY, perspective: 400}, + 0.4: {rotateY: -190 + target.cur.rotateY, translateZ: 150 + target.cur.translateZ, perspective: 400}, + 0.5: {rotateY: -170 + target.cur.rotateY, translateZ: 150 + target.cur.translateZ, perspective: 400}, + 0.8: {scaleX: 0.95 * target.cur.scaleX, scaleY: 0.95 * target.cur.scaleY, perspective: 400}, + 1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, rotateY: 0 + target.cur.rotateY, translateZ: 0 + target.cur.translateZ, perspective: 400} + }; + ease = ['easeIn', 'easeIn', 'easeIn', 'easeIn', 'easeIn']; + } else if (predefined === 'flipInX') { + frame = { + 0: {rotateX: 90 + target.cur.rotateX, perspective: 400, opacity: 0 * target.dom.style.opacity}, + 0.4: {rotateX: -20 + target.cur.rotateX, perspective: 400, opacity: 1 * target.dom.style.opacity}, + 0.6: {rotateX: 10 + target.cur.rotateX, perspective: 400, opacity: 1 * target.dom.style.opacity}, + 0.8: {rotateX: -5 + target.cur.rotateX, perspective: 400, opacity: 1 * target.dom.style.opacity}, + 1: {rotateX: 0 + target.cur.rotateX, perspective: 400, opacity: 1 * target.dom.style.opacity} + }; + ease = ['easeIn', 'easeIn', 'easeIn', 'easeIn', 'easeIn']; + } else if (predefined === 'flipInY') { + frame = { + 0: {rotateY: 90 + target.cur.rotateY, perspective: 400, opacity: 0 * target.dom.style.opacity}, + 0.4: {rotateY: -20 + target.cur.rotateY, perspective: 400, opacity: 1 * target.dom.style.opacity}, + 0.6: {rotateY: 10 + target.cur.rotateY, perspective: 400, opacity: 1 * target.dom.style.opacity}, + 0.8: {rotateY: -5 + target.cur.rotateY, perspective: 400, opacity: 1 * target.dom.style.opacity}, + 1: {rotateY: 0 + target.cur.rotateY, perspective: 400, opacity: 1 * target.dom.style.opacity} + }; + ease = ['easeIn', 'easeIn', 'easeIn', 'easeIn', 'easeIn']; + } else if (predefined === 'flipOutX') { + frame = { + 0: {perspective: 400}, + 0.3: {perspective: 400, rotateX: -20 + target.cur.rotateX, opacity: 1 * target.dom.style.opacity}, + 1: {perspective: 400, rotateX: 90 + target.cur.rotateX, opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'flipOutY') { + frame = { + 0: {perspective: 400}, + 0.3: {perspective: 400, rotateY: -15 + target.cur.rotateY, opacity: 1 * target.dom.style.opacity}, + 1: {perspective: 400, rotateY: 90 + target.cur.rotateY, opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'lightSpeedIn') { + frame = { + 0: {translateX: (width * 1) + target.cur.translateX, skewX: -30 + target.cur.skewX, opacity: 0 * target.dom.style.opacity}, + 0.6: {translateX: 0 + target.cur.translateX, skewX: 20 + target.cur.skewX, opacity: 1 * target.dom.style.opacity}, + 0.8: {translateX: 0 + target.cur.translateX, skewX: -5 + target.cur.skewX, opacity: 1 * target.dom.style.opacity}, + 1: {translateX: 0 + target.cur.translateX, skewX: 0 + target.cur.skewX, opacity: 1 * target.dom.style.opacity} + }; + } else if (predefined === 'lightSpeedOut') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 1: {translateX: (width * 1) + target.cur.translateX, skewX: 30 + target.cur.skewX, opacity: 0 * target.dom.style.opacity} + }; + } else if (predefined === 'rotateIn') { + frame = { + 0: {rotateZ: -200 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}, + 1: {rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity} + }; + transformOrigin = 'center'; + } else if (predefined === 'rotateInDownLeft') { + frame = { + 0: {rotateZ: -45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}, + 1: {rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity} + }; + + transformOrigin = 'left bottom'; + } else if (predefined === 'rotateInDownRight') { + frame = { + 0: {rotateZ: 45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}, + 1: {rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity} + }; + transformOrigin = 'right bottom'; + } else if (predefined === 'rotateInUpLeft') { + frame = { + 0: {rotateZ: 45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}, + 1: {rotateZ: +target.cur.rotateZ, opacity: 1 * target.dom.style.opacity} + }; + transformOrigin = 'left bottom'; + } else if (predefined === 'rotateInUpRight') { + frame = { + 0: {rotateZ: -90 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}, + 1: {rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity} + }; + transformOrigin = 'right bottom'; + } else if (predefined === 'rotateOut') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 1: {rotateZ: 200 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity} + }; + transformOrigin = 'center'; + } else if (predefined === 'rotateOutDownLeft') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 1: {rotateZ: 45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity} + }; + transformOrigin = 'left bottom'; + } else if (predefined === 'rotateOutDownRight') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 1: {rotateZ: -45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity} + }; + transformOrigin = 'right bottom'; + } else if (predefined === 'rotateOutUpLeft') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 1: {rotateZ: -45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity} + }; + transformOrigin = 'left bottom'; + } else if (predefined === 'rotateOutUpRight') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 1: {rotateZ: 90 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity} + }; + transformOrigin = 'right bottom'; + } else if (predefined === 'hinge') { + frame = { + 0: {opacity: 1 * target.dom.style.opacity}, + 0.2: {rotateZ: 80 + target.cur.rotateZ}, + 0.4: {rotateZ: 60 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity}, + 0.6: {rotateZ: 80 + target.cur.rotateZ}, + 0.8: {rotateZ: 60 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity}, + 1: {translateY: 700 + target.cur.translateY, opacity: 0 * target.dom.style.opacity} + }; + transformOrigin = 'top left'; + ease = ['easeInOut', 'easeInOut', 'easeInOut', 'easeInOut', 'easeInOut', 'easeInOut']; + } else { + throw new Error('the name of animation is not exists'); + } + + return [frame, ease, transformOrigin, visibility]; + } + }; + + ns.AnimationUtil = AnimationUtil; +})(window, ns, ns.base); +// TODO + +(function(window, ns, base) { + var _singleton; + + var ObjectManager = base.Class.extend({ + + _init: function() { + if (_singleton !== undefined) { + _singleton = new this(); + return _singleton; + } + this.targetObjects = []; + + return this; + }, + + /** + * Add animation object to manager. + * @method addTarget + * @param {target} animation object + * @member ns.ObjectManager.addTarget + * @private + */ + addTarget: function(target) { + this.targetObjects.push(target); + target.map = new ns.base.WeakMap(); + }, + + /** + * Create animation object. + * @method getObject + * @param {target} animation object + * @member ns.ObjectManager.getObject + * @private + */ + getObject: function(obj) { + + if (obj instanceof ns.AnimationObject) { + return obj; + } + + for (var i = 0, len = this.targetObjects.length; i < len; i++) { + if(obj instanceof this.targetObjects[i].$type) { + + var object = this.targetObjects[i].map.get(obj); + + if(object === undefined) { + object = new ns[this.targetObjects[i].$namespace](obj); + this.targetObjects[i].map.set(obj, object); + } + return object; + } + } + + throw 'CannotCreateObject'; + + return; + }, + + + static: { + /** + * Return ObjectManger object + * @method getInstance + * @return {object} + * @member ns.ObjectManager.getInstance + * @static + */ + getInstance: function() { + if (_singleton === undefined) { + _singleton = new ObjectManager(); + } + return _singleton; + }, + + /** + * Create Animation Object by using plugin + * @method plugin + * @param {object} + * @member ns.ObjectManager.plugin + * @static + */ + plugin: function(definition) { + var keywordTest = /^\$(?:namespace|constructor|type)$/; + + if( (!definition.$constructor) ) { + return; + } + // TODO : $namespace, type 예외 처리 + function Class() { + ns.AnimationObject.call(this); + definition.$constructor.apply(this, arguments); + } + + Class.prototype = new ns.AnimationObject(); + Class.prototype.constructor = Class; + + for(var name in definition) { + if(keywordTest.test(name)) { + continue; + } + + Class.prototype[name] = typeof definition[name] === 'function' && definition[name]; + } + + ns[definition.$namespace] = Class; + + this.getInstance().addTarget(definition); + + return Class; + } + } + }); + + /* + * Manages objects that will be animated. + */ + ns.ObjectManager = ObjectManager; + +})(window, ns, ns.base); + + + +(function(window) { + 'use strict'; + + (function(window, ns, base) { + var AnimationObject = ns.base.Class.extend({ + _init: function() { + this.from = new ns.Transform(); + this.cur = base.copy(this.from); + + this.updateSeek = false; + this.updateSeekProperty = []; + }, + + getFrom: function(to) { + var v = {}; + var to = to.animation; + for(var i in to){ + v[i] = this.from[i]; + this.from[i] = to[i]; + } + return v; + }, + + setFrom: function(v) { + this.from.set(v); + }, + translate: function() { + + }, + rotate: function() { + + } + }); + + /* + * Manages animationObject. + */ + ns.AnimationObject = AnimationObject; + + })(window, ns, ns.base); + +})(window); +(function(window, ns, base) { + 'use strict'; + var CssAnimationUtil = ns.CssAnimationUtil.getInstance(), + CssStringCreator = ns.CssStringCreator.getInstance(); + + /* + * Constructs and Sets based on DOMObject. DOM Object is the one of target for animation. + */ + + ns.ObjectManager.plugin({ + $namespace: 'DomObject', + $type: window.HTMLElement, + $constructor: function(dom) { + this.dom = dom; + //this.style = dom.style; + this.unit = {}; + this._perspective = false; + }, + + /** + * Render dom object on screen. + * @method render + * @param {value} update target value + * @param {unit} unix + * @member ns.DomObject + * @private + */ + render: function(tweenInfo) { + var i, u = tweenInfo.updateProperty, l; + for (i = 0; l = u[i]; i++) { + tweenInfo.targetStyle[l] = CssStringCreator[l](this, tweenInfo.unit); + } + //var isUpdateTransform = false; + // + //for(var i in updateValue) { + // if(!this.isTransform(i) && this.dom.style[i] !== undefined) { + // this.dom.style[i] = CssStringCreator[i](updateValue, unit); + // } else { + // if(!isUpdateTransform) { + // this.dom.style.WebkitTransform = CssStringCreator.WebkitTransform(updateValue); + // isUpdateTransform = true; + // } + // } + //} + }, + + objectRender: function(updateValue) { + var isUpdateTransform = false; + + for (var i in updateValue) { + if (!this.isTransform(i) && this.dom.style[i] !== undefined) { + this.dom.style[i] = CssStringCreator[i](updateValue, unit); + } else { + if (!isUpdateTransform) { + this.dom.style.WebkitTransform = CssStringCreator.WebkitTransform(updateValue); + isUpdateTransform = true; + } + } + } + }, + + /** + * Create tween object in order to animate dom object. + * @method createTweenObject + * @param {value} animation from value + * @param {value} animation to value + * @param {value} animation option including duration, delay, ease ans so on. + * @member ns.DomObject + * @private + */ + createTweenInfo: function(fromTo, option, needFromTo) { + var info = { + fromTo: {}, + animationFromTo: fromTo, + cur: this.cur, + option: option, + name: [], + unit: {}, + target: this, + targetStyle: this.dom.style, + updateProperty: [] + }; + + if (needFromTo) { + this.setAnimationFromTo(info); + } + + return info; + }, + + setAnimationFromTo: function(obj) { + var isTransform = false, + fromTo = obj.animationFromTo, + i; + + for (i in fromTo) { + if (this.isTransform(i)) { + CssAnimationUtil.WebkitTransform(i, obj); + if (!isTransform) { + obj.updateProperty.push('WebkitTransform'); + isTransform = true; + } + } else if (i === 'perspective') { + this._perspective = base.isNumber(fromTo[i]) ? fromTo[i] : (base.isNumber(fromTo[i][1]) ? fromTo[i][1] : 0); + this.cur.perspective = this._perspective; + } else { + if (CssAnimationUtil[i]) { + CssAnimationUtil[i](obj); + obj.updateProperty.push(i); + } + } + + } + }, + /** + * Check if it is transform or not. + * @method isTransform + * @param {string} + * @return {boolean} + * @member ns.DomObject + * @private + */ + isTransform: function(i) { + if (i === undefined || i === null) { + return; + } + if (i === 'translateX' || i === 'translateY' || i === 'translateZ' || + i === 'rotateX' || i === 'rotateY' || i === 'rotateZ' || + i === 'scaleX' || i === 'scaleY' || i === 'skewX' || i === 'skewY' /*|| i === 'perspective'*/) { + return true; + + } + return false; + }, + + /** + * Set perspective of dom object. + * @method perspective + * @param {number} perspective value + * @member ns.DomObject + * @private + */ + perspective: function(n) { + if (n === undefined || n === null) { + return; + } + if (!ns.base.isNumber(n)) { + return; + } + this._perspective = n; + this.cur.perspective = n; + }, + + /** + * Set animation value of dom object + * @method set + * @param {value} animation value + * @member ns.DomObject + * @private + */ + set: function(v) { + if (v === undefined || v === null) { + return; + } + for (var i in v) { + if (this.isTransform(i)) { + this.from[i] = v[i]; + this.cur[i] = v[i]; + } else if (i === 'perspective') { + this.perspective(v[i]); + } else { + this.dom.style[i] = v[i]; + } + } + this.objectRender(base.deepCopy(this.from)); + } + }); +})(window, ns, ns.base); + +/** + * # TAU Animation + * + * Provides features that make and control animation. + * Simple Animation has relevance to Tween Animator. + * As you can see below APIs, almost APIs make Tween-able object and control animation. + * + * @example + * #### using tween and tween from ~ to + * + * $('#box').tween({left: 200}, {duration: 1000, ease: 'bounceInOut', onComplete: function() { + * console.log('animation complete'); + * } + * }); + * $('#box').tween({left: [200, 300]} {duration: 1000, ease: 'bounceInOut', onComplete: function() { + * console.log('animation complete'); + * } + * }); + * + * + * #### using tween and tween from ~ to as chaining + * + * var box = document.createElement('div'); + * box.tween({rotateZ: 120}, 1000) + * .tween({left: 200}, 1000) + * .tween({left: [200, 400], top: 100}, 1000); + * + * #### effect animation with stagger + * + * $('.box').animate('bounce', {duration: 1000, stagger: 200}); + * + * + * @class tau.animation.SimpleAnimationMixinObject + */ +(function(window, ns, base) { + 'use strict'; + + var ObjectManager = ns.ObjectManager.getInstance(); + + var SimpleAnimationMixinObject = { + /** + * Adds tween animation with animation information and target is animated. + * @method tween + * @member tau.animation.SimpleAnimationMixinObject + * @public + */ + tween: function(fromTo, arg1, arg2) { + var option; + + if (!this.simpleAnimation) { + if (this.length) { + this.simpleAnimation = new ns.SimpleAnimationGroup(this); + } else { + this.simpleAnimation = new ns.SimpleAnimation(this); + } + } + + option = ns.AnimationUtil.optionAnalyzer(arg1, arg2); + this.simpleAnimation.add(fromTo, option); + this.simpleAnimation.play(); + + return this; + }, + + /** + * Stops animation or group animations. + * @method stop + * @member tau.animation.SimpleAnimationMixinObject + * @public + */ + stop: function() { + if (!this.simpleAnimation) { + + if (!this.simpleAnimation) { + if (this.length) { + this.simpleAnimation = new ns.SimpleAnimationGroup(this); + } else { + this.simpleAnimation = new ns.SimpleAnimation(this); + } + } + + } + this.simpleAnimation.stop(); + + }, + + /** + * Sets transform property of target. + * @method transform + * @member tau.animation.SimpleAnimationMixinObject + * @public + */ + transform: function(v) { + if (!this.simpleAnimation) { + if (this.length) { + this.simpleAnimation = new ns.SimpleAnimationGroup(this); + } else { + this.simpleAnimation = new ns.SimpleAnimation(this); + } + } + + this.simpleAnimation.target.set(v); + } + }; + + /** + * Makes simpleAnimation for playing animation. + * @constructor SimpleAnimation + * @param {Object} target + * The target is animated by tween animator. + * @member tau.animation.SimpleAnimation + * @private + */ + var SimpleAnimation = function(target) { + + this.tweenAnimator = new ns.TweenAnimator(); + this.target = ObjectManager.getObject(target); // get animation object + this.target.simpleAnimation = this; + + this.target.render && this.tweenAnimator.setRender(this.target.render); + this.target.cur && this.tweenAnimator.setUpdateTarget(this.target.cur); + }; + + /** + * Adds tween information object in animator. + * @method add + * @param {Object} fromTo + * @param {Object} option + * @param {Object} secondTweenAnimator + * @member tau.animation.SimpleAnimation.prototype + * @private + */ + SimpleAnimation.prototype.add = function(fromTo, option, secondTweenAnimator) { + var frame, tweenObject, lastTween, st, + tweenAnimator = secondTweenAnimator || this.tweenAnimator, + self = this; + + if (typeof fromTo === 'string') { + frame = ns.AnimationUtil.effectAnalyzer(this.target, fromTo); + + ns.AnimationUtil.createKeyFrame(frame[0], option, function(ft, o, i) { + if (frame[1] !== undefined) { + o.ease = frame[1][i]; + } + + tweenObject = self.target.createTweenInfo(ft, o, true); + tweenAnimator.add(tweenObject); + + if (frame[2] !== undefined) { + if (i === 0) { + tweenObject.startCallback.on(function() { + self.target.dom.style.webkitTransformOrigin = frame[2]; + }); + } else if (i === frame.length) { + tweenObject.completeCallback.on(function() { + self.target.dom.style.webkitTransformOrigin = ''; + }); + } + } + + if (frame[3] !== undefined) { + tweenObject.completeCallback.on(function() { + self.target.dom.style.visibility = frame[3]; + }); + } + }); + + return; + } + + if (fromTo.effect) { + if (this.parTweensGroup === undefined) { + this.parTweensGroup = []; + st = new ns.TweenAnimator(); + this.parTweensGroup.push(st); + } else { + st = this.parTweensGroup[0]; + } + + this.target.render && st.setRender(this.target.render); + this.target.cur && st.setUpdateTarget(this.target.cur); + + this.add(fromTo.effect, base.deepCopy(option), st); + } + + if (tweenAnimator.getState() === 'running') { + tweenObject = self.target.createTweenInfo(fromTo, option, false); + + if (lastTween = tweenAnimator.getLastTweenInfo()) { + lastTween.completeCallback.on(function() { + self.target.setAnimationFromTo(tweenObject); + }); + } + + } else { + tweenObject = this.target.createTweenInfo(fromTo, option, true); + } + + tweenAnimator.add(tweenObject); + + }; + + /** + * Plays tween animation. + * @method play + * @member tau.animation.SimpleAnimation.prototype + * @private + */ + SimpleAnimation.prototype.play = function() { + var i , len; + this.tweenAnimator.play(); + if (this.parTweensGroup) { + for (i = 0, len = this.parTweensGroup.length; i < len; i++) { + this.parTweensGroup[i].play(); + } + } + }; + + /** + * Stops tween animation. + * @method stop + * @member tau.animation.SimpleAnimation.prototype + * @private + */ + SimpleAnimation.prototype.stop = function() { + var i , len; + this.tweenAnimator.stop(); + if (this.parTweensGroup) { + for (i = 0, len = this.parTweensGroup.length; i < len; i++) { + this.parTweensGroup[i].stop(); + } + } + }; + + /** + * Makes group of simpleAnimation. + * @constructor SimpleGroup + * @param {Array} t + * The target will be added Simple group. + * @member tau.animation.SimpleAnimationGroup + * @private + */ + function SimpleAnimationGroup(t) { + var i, simple; + + this.target = []; + this.len = t.length; + + for (i = 0; i < this.len; i++) { + if (!(simple = ObjectManager.getObject(t[i]).simpleAnimation)) { + this.target[i] = new ns.SimpleAnimation(t[i]); + } else { + this.target[i] = simple; + } + + } + } + + /** + * Adds animation to TweenObject + * @method add + * @param {Object} fromTo + * @param {Object} option + * The target will be added simple group + * @member tau.animation.SimpleGroup.prototype + * @private + */ + SimpleAnimationGroup.prototype.add = function(fromTo, option) { + var completedCnt = 0, + self = this; + + ns.AnimationUtil.checkStagger(this.target, option, function(t, o, idx) { + + if (option.onComplete) { + o.onComplete = function() { + completedCnt++; + if (completedCnt === self.len) { + t.tweenAnimator.getCurrentTweenInfo().completeCallback.on(option.onComplete); + } + }; + } + +// t.simpleAnimation.add(fromTo, o); + t.add(fromTo, o); + + }); + }; + + /** + * Plays animation. + * @method play + * The target will be added simple group + * @member tau.animation.SimpleAnimationGroup.prototype + * @private + */ + SimpleAnimationGroup.prototype.play = function() { + var i; + + for (i = 0; i < this.len; i++) { + this.target[i].play(); + } + }; + + /** + * Stop animation. + * @method play + * The target will be added simple group + * @member tau.animation.SimpleAnimationGroup.prototype + * @private + */ + SimpleAnimationGroup.prototype.stop = function() { + var i; + + for (i = 0; i < this.len; i++) { + this.target[i].stop(); + } + }; + + ns.SimpleAnimation = SimpleAnimation; + ns.SimpleAnimationGroup = SimpleAnimationGroup; + ns.SimpleAnimationMixinObject = SimpleAnimationMixinObject; + +})(window, ns, ns.base); + +/* + * # SimpleMixin + * + * Creates mixin object. + * If user animate pure DOM such as div, SimpleMixin is going to make appropriate target object. + * + * @class ns.SimpleMixin + */ +(function(window, ns) { + 'use strict'; + var SimpleAnimationMixinObject = ns.SimpleAnimationMixinObject; + + /** + * Returns target after mixin APIs. + * @method extendAnimation + * @param {Object} target + * @param {Object|undefined} getElementFn + * @return {Object} + * @member ns.SimpleMixin + * @static + */ + var mixin = function(target, getElementFn) { + var p; + + if (target.prototype !== undefined) { + (p = isProperty(target.prototype)) && throwMixinException(p); + + for (var i in SimpleAnimationMixinObject) { + target.prototype[i] = SimpleAnimationMixinObject[i]; + + } + } else if (target instanceof Object) { + (p = isProperty(target)) && throwMixinException(p); + + for (var i in SimpleAnimationMixinObject) { + if (SimpleAnimationMixinObject.hasOwnProperty(i)) { + target[i] = SimpleAnimationMixinObject[i]; + } + } + } else { + throwMixinException(); + } + return target; + }; + + function isProperty(t) { + var propertyTest = ['tween', 'stop', 'transform', 'simpleAnimation'], + i, len; + + for (i = 0, len = propertyTest.length; i < len; i++) { + if (t.hasOwnProperty(propertyTest[i])) { + return propertyTest[i]; + } + } + + return false; + + } + + function throwMixinException(p) { + var message = 'Function or Object can apply Mixin'; + (p !== undefined) ? (message += ': \"' + p + '\" is overrided.') : (message += '.'); + + console.warn(message); + + //throw "CannotTauAnimationMixinException"; + } + + ns.SimpleMixin = mixin; +})(window, ns); + +(function(window, ns) { + 'use strict'; + + var ObjectManager = ns.ObjectManager.getInstance(); + + /** + * Returns animation target object + * @method target + * @param {String} str + * The str indicate ID or class name for selecting HTML element + * @member ns.Target + * @return {Target} Target Object + * @public + * @class ns.Target + */ + + ns.SimpleMixin(ns.DomObject); + + ns.target = function(str) { + if (typeof str === 'string') { + var s = str.slice(0, 1), c = str.slice(1), + result; + + if (s === '.') { + result = document.getElementsByClassName(c); + if (!result.tween) { // TODO: not mixin + ns.SimpleMixin(result, function() { + return result + }); + } + } else if (s === '#') { + result = document.getElementById(c); + result = ObjectManager.getObject(result); + } else { + + } + } else { + if (str instanceof window.HTMLElement) { + result = ObjectManager.getObject(str); + } else { + + } + } + + return result; + }; + + //checking whether jQuery is loaded or not. + //if (window.jQuery && window.$) { + // ns.SimpleMixin($, $.get); + //} else { + // window.$ = ns.$; + //} + +})(window, ns); + +})(window); \ No newline at end of file diff --git a/d2d_app/client/lib/tau/animation/tau.animation.min.js b/d2d_app/client/lib/tau/animation/tau.animation.min.js new file mode 100644 index 0000000..baba450 --- /dev/null +++ b/d2d_app/client/lib/tau/animation/tau.animation.min.js @@ -0,0 +1,2 @@ +(function(t){!t.tau&&(t.tau={});var e=t.tau.animation={};(function(t,e){(function(){for(var e=0,i=["ms","moz","webkit","o"],a=0;i.length>a&&!t.requestAnimationFrame;++a)t.requestAnimationFrame=t[i[a]+"RequestAnimationFrame"],t.cancelAnimationFrame=t[i[a]+"CancelAnimationFrame"]||t[i[a]+"CancelRequestAnimationFrame"];void 0===t.requestAnimationFrame&&(t.requestAnimationFrame=function(i){var a=Date.now(),n=Math.max(0,16-(a-e)),r=t.setTimeout(function(){i(a+n)},n);return e=a+n,r}),t.cancelAnimationFrame=t.cancelAnimationFrame||function(e){t.clearTimeout(e)}})(),function(t,e){t.Uint8Array.prototype.setValue=function(){for(var t=0,e=this.length;e>t;t++){if(void 0===arguments[t])return;this[t]=arguments[t]}},e.getTime=function(){return t.performance?t.performance.now?function(){return t.performance.now()}:t.performance.webkitNow?function(){return t.performance.webkitNow()}:function(){return(new Date).getTime()}:function(){return(new Date).getTime()}}()}(t,e);var i={ENUM:{NODETYPE:{GROUP:1,ANIMATION:2},GROUPTYPE:{SEQUENCE:4,PARALLEL:8}},forEach:function(t,e){for(var i=0,a=t&&t.length;a>i;i++){var n=t[i];e(n,i)}},copy:function(t,e){e=e||{};for(var i in t)t.hasOwnProperty(i)&&"$$"!==i.substr(0,2)&&(e[i]=t[i]);return e},arrayCopy:function(t,i){var a,n=t.length;if(void 0!==n)for(void 0===i&&(i=t instanceof Uint8Array?new Uint8Array(n):[]),a=0;n>a;a++)i[a]="string"!=typeof t[a]&&void 0!==t[a].length?e.base.arrayCopy(t[a]):t[a];else i=t;return i},deepCopy:function(t,e){if("object"==typeof t){e=e||{},t.length!==void 0&&(t instanceof Array?e=[]:t instanceof Uint8Array&&(e=new Uint8Array(t.length)));for(var i in t)"object"==typeof t[i]?e[i]=this.deepCopy(t[i]):"string"==typeof t[i]?e[i]=t[i]:"number"==typeof t[i]?e[i]=t[i]:"boolean"==typeof t[i]&&(e[i]=1==t[i]?!0:!1)}else e=t;return e},singleTon:function(t){var e={};return e.getInstance=function(){return void 0===this._singleton&&(this._singleton=new t),this._singleton},e},isNumber:function(t){return"number"==typeof t},isFunction:function(t){return"function"==typeof t},isObject:function(t){return t instanceof Object},isArray:function(t){return t instanceof Array},selector:function(t){var e,i=t.slice(0,1),a=t.slice(1);return"."===i?e=document.getElementsByClassName(a):"#"===i&&(e=document.getElementById(a)),e}};i.WeakMap=function(){this.keys=[],this.values=[],this.i=0},i.WeakMap.prototype.del=function(t){return this.has(t)&&(this.keys.splice(this.i,1),this.values.splice(this.i,1)),this.i>-1},i.WeakMap.prototype.get=function(t,e){return this.has(t)?this.values[this.i]:e},i.WeakMap.prototype.has=function(t){if(t!==Object(t))throw new TypeError("not a non-null object");return this.i=Array.prototype.indexOf.call(this.keys,t),this.i>-1},i.WeakMap.prototype.set=function(t,e){this.has(t)?this.values[this.i]=e:this.values[this.keys.push(t)-1]=e},i.WeakMap.prototype.getKey=function(){return this.keys};var a=!1,n=/xyz/.test(function(){})?/\b_super\b/:/.*/;i.Class=function(){},i.Class.extend=function(t){function e(){return!a&&this._init?this._init.apply(this,arguments):void 0}var i=this.prototype,r=t.static;a=!0;var o=new this;a=!1;for(var s in t)"static"!==s&&(o[s]="function"==typeof t[s]&&"function"==typeof i[s]&&n.test(t[s])?function(t,e){return function(){var a=this._super;this._super=i[t];var n=e.apply(this,arguments);return this._super=a,n}}(s,t[s]):t[s]);if(e.prototype=o,e.prototype.constructor=e,e.extend=arguments.callee,r)for(var c in r)r.hasOwnProperty(c)&&(e[c]=r[c]);return e},e.base=i})(t,e),function(t,e){"use strict";var i=e.base.Class.extend({_init:function(){this.now=e.getTime,this._frameId=null,this.animators=[],this.animatorIdx=0},tickOn:function(){var i=this;(function a(){i._frameId=t.requestAnimationFrame(a);var n,r=e.getTime();for(n=0;i.animatorIdx>n;n++)i.animators[n].tick(r)})()},tickOff:function(){this._frameId&&(t.cancelAnimationFrame(this._frameId),this._frameId=null)},__on:function(t){0>this.animators.indexOf(t)&&(this.animators[this.animatorIdx]=t,this.animatorIdx++,null===this._frameId&&this.tickOn())},__off:function(t){var e=this.animators.indexOf(t);e>=0&&(this.animators.splice(e,1),this.animatorIdx--,0===this.animatorIdx&&this.tickOff())}});e.Ticker=e.base.singleTon(i)}(t,e),function(t,e){"use strict";function i(){this.regExpCubicBezier=/cubic-bezier\s*\(\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*\)/}function a(t,e,i,a){return function(t){var i=1-t,n=3*i,r=t*t,o=r*t,s=n*t*i,c=n*r;return s*e+c*a+o}}function n(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}var r;r=i.prototype,r.ease=a(.25,.1,.25,1),r.easeOut=a(0,0,.58,1),r.easeInOut=a(.42,0,.58,1),r.easeIn=a(.42,0,1,1),r.sineIn=a(.47,0,.745,.715),r.sineOut=a(.39,.575,.565,1),r.sineInOut=a(.445,.05,.55,.95),r.expoIn=a(.95,.05,.795,.035),r.expoOut=a(.19,1,.22,1),r.expoInOut=a(1,0,0,1),r.circIn=a(.6,.04,.98,.335),r.circOut=a(.075,.82,.165,1),r.circInOut=a(.785,.135,.15,.86),r.backIn=a(.6,-.28,.735,.045),r.backOut=a(.175,.885,.32,1.275),r.backInOut=a(.68,-.55,.265,1.55),r.zoomInDown=a(.55,.055,.675,.19),r.bounce1=a(.215,.61,.355,1),r.bounce2=a(.755,.05,.855,.06),r.linear=function(t){return t},r.cubicIn=function(t){return t*t*t},r.cubicOut=function(t){return--t*t*t+1},r.cubicInOut=function(t){return.5>t?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},r.quadIn=function(t){return t*t},r.quadOut=function(t){return t*(2-t)},r.quadInOut=function(t){return.5>t?2*t*t:-1+(4-2*t)*t},r.quartIn=function(t){return t*t*t*t},r.quartOut=function(t){return 1- --t*t*t*t},r.quartInOut=function(t){return.5>t?8*t*t*t*t:1-8*--t*t*t*t},r.quintIn=function(t){return t*t*t*t*t},r.quintOut=function(t){return 1+--t*t*t*t*t},r.quintInOut=function(t){return.5>t?16*t*t*t*t*t:1+16*--t*t*t*t*t},r.bounceOut=function(t){return n(t)},r.bounceIn=function(t){return 1-i.prototype.bounceOut(1-t)},r.bounceInOut=function(t){return.5>t?.5*i.prototype.bounceIn(2*t):.5*i.prototype.bounceOut(2*t-1)+.5};var o=2*Math.PI,s=.3/o*Math.asin(1);r.elasticIn=function(t){return 0===t||1===t?t:-(Math.pow(2,10*(t-=1))*Math.sin((t-s)*o/.3))},r.elasticOut=function(t){return 0===t||1===t?t:Math.pow(2,-10*t)*Math.sin((t-s)*o/.3)+1},r.elasticInOut=function(t){return 1>(t*=2)?-.5*Math.pow(2,10*(t-=1))*Math.sin((t-s)*o/.3):.5*Math.pow(2,-10*(t-=1))*Math.sin((t-s)*o/.3)+1},e.Ease=e.base.singleTon(i)}(t,e),function(t,e){"use strict";var i=e.Ticker.getInstance(),a=e.Ease.getInstance(),n={STOP:"stop",PAUSE:"pause",RUN:"running"},r={FORWARD:!0,REVERSE:!1},o=function(){var t=0,e=0,i=[];return{add:function(t){i[e]=t,e++},next:function(){return e>t?(t++,i[t-1]):!1},cur:function(){return t},rewind:function(){t=0},get:function(t){return void 0===t?i:i[t]},length:function(){return e},hasNext:function(){return e>t},clear:function(){0!==e&&e>=t&&i.splice(0,t),t=0,e=i.length},allClear:function(){i=[],t=e=0}}},s=function(){var t=[],e=0;return{on:function(i){t[e]=i,e++},onFront:function(i){t.unshift(i),e++},emit:function(){for(var i=0;e>i;i++)t[i].apply(null,arguments)},remove:function(i){for(var a=0;e>a;a++)t[a]===i&&(t[a].splice(a,1),e--)},getLength:function(){return e},removeAll:function(){t=[],e=0}}},c=e.base.Class.extend({_init:function(t,e){this.tweenQueue=o(),this.tweenInfo=null,this._direction=r.FORWARD,this._state=n.STOP,this._isTick=!1,this.isTweenInfo=!1,t&&this.add(t,e),this._startTime=this._lastTime=this._playTime=this._previousTime=0,this._totalTime=this._duration+this._delay,this._changedDirection=!1,this._isCache=!1},tick:function(t){if(this._state===n.RUN){var e=t,i=e-this._playTime;if(this._previousTime=e,0>i)return;this._duration>=i?(this.tweenInfo.progress=i/(this._duration||1),this._update()):(1!==this.tweenInfo.progress&&(this.tweenInfo.progress=1,this._update()),e>=this._lastTime&&this._complete())}},play:function(){this._state!==n.RUN&&(this._state===n.PAUSE?(this._direction!==r.FORWARD&&(this._direction=r.FORWARD,this._changedDirection=!0),this.resume()):(this._direction=r.FORWARD,this._play()))},reverse:function(){this._state!==n.RUN&&(this._state===n.PAUSE?(this._direction!==r.REVERSE&&(this._direction=r.REVERSE,this._changedDirection=!0),this.resume()):(this._direction=r.REVERSE,this._play()))},stop:function(){this._state!==n.STOP&&(this._stopTween(),this.tweenQueue.allClear())},pause:function(){this._state===n.RUN&&(this._state=n.PAUSE)},resume:function(t){var i=e.getTime();if(this._state===n.PAUSE){if(this._changedDirection||void 0!==t&&t!==this._direction)void 0!==t&&(this._direction=t),this._lastTime=i+this._previousTime-this._playTime,this._playTime=this._lastTime-this._duration,this._startTime=this._playTime-this._delay,this._changedDirection=!1;else{var a=i-this._previousTime;this._startTime+=a,this._playTime+=a,this._lastTime+=a}this._state=n.RUN}},seek:function(t){var e=t*this._totalTime-this._delay;e>=0&&this._update(e/this._duration)},getSeek:function(t,e){var i,a,n,t,r=this.tweenInfo.name,o=this.tweenInfo.to,s=this.tweenInfo.from;for(e&&(t=t*this._totalTime-this._delay),i=0;a=r[i];i++)this.cur[a]&&(n=this.cur[a].length)?(void 0===this.cur[a]&&(this.cur[a]=[]),this._calculateTween(this.cur[a],o[a],s[a],t)):this.cur[a]=(o[a]-s[a])*this._ease(t)+s[a];return this.cur},setStartTime:function(t){this._startTime=t},replay:function(){this._update(0),this._start()},duration:function(t){this._duration=e.base.isNumber(t)?t:1e3},delay:function(t){this._delay=e.base.isNumber(t)?t:0},ease:function(t){this._ease=e.base.isFunction(a[t])?a[t]:a.linear},loop:function(t){this._loop=e.base.isNumber(t)?t:1},add:function(t,e){var i;return void 0===e?(i=t,i.startCallback=s(),i.completeCallback=s(),i.progress=0):(i={fromTo:{},name:[],progress:0,startCallback:s(),completeCallback:s()},i.option=e),i.option.onStart&&i.startCallback.on(i.option.onStart),i.option.onComplete&&i.completeCallback.on(i.option.onComplete),this.tweenQueue.add(i),1===this.tweenQueue.length()&&(this.tweenQueue.next(),this.initTween(i),this.isTweenInfo=!0),i},setRender:function(t){this.render=t},setUpdateTarget:function(t){this.cur=t},getState:function(){return this._state},getCurrentTweenInfo:function(){return this.tweenInfo},nextTweenInfo:function(){return this.tweenQueue.next()},getLastTweenInfo:function(){return this.tweenQueue.get(this.tweenQueue.length()-1)},getFirstTweenInfo:function(){return this.tweenQueue.get(0)},initTween:function(t){var i=t.option;this.tweenInfo=t,this.cur=void 0!==this.cur?this.cur:void 0!==i._cur?i._cur:{},this.option=i,this._onUpdate=i.onUpdate,e.base.isObject(i)?(this.duration(i.duration),this.ease(i.ease),this.delay(i.delay),this.loop(i.loop),this._reverseDelay=i.reverseDelay||0):(this._duration=1e3,this._delay=0,this._loop=1,this._ease=a.linear,this._reverseDelay=0),this._loopCnt=this._loop},tweenQueueCache:function(t){"boolean"==typeof t&&(this._isCache=t)},_play:function(){this._state===n.PAUSE?this.resume():this._state===n.STOP&&this._start()},_start:function(){this._state=n.RUN,this._startTime=this._startTime||e.getTime(),this._playTime=this._startTime+(this._direction?this._delay:0),this._lastTime=this._playTime+this._duration+(this._direction?0:this._delay)+this._reverseDelay,this.tweenInfo.startCallback.emit(),this._isTick||(i.__on(this),this._isTick=!0)},_update:function(t){var e,i,a,n=this.tweenInfo.name,o=this.tweenInfo.fromTo;for(this.tweenInfo.progress=void 0!==t?t:this._direction===r.REVERSE?1-this.tweenInfo.progress:this.tweenInfo.progress,e=0;i=n[e];e++)o[i][0]&&(a=o[i][0].length)?(void 0===this.cur[i]&&(this.cur[i]=[]),this._calculateTween(this.cur[i],o[i][0],o[i][1])):this.cur[i]=(o[i][1]-o[i][0])*this._ease(this.tweenInfo.progress)+o[i][0];this.render&&this.render.call(this.cur,this.tweenInfo),this._onUpdate&&this._onUpdate.call(this.cur,this.tweenInfo)},_calculateTween:function(t,e,i,a){var n,r;for(void 0===a&&(a=this.tweenInfo.progress),n=0,r=i.length;r>n;n++)"number"==typeof i[n]?t[n]=(i[n]-e[n])*this._ease(a)+e[n]:"string"==typeof i[n]?t[n]=i[n]:(void 0===t[n]&&(t[n]=[]),this._calculateTween(t[n],e[n],i[n]))},_complete:function(){var t;this.setStartTime(null),this.isTweenInfo=!1,this.tweenInfo.completeCallback.emit(),--this._loopCnt>0?this.replay():!this.isTweenInfo&&(t=this.tweenQueue.next())?(this.initTween(t),this._isCache||this.tweenQueue.clear(),this._start()):this.isTweenInfo?this._start():(this._stopTween(),this.option._stackTweensFlag?(this.tweenQueue.rewind(),t=this.tweenQueue.next(),this.initTween(t)):this.tweenQueue.allClear())},_stopTween:function(){this._state=n.STOP,this._startTime=null,i.__off(this),this._isTick=!1}});e.TweenAnimator=e.Tween=c}(t,e),function(t,e,i){"use strict";var a=e.base.Class.extend({_init:function(){this.init()},init:function(){this.translateX=0,this.translateY=0,this.translateZ=0,this.rotateX=0,this.rotateY=0,this.rotateZ=0,this.skewX=0,this.skewY=0,this.scaleX=1,this.scaleY=1},copy:function(t){this.translateX=t.translateX,this.translateY=t.translateY,this.translateZ=t.translateZ,this.rotateX=t.rotateX,this.rotateY=t.rotateY,this.rotateZ=t.rotateZ,this.skewX=t.skewX,this.skewY=t.skewY,this.scaleX=t.scaleX,this.scaleY=t.scaleY},set:function(t){t instanceof Array&&(this.translateX=i.isNumber(t[0])?t[0]:0,this.translateY=i.isNumber(t[1])?t[1]:0,this.translateZ=i.isNumber(t[2])?t[2]:0,this.rotateX=i.isNumber(t[3])?t[3]:0,this.rotateY=i.isNumber(t[4])?t[4]:0,this.rotateZ=i.isNumber(t[5])?t[5]:0,this.scaleX=i.isNumber(t[6])?t[6]:1,this.scaleY=i.isNumber(t[7])?t[7]:1,this.skewX=i.isNumber(t[8])?t[8]:0,this.skewY=i.isNumber(t[9])?t[9]:0)}});e.Transform=a}(t,e,e.base),function(t,e,i){"use strict";var a={aqua:new Uint8Array([0,255,255]),lime:new Uint8Array([0,255,0]),silver:new Uint8Array([192,192,192]),black:new Uint8Array([0,0,0]),maroon:new Uint8Array([128,0,0]),teal:new Uint8Array([0,128,128]),blue:new Uint8Array([0,0,255]),navy:new Uint8Array([0,0,128]),white:new Uint8Array([255,255,255]),fuchsia:new Uint8Array([255,0,255]),olive:new Uint8Array([128,128,0]),yellow:new Uint8Array([255,255,0]),orange:new Uint8Array([255,165,0]),gray:new Uint8Array([128,128,128]),purple:new Uint8Array([128,0,128]),green:new Uint8Array([0,128,0]),red:new Uint8Array([255,0,0]),pink:new Uint8Array([255,192,203]),cyan:new Uint8Array([0,255,255]),transparent:new Uint8Array([255,255,255,0])},n=i.Class.extend({_init:function(){var t=this,e=["borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","marginTop","marginRight","marginBottom","marginLeft","paddingTop","paddingRight","paddingBottom","paddingLeft","width","height","top","left","clipTop","clipBottom","clipRight","clipLeft","fontSize","lineHeight"];e.forEach(function(e){t[e]=t._unit.bind(t)});var i=["backgroundPosition","backgroundSize"];i.forEach(function(e){t[e]=t._arrayUnit.bind(t)});var a=["border","borderTop","borderRight","borderLeft","borderBottom"];a.forEach(function(e){t[e]=function(i){var a,n={};return a=t._blank(i),n[e+"Width"]=a[0],n[e+"Style"]="none"===a[1]?"solid":a[1],n[e+"Color"]=a[2],n}});var n=["backgroundColor","color","borderColor","borderTopColor","borderRightColor","borderLeftColor","borderBottomColor"];n.forEach(function(e){t[e]=t._color});var r=["margin","padding"];r.forEach(function(e){t[e]=function(i){var a=t._blank(i),n={};return 4===a.length?(n[e+"Top"]=a[0],n[e+"Right"]=a[1],n[e+"Bottom"]=a[2],n[e+"Left"]=a[3]):3===a.length?(n[e+"Top"]=a[0],n[e+"Right"]=a[1],n[e+"Bottom"]=a[2],n[e+"Left"]=a[1]):2===a.length?(n[e+"Top"]=a[0],n[e+"Right"]=a[1],n[e+"Bottom"]=a[0],n[e+"Left"]=a[1]):1===a.length&&(n[e+"Top"]=a[0],n[e+"Right"]=a[0],n[e+"Bottom"]=a[0],n[e+"Left"]=a[0]),n}});var o=["boxShadow","textShadow"];o.forEach(function(e){t[e]=function(e){var i,a,n,r,o,s=[],c=0,l=/rgb\([0-9]+[\, |\s]+[0-9]+[\, |\s]+[0-9]+\)/g;for(s=e.match(l)||[],e=e.replace(l,"rgb"),e=e.split(","),i=0,n=e.length;n>i;i++){for(e[i].match("rgb")&&s[c]&&(e[i]=e[i].replace("rgb",s[c]),c++),e[i]=t._blank(e[i]),o=e[i].length-1,(r=t._color(e[i][0]))?(e[i].splice(0,1),e[i].push(r)):r=t._color(e[i][o]),a=0;o>a;a++)e[i][a]=t._unit(e[i][a]);e[i][a]=r}return e}})},opacity:function(t){return parseFloat(t)},clip:function(t){var e=t.replace(/\(|\)|,/g," ").trim().split(/\s+/g),i=[];i[0]=e[0];for(var a=1;4>=a;a++)i[a]=this._unit(e[a]);return i},webkitClipPath:function(t){var e,i,a=[],n=t.replace(/\(|\)|,/g," ").trim().split(/\s+/g);for(a.push(n[0]),e=1,i=n.length;i>e;e++)a.push(this._unit(n[e]));return a},backgroundImage:function(t){return t.replace(/url\(|\)$/gi,"")},_arrayUnit:function(t){var e,i,a=t.trim().split(" ");for(e=0,i=a.length;i>e;e++)a[e]=this._unit(a[e]);return a},_unit:function(t){return"string"==typeof t?{number:this._getFloat(t),unit:this._getChar(t)||"px"}:{number:t,unit:"px"}},_color:function(t){var e,i,n,r,o,s,c,l;if(void 0===t||null===t)return console.log("invalid color"),!1;if(a[t])l=a[t];else if(t instanceof Array||t instanceof Uint8Array)l=new Uint8Array(t);else if(c=t.toLowerCase(),c=c.trim(),"r"===c.charAt(0)&&"g"===c.charAt(1)&&"b"===c.charAt(2)){if("a"===c.charAt(3)){for(r=c.replace(/rgba\(/g,"").replace(/\)/g,"").replace(/(\s*)/g,"").replace(/\,/g," ").split(" "),s=0,o=r.length-1;o>s;s++)r[s]=parseInt(r[s]);r[o]=parseFloat(r[o])}else for(r=c.replace(/rgb\(/g,"").replace(/\)/g,"").replace(/(\s*)/g,"").replace(/\,/g," ").split(" "),s=0,o=r.length;o>s;s++)r[s]=parseInt(r[s]);l=new Uint8Array(r)}else{if("#"!==c.charAt(0))return!1;4===c.length&&(e=c.charAt(1),i=c.charAt(2),n=c.charAt(3),c="#"+e+e+i+i+n+n),c=parseInt(c.substr(1),16),l=new Uint8Array(3),l.setValue(c>>16,255&c>>8,255&c)}return l},_getChar:function(t){var e=t.match(/[^0-9.-]/g),i="";return null!==e&&(i=e.join("")),i.replace(/\, /g,""),i},_getNum:function(t){return parseInt(t.match(/^[-]?\d+/g),10)},_getFloat:function(t){return parseFloat(t.match(/^[+-]?\d*(\.?\d*)/g))},_blank:function(t){return t.trim().replace(/\, /g,",").split(" ")}});e.CSSPropertyParser=i.singleTon(n)}(t,e,e.base),function(t,e,i){"use strict";var a=i.Class.extend({_init:function(){this.createColor(),this.createBorderStyle(),this.createBlankFunction(),this.createUnit(),this.createShadow()},opacity:function(t){return t.opacity},WebkitTransform:function(t){var e="";return e+=t.perspective?"perspective("+t.perspective+"px) ":"",e+="translate3d("+t.translateX+"px, "+t.translateY+"px, "+t.translateZ+"px) ",e+=t.rotateX?"rotateX("+t.rotateX+"deg) ":"",e+=t.rotateY?"rotateY("+t.rotateY+"deg) ":"",e+=t.rotateZ?"rotateZ("+t.rotateZ+"deg) ":"",e+=1!==t.scaleX?"scaleX("+t.scaleX+") ":"",e+=1!==t.scaleY?"scaleY("+t.scaleY+") ":"",e+=t.skewX?"skewX("+t.skewX+"deg) ":"",e+=t.skewY?"skewY("+t.skewY+"deg) ":""},createUnit:function(){function t(t,e){return"px"===e[this]?Math.round(t[this])+e[this]:t[this]+e[this]}function e(t,e){return t[this][0]+e[this][0]+" "+t[this][1]+e[this][1]}var i=this,a=["width","height","top","left"],n=["backgroundPosition","backgroundSize"];a.forEach(function(e){i[e]=t.bind(e)}),n.forEach(function(t){i[t]=e.bind(t)})},createColor:function(){var t=this,e=["borderColor","borderTopColor","borderRightColor","borderLeftColor","borderBottomColor","backgroundColor","color"];e.forEach(function(e){t[e]=t._rgbColor(e)})},createBorderStyle:function(){function t(t,e){var i=this+"Width",a=this+"Color",n=this+"Style";return t[i]+e[i]+" "+e[n]+" rgb("+t[a][0]+", "+t[a][1]+", "+t[a][2]+")"}function e(t,e){return t[this].toFixed(2)+e[this]}var i=this,a=["border","borderTop","borderRight","borderLeft","borderBottom"],n=["borderWidth","borderTopWidth","borderRightWidth","borderLeftWidth","borderBottomWidth"],r=["borderStyle","borderTopStyle","borderRightStyle","borderLeftStyle","borderBottomStyle"];a.forEach(function(e){i[e]=t.bind(e)}),r.forEach(function(t){i[t]=i._direct(t)}),n.forEach(function(t){i[t]=e.bind(t)})},createBlankFunction:function(){function t(t,e){var i=this+"Top",a=this+"Right",n=this+"Bottom",r=this+"Left";return t[i]+e[i]+" "+t[a]+e[a]+" "+t[n]+e[n]+" "+t[r]+e[r]}function e(t,e){return t[this]+e[this]}var i=this,a=["margin","padding"],n=["marginTop","marginRight","marginBottom","marginLeft","paddingTop","paddingRight","paddingBottom","paddingLeft","lineHeight","fontSize"];a.forEach(function(e){i[e]=t.bind(e)}),n.forEach(function(t){i[t]=e.bind(t)})},createShadow:function(){var t=this,e=["boxShadow","textShadow"];e.forEach(function(e){t[e]=function(t,i){var a,n,r,o,s=t[e],c=i[e],l="";for(a=0,r=s.length;r>a;a++){for(0!==a&&(l+=", "),n=0,o=s[a].length-1;o>n;n++)l+=s[a][n]+c[a][n]+" ";l+="rgb("+s[a][n][0]+","+s[a][n][1]+","+s[a][n][2]+") "}return l}})},clip:function(t){return t.clip[0]+"("+t.clip[1][0]+t.clip[1][1]+" "+t.clip[2][0]+t.clip[2][1]+" "+t.clip[3][0]+t.clip[3][1]+" "+t.clip[4][0]+t.clip[4][1]+")"},webkitClipPath:function(t,e){var i,a,n,r=t.webkitClipPath,o=e.webkitClipPath,s=e.webkitClipPathStyle;if("circle"===s)return o[0]+"("+r[0]+o[1]+" at "+r[1]+o[2]+" "+r[2]+o[3]+")";if("polygon"===s){for(n=s+"(",i=0,a=r.length;a>i;i+=2)n+=r[i]+o[i]+" "+r[i+1]+o[i+1],n+=i+1!==a-1?", ":")";return n}},_direct:function(t){return function(e){return e[t]}},_rgbColor:function(t){return function(e){return"rgb("+e[t][0]+", "+e[t][1]+", "+e[t][2]+")"}}});e.CssStringCreator=i.singleTon(a)}(t,e,e.base),function(t,e,i){"use strict";var a=e.CSSPropertyParser.getInstance(),n=i.Class.extend({_init:function(){var t,e,i,n,r,o,s,c=this;t=["backgroundColor","color","borderColor","borderTopColor","borderRightColor","borderLeftColor","borderBottomColor"],t.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_colorType")}}),e=["width","left","marginRight","marginLeft","paddingRight","paddingLeft","marginTop","marginBottom","paddingBottom","paddingTop","clipTop","clipBottom","clipRight","clipLeft","borderWidth","borderTopWidth","borderRightWidth","borderLeftWidth","borderBottomWidth","clipTop","clipBottom","clipRight","clipLeft"],e.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_unitType","width")}}),i=["height","top"],i.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_unitType","height")}}),n=["backgroundPosition","backgroundSize"],n.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_backgroundType")}}),r=["margin","padding"],r.forEach(function(t){c[t]=function(e){var i,n,r;if(2===e.animationFromTo[t].length){i=a[t](e.animationFromTo[t][0]),n=a[t](e.animationFromTo[t][1]);for(r in n)e.animationFromTo[r]=[i[r],n[r]],c[r](e)}else{n=a[t](e.animationFromTo[t]);for(r in n)e.animationFromTo[r]=n[r],c[r](e)}}}),o=["border","borderTop","borderRight","borderLeft","borderBottom"],o.forEach(function(t){c[t]=function(e){var i,n;2===e.animationFromTo[t].length?(i=a[t](e.animationFromTo[t][0]),n=a[t](e.animationFromTo[t][1]),e.animationFromTo[t+"Width"]=[i[t+"Width"],n[t+"Width"]],e.animationFromTo[t+"Color"]=[i[t+"Color"],n[t+"Color"]]):(n=a[t](e.animationFromTo[t]),e.animationFromTo[t+"Width"]=n[t+"Width"],e.animationFromTo[t+"Color"]=n[t+"Color"]),e.unit[t+"Style"]=n[t+"Style"],c[t+"Width"](e),c[t+"Color"](e)}}),o=["border","borderTop","borderRight","borderLeft","borderBottom"],o.forEach(function(t){c[t]=function(e){var i,n;2===e.animationFromTo[t].length?(i=a[t](e.animationFromTo[t][0]),n=a[t](e.animationFromTo[t][1]),e.animationFromTo[t+"Width"]=[i[t+"Width"],n[t+"Width"]],e.animationFromTo[t+"Color"]=[i[t+"Color"],n[t+"Color"]]):(n=a[t](e.animationFromTo[t]),e.animationFromTo[t+"Width"]=n[t+"Width"],e.animationFromTo[t+"Color"]=n[t+"Color"]),e.unit[t+"Style"]=n[t+"Style"],c[t+"Width"](e),c[t+"Color"](e)}}),s=["boxShadow","textShadow"],s.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_shadowType")}}),this.webkitClipPath=function(t){this.settingCssAnimation("webkitClipPath",t,"_webkitClipPathType")},this.fontSize=function(t){this.settingCssAnimation("fontSize",t,"_fontSizeType")},this.lineHeight=function(t){this.settingCssAnimation("lineHeight",t,"_unitType","lineHeight")},this.opacity=function(t){this.settingCssAnimation("opacity",t)},this.WebkitTransform=function(t,e){var i,a;"object"==typeof e.animationFromTo[t]&&2===e.animationFromTo[t].length?(i=e.animationFromTo[t][0],a=e.animationFromTo[t][1]):(i=e.target.cur[t],a=e.animationFromTo[t]),("translateX"===t||"translateY"===t||"translateZ"===t)&&("string"==typeof i&&(i=this._getTranslateValue(t,e,i)),"string"==typeof a&&(a=this._getTranslateValue(t,e,a))),e.fromTo[t]=[i,a],e.target.from[t]=a,e.name.push(t)}},settingCssAnimation:function(e,i,n,r){var o;o=i.fromTo[e]=[],"object"==typeof i.animationFromTo[e]&&2===i.animationFromTo[e].length?(o[0]=i.animationFromTo[e][0],o[1]=i.animationFromTo[e][1]):(o[0]=t.getComputedStyle(i.target.dom)[e],(""===o[0]||"auto"===o[0]||"none"===o[0]||void 0===o[0])&&(o[0]=this._exceptGetStyle(i.target.dom,e)),o[1]=i.animationFromTo[e]),o[0]=a[e](o[0]),o[1]=a[e](o[1]),n&&this[n]&&this[n](e,i,r),i.name.push(e)},unitArray:function(t,e,i){var a,n,r,o,s,c=[],l=[],u=[],p=e.fromTo[t];for(a=0,n=p[0].length;n>a;a++)r=p[0][a],o=p[1][a],r.unit!==o.unit&&(s="object"==typeof i&&i[a]?i[a]:i,this._convertUnit(e.target.dom,r,o,s,t)),c.push(r.number),l.push(o.number),u.push(o.unit);e.fromTo[t]=[c,l],e.unit[t]=u},_colorType:function(t,e){e.target.cur[t]=new Uint8Array(3)},_fontSizeType:function(t,e){var i=e.fromTo[t];isNaN(i[0].number)&&this._getStringFontNumber(i[0],e.target.dom),isNaN(i[1].number)&&this._getStringFontNumber(i[1],e.target.dom),this._unitType(t,e,"fontSize")},_backgroundType:function(t,e){1===e.fromTo[t][0].length&&e.fromTo[t][0].push({number:50,unit:"%"}),1===e.fromTo[t][1].length&&e.fromTo[t][1].push({number:50,unit:"%"}),this.unitArray(t,e,["width","height"])},_unitType:function(t,e,i){var a=e.fromTo[t][0],n=e.fromTo[t][1];return a.unit!==n.unit&&this._convertUnit(e.target.dom,a,n,i,t),e.unit[t]=n.unit,e.target.unit[t]=n.unit,e.fromTo[t][0]=a.number,e.fromTo[t][1]=n.number,!1},_webkitClipPathType:function(t,e){var i=e.fromTo[t];e.unit[t+"Style"]=i[1][0],i[0].splice(0,1),i[1].splice(0,1),this.unitArray(t,e,"width")},_shadowType:function(t,e){var a,n,r,o,s,c,l,u=e.fromTo[t][0],p=e.fromTo[t][1],h=[];for(e.unit[t]=h,o=0,l=p.length;l>o;o++){for(!u[o]&&(u[o]=[]),a=u[o],n=p[o],r=[],h.push(r),s=0,c=n.length-1;c>s;s++)r.push(n[s].unit),a[s]&&n[s].unit!==a[s].unit&&this._convertUnit(e.target.dom,a[s],n[s],"width",t),n[s]=n[s].number,a[s]=a[s]?a[s].number:0;a[c]||(a[c]=new Uint8Array(3))}e.cur[t]=i.deepCopy(p)},_exceptGetStyle:function(e,i){var a,n,r;return"left"===i?a=e.offsetLeft+"px":"top"===i?a=e.offsetTop+"px":"clip"===i?a="rect(0px 0px 0px 0px)":"boxShadow"===i?a="0px 0px 0px 0px black":"textShadow"===i?a="0px 0px 0px black":"backgroundPosition"===i?a="0px 0px":"backgroundSize"===i&&(n=this._getStyle(e,"backgroundImage"),t.aa=r=new Image,r.src=n,a=r.width&&r.height?r.width+"px "+r.height+"px":"0px 0px"),void 0===a&&(a="0px"),a},_getCriterionEm:function(t,e){return"fontSize"===e?16:this._getStyle(t,"fontSize").number||16},_getCriterionPercent:function(e,i,n){var r,o,s,c,l=e.parentNode;if("lineHeight"===n)return this._getStyle(e,"fontSize").number||16;if("backgroundPosition"===n)return s=this._getStyle(e,i).number,c=this._getBackgroundImageSize(e,i),s-c+1;if("backgroundSize"===n)return this._getStyle(e,i).number;for(r=a._getFloat(t.getComputedStyle(l)[i]);""===r&&l!==document.body;)l=l.parentNode,r=a._getFloat(t.getComputedStyle(l)[i]);return 0!==r||"width"!==i&&"height"!==i||(o=i.substring(0,1).toUpperCase()+i.substring(1),r=t["inner"+o]),r},_getStyle:function(e,i){var n=t.getComputedStyle(e)[i];return n=a[i](n)},_getBackgroundImageSize:function(t,e){var i,a,n=this._getStyle(t,"backgroundSize");return"auto"===n[0].unit?(i=this._getStyle(t,"backgroundImage"),a=new Image,a.src=i,void 0===e?[a.width,a.height]:a[e]):n["width"===e?0:1].number},_getStringFontNumber:function(t,e){var i=t.unit;"normal"===i||"initial"===i?(t.number=this._getStyle(e,"fontSize").number||16,t.unit="px"):"xx-small"===i?(t.number=.5625,t.unit="em"):"x-small"===i?(t.number=.625,t.unit="em"):"small"===i?(t.number=.8125,t.unit="em"):"medium"===i?(t.number=1,t.unit="em"):"large"===i?(t.number=1.125,t.unit="em"):"x-large"===i?(t.number=1.5,t.unit="em"):"xx-large"===i&&(t.number=2,t.unit="em")},_getTranslateValue:function(t,e,i){var n,r;return n=a._unit(i),"px"!==n.unit?"translateX"===t||"translateZ"===t?r=this._convertPx(e.target.dom,n.number,n.unit,"width"):"translateY"===t&&(r=this._convertPx(e.target.dom,n.number,n.unit,"height")):r=n.number,r},_convertUnit:function(t,e,i,a,n){"em"===i.unit?e.number=this._convertEm(t,e.number,e.unit,a,n):"%"===i.unit?e.number=this._convertPer(t,e.number,e.unit,a,n):"px"===i.unit?e.number=this._convertPx(t,e.number,e.unit,a,n):"cm"===i.unit?e.number=this._convertCm(t,e.number,e.unit,a,n):"pt"===i.unit&&(e.number=this._convertPt(t,e.number,e.unit,a,n))},_convertEm:function(t,e,i,a,n){var r=this._getCriterionEm(t,a,n);return 0===e?0:"px"===i?e/r:"%"===i?e/100*this._getCriterionPercent(t,a,n)/r:"cm"===i||"pt"===i?this._convertPx(t,e,i,a,n)/r:!1},_convertPer:function(t,e,i,a,n){var r=this._getCriterionPercent(t,a,n);return 0===e?0:"px"===i?100*(e/r):"em"===i?100*(e*this._getCriterionEm(t,a,n)/r):"cm"===i||"pt"===i?100*(this._convertPx(t,e,i,a,n)/r):!1},_convertPx:function(t,e,i,a,n){return 0===e?0:"%"===i?e/100*this._getCriterionPercent(t,a,n):"em"===i?e*e*this._getCriterionEm(t,a,n):"cm"===i?37.795*e:"pt"===i?1.3*e:!1},_convertCm:function(t,e,i,a,n){var r;return 0===e?0:(r="px"!==i?this._convertPx(t,e,i,a,n):e,.02646*r)},_convertPt:function(t,e,i,a,n){var r;return 0===e?0:(r="px"!==i?this._convertPx(t,e,i,a,n):e,.75*r)}});e.CssAnimationUtil=e.base.singleTon(n)}(t,e,e.base),function(t,e){var i={optionAnalyzer:function(t,e){var i;return void 0!==t?"number"==typeof t?(i=e&&"object"==typeof e?e:{},i.duration=t):"object"==typeof t&&(i=t):(i={},i.duration=1e3),i},checkStagger:function(t,i,a){var n,r,o;for(this.animations=[],n=0,r=t.length;r>n;n++)o=e.base.deepCopy(i),i.stagger&&(o.delay=i.stagger*n+(i.delay||0),o.reverseDelay=i.stagger*(r-n)),0!==n&&i.drag&&(o.duration+=i.drag*n),0===n&&i.onStart&&(o.onStart=i.onStart),a(t[n],o,n)},createKeyFrame:function(t,i,a){var n,r,o,s,c,l,u=[];for(n in t)u.push(parseFloat(n));for(u.sort(function(t,e){return t-e}),s=u[0],n=0,o=u.length-1;o>n;n++){l=e.base.deepCopy(i),c={};for(r in t[u[n+1]])c[r]=void 0!==t[u[n]][r]?[t[u[n]][r],t[u[n+1]][r]]:t[u[n+1]][r];l.duration=i.duration*(u[n+1]-s),s=u[n+1],0===n?(i.onStart&&(l.onStart=i.onStart),i.delay&&(l.delay=i.delay),l.reverseDelay=0):(i.delay&&(l.delay=0),i.stagger&&(l.delay=0),n===o-1?i.onComplete&&(l.onComplete=i.onComplete):l.reverseDelay=0),a(c,l,n)}},effectAnalyzer:function(t,i){var a,n,r,o,s,c=e.CssAnimationUtil.getInstance()._getCriterionPercent(t.dom,"width"),l=e.CssAnimationUtil.getInstance()._getCriterionPercent(t.dom,"height");if(a=i,t.dom.style.opacity=t.dom.style.opacity?t.dom.style.opacity:1,"pulse"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY},.5:{scaleX:1.05*t.cur.scaleX,scaleY:1.05*t.cur.scaleY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY}};else if("rollIn"===a)n={0:{translateX:-100+t.cur.translateX,rotateZ:-120+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{translateX:0+t.cur.translateX,rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}};else if("rollOut"===a)n={0:{opacity:1*t.dom.style.opacity},1:{translateX:200+t.cur.translateX,rotateZ:120+t.cur.rotateZ,opacity:0*t.dom.style.opacity}};else if("bounce"===a)n={0:{translateY:0+t.cur.translateY},.2:{translateY:0+t.cur.translateY},.4:{translateY:-30+t.cur.translateY},.5:{translateY:0+t.cur.translateY},.7:{translateY:-15+t.cur.translateY},.8:{translateY:0+t.cur.translateY},.9:{translateY:-4+t.cur.translateY},1:{translateY:0+t.cur.translateY}},r=["bounce1","bounce1","bounce2","bounce1","bounce2","bounce1","","bounce1"],o="center bottom";else if("bounceIn"===a)n={0:{scaleX:.3*t.cur.scaleX,scaleY:.3*t.cur.scaleY},.2:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY},.4:{scaleX:.9*t.cur.scaleX,scaleY:.9*t.cur.scaleY},.6:{scaleX:1.03*t.cur.scaleX,scaleY:1.03*t.cur.scaleY},.8:{scaleX:.97*t.cur.scaleX,scaleY:.97*t.cur.scaleY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY}},r=["bounce1","bounce1","bounce1","bounce1","bounce1","bounce1"]; +else if("bounceInDown"===a)n={0:{translateY:-3e3+t.cur.translateY,opacity:0*t.dom.style.opacity},.6:{translateY:25+t.cur.translateY,opacity:1*t.dom.style.opacity},.75:{translateY:-10+t.cur.translateY,opacity:1*t.dom.style.opacity},.9:{translateY:5+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity}},r=["bounce1","bounce1","bounce1","bounce1","bounce1"];else if("bounceInLeft"===a)n={0:{translateX:-3e3+t.cur.translateX,opacity:0*t.dom.style.opacity},.6:{translateX:25+t.cur.translateX,opacity:1*t.dom.style.opacity},.75:{translateX:-10+t.cur.translateX,opacity:1*t.dom.style.opacity},.9:{translateX:5+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity}},r=["bounce1","bounce1","bounce1","bounce1","bounce1"];else if("bounceInRight"===a)n={0:{translateX:3e3+t.cur.translateX,opacity:0*t.dom.style.opacity},.6:{translateX:-25+t.cur.translateX,opacity:1*t.dom.style.opacity},.75:{translateX:10+t.cur.translateX,opacity:1*t.dom.style.opacity},.9:{translateX:-5+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity}},r=["bounce1","bounce1","bounce1","bounce1","bounce1"];else if("bounceInUp"===a)n={0:{translateY:3e3+t.cur.translateY,opacity:0*t.dom.style.opacity},.6:{translateY:-25+t.cur.translateY,opacity:1*t.dom.style.opacity},.75:{translateY:10+t.cur.translateY,opacity:1*t.dom.style.opacity},.9:{translateY:-5+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity}},r=["bounce1","bounce1","bounce1","bounce1","bounce1"];else if("bounceOut"===a)n={.2:{opacity:0*t.dom.style.opacity,scaleX:.9*t.cur.scaleX,scaleY:.9*t.cur.scaleY},.5:{opacity:1*t.dom.style.opacity,scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY},1:{opacity:0*t.dom.style.opacity,scaleX:.3*t.cur.scaleX,scaleY:.3*t.cur.scaleY}};else if("bounceOutDown"===a)n={0:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity},.1:{translateY:10+t.cur.translateY,opacity:1*t.dom.style.opacity},.45:{translateY:-20+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{translateY:2e3+t.cur.translateY,opacity:0*t.dom.style.opacity}};else if("bounceOutLeft"===a)n={0:{translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity},.2:{translateX:20+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{translateX:-2e3+t.cur.translateX,opacity:0*t.dom.style.opacity}};else if("bounceOutRight"===a)n={0:{translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity},.2:{translateX:-20+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{translateX:2e3+t.cur.translateX,opacity:0*t.dom.style.opacity}};else if("bounceOutUp"===a)n={0:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity},.2:{translateY:-10+t.cur.translateY,opacity:1*t.dom.style.opacity},.45:{translateY:20+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{translateY:-2e3+t.cur.translateY,opacity:0*t.dom.style.opacity}};else if("zoomIn"===a)n={0:{scaleX:.3*t.cur.scaleX,scaleY:.3*t.cur.scaleY,opacity:0*t.dom.style.opacity},.5:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity}};else if("zoomInDown"===a)n={0:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,opacity:0*t.dom.style.opacity,translateX:0+t.cur.translateX,translateY:-1e3+t.cur.translateY},.6:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX,translateY:60+t.cur.translateY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX,translateY:0+t.cur.translateY}},r=["zoomInDown","backOut"];else if("zoomInLeft"===a)n={0:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,opacity:0*t.dom.style.opacity,translateX:-1e3+t.cur.translateX},.6:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateX:10+t.cur.translateX},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateX}},r=["zoomInDown","backOut"];else if("zoomInRight"===a)n={0:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,opacity:0*t.dom.style.opacity,translateX:1e3+t.cur.translateX,translateY:t.cur.translateY},.6:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateX:-10+t.cur.translateX,translateY:t.cur.translateY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateY:t.cur.translateY}},r=["zoomInDown","backOut"];else if("zoomInUp"===a)n={0:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,opacity:0*t.dom.style.opacity,translateY:1e3+t.cur.translateY},.6:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateY:-60+t.cur.translateY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY}},r=["zoomInDown","backOut"];else if("zoomOut"===a)n={0:{opacity:1*t.dom.style.opacity},.6:{scaleX:.3*t.cur.scaleX,scaleY:.3*t.cur.scaleY,opacity:0*t.dom.style.opacity},1:{opacity:0*t.dom.style.opacity}};else if("zoomOutDown"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity},.4:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,translateY:-60+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,translateY:2e3+t.cur.translateY,opacity:0*t.dom.style.opacity}},r=["zoomInDown","backOut"],o="center bottom";else if("zoomOutLeft"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity},.4:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,translateX:42+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,translateX:-2e3+t.cur.translateX,opacity:0*t.dom.style.opacity}},o="left center";else if("zoomOutRight"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity},.4:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,translateX:-42+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,translateX:2e3+t.cur.translateX,opacity:0*t.dom.style.opacity}},o="right center";else if("zoomOutUp"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity},.4:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,translateY:60+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,translateY:-2e3+t.cur.translateY,opacity:0*t.dom.style.opacity}},r=["zoomInDown","backOut"],o="center bottom";else if("slideInDown"===a)n={0:{translateY:-1*l+t.cur.translateY},1:{translateY:0+t.cur.translateY}},s="visible";else if("slideInLeft"===a)n={0:{translateX:-1*c+t.cur.translateX},1:{translateX:0+t.cur.translateX}},s="visible";else if("slideInRight"===a)n={0:{translateX:1*c+t.cur.translateX},1:{translateX:0+t.cur.translateX}},s="visible";else if("slideInUp"===a)n={0:{translateY:1*l+t.cur.translateY},1:{translateY:0+t.cur.translateY}},s="visible";else if("slideOutDown"===a)n={0:{translateY:0+t.cur.translateY},1:{translateY:1*l+t.cur.translateY}},s="hidden";else if("slideOutLeft"===a)n={0:{translateX:0+t.cur.translateX},1:{translateX:-1*c+t.cur.translateX}},s="hidden";else if("slideOutRight"===a)n={0:{translateX:0+t.cur.translateX},1:{translateX:1*c+t.cur.translateX}},s="hidden";else if("slideOutUp"===a)n={0:{translateY:0+t.cur.translateY},1:{translateY:-1*l+t.cur.translateY}},s="hidden";else if("flash"===a)n={0:{opacity:1*t.dom.style.opacity},.25:{opacity:0*t.dom.style.opacity},.5:{opacity:1*t.dom.style.opacity},.75:{opacity:0*t.dom.style.opacity},1:{opacity:1*t.dom.style.opacity}};else if("rubberBand"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY},.3:{scaleX:1.25*t.cur.scaleX,scaleY:.75*t.cur.scaleY},.4:{scaleX:.75*t.cur.scaleX,scaleY:1.25*t.cur.scaleY},.5:{scaleX:1.15*t.cur.scaleX,scaleY:.85*t.cur.scaleY},.65:{scaleX:.95*t.cur.scaleX,scaleY:1.05*t.cur.scaleY},.75:{scaleX:1.05*t.cur.scaleX,scaleY:.95*t.cur.scaleY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY}};else if("shake"===a)n={0:{translateX:0+t.cur.translateX},.1:{translateX:-10+t.cur.translateX},.2:{translateX:10+t.cur.translateX},.3:{translateX:-10+t.cur.translateX},.4:{translateX:10+t.cur.translateX},.5:{translateX:-10+t.cur.translateX},.6:{translateX:10+t.cur.translateX},.7:{translateX:-10+t.cur.translateX},.8:{translateX:10+t.cur.translateX},.9:{translateX:-10+t.cur.translateX},1:{translateX:0+t.cur.translateX}};else if("swing"===a)n={0:{rotateZ:0+t.cur.rotateZ},.2:{rotateZ:15+t.cur.rotateZ},.4:{rotateZ:-10+t.cur.rotateZ},.6:{rotateZ:5+t.cur.rotateZ},.8:{rotateZ:-5+t.cur.rotateZ},1:{rotateZ:0+t.cur.rotateZ}},o="top center";else if("tada"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,rotateZ:0+t.cur.rotateZ},.15:{scaleX:.9*t.cur.scaleX,scaleY:.9*t.cur.scaleY,rotateZ:-3+t.cur.rotateZ},.3:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:3+t.cur.rotateZ},.4:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:-3+t.cur.rotateZ},.5:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:3+t.cur.rotateZ},.6:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:-3+t.cur.rotateZ},.7:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:3+t.cur.rotateZ},.8:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:-3+t.cur.rotateZ},.9:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:3+t.cur.rotateZ},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,rotateZ:0+t.cur.rotateZ}};else if("wobble"===a)n={0:{translateX:0+t.cur.translateX,rotateZ:0+t.cur.rotateZ},.15:{translateX:c*-.25+t.cur.translateX,rotateZ:-5+t.cur.rotateZ},.3:{translateX:.2*c+t.cur.translateX,rotateZ:3+t.cur.rotateZ},.45:{translateX:c*-.15+t.cur.translateX,rotateZ:-3+t.cur.rotateZ},.6:{translateX:.1*c+t.cur.translateX,rotateZ:2+t.cur.rotateZ},.75:{translateX:c*-.05+t.cur.translateX,rotateZ:-1+t.cur.rotateZ},1:{translateX:0+t.cur.translateX,rotateZ:0+t.cur.rotateZ}};else if("jello"===a)n={0:{skewX:0+t.cur.skewX,skewY:0+t.cur.skewY},.22:{skewX:-12.5+t.cur.skewX,skewY:-12.5+t.cur.skewY},.33:{skewX:6.25+t.cur.skewX,skewY:6.25+t.cur.skewY},.44:{skewX:-3.125+t.cur.skewX,skewY:-3.125+t.cur.skewY},.55:{skewX:1.5625+t.cur.skewX,skewY:1.5625+t.cur.skewY},.66:{skewX:-.78125+t.cur.skewX,skewY:-.78125+t.cur.skewY},.77:{skewX:.390625+t.cur.skewX,skewY:.390625+t.cur.skewY},.88:{skewX:-.1953125+t.cur.skewX,skewY:-.1953125+t.cur.skewY},1:{skewX:0+t.cur.skewX,skewY:0+t.cur.skewY}},o="center";else if("fadeIn"===a)n={0:{opacity:0*t.dom.style.opacity},1:{opacity:1*t.dom.style.opacity}};else if("fadeInDown"===a)n={0:{translateY:-1*l+t.cur.translateY,opacity:0*t.dom.style.opacity},1:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity}};else if("fadeInDownBig"===a)n={0:{opacity:0*t.dom.style.opacity,translateY:-2e3+t.cur.translateY},1:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY}};else if("fadeInLeft"===a)n={0:{opacity:0*t.dom.style.opacity,translateX:-1*c+t.cur.translateX},1:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX}};else if("fadeInLeftBig"===a)n={0:{opacity:0*t.dom.style.opacity,translateX:-2e3+t.cur.translateX},1:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX}};else if("fadeInRight"===a)n={0:{opacity:0*t.dom.style.opacity,translateX:1*c+t.cur.translateX},1:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX}};else if("fadeInRightBig"===a)n={0:{opacity:0*t.dom.style.opacity,translateX:2e3+t.cur.translateX},1:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX}};else if("fadeInUp"===a)n={0:{opacity:0*t.dom.style.opacity,translateY:1*l+t.cur.translateY},1:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY}};else if("fadeInUpBig"===a)n={0:{opacity:0*t.dom.style.opacity,translateY:2e3+t.cur.translateY},1:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY}};else if("fadeOut"===a)n={0:{opacity:1*t.dom.style.opacity},1:{opacity:0*t.dom.style.opacity}};else if("fadeOutDown"===a)n={0:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY},1:{opacity:0*t.dom.style.opacity,translateY:1*l+t.cur.translateY}};else if("fadeOutDownBig"===a)n={0:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY},1:{opacity:0*t.dom.style.opacity,translateY:2e3+t.cur.translateY}};else if("fadeOutLeft"===a)n={0:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX},1:{opacity:0*t.dom.style.opacity,translateX:-1*c+t.cur.translateX}};else if("fadeOutLeftBig"===a)n={0:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX},1:{opacity:0*t.dom.style.opacity,translateX:-2e3+t.cur.translateX}};else if("fadeOutRight"===a)n={0:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX},1:{opacity:0*t.dom.style.opacity,translateX:1*c+t.cur.translateX}};else if("fadeOutRightBig"===a)n={0:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX},1:{opacity:0*t.dom.style.opacity,translateX:2e3+t.cur.translateX}};else if("fadeOutUp"===a)n={0:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY},1:{opacity:0*t.dom.style.opacity,translateY:-1*l+t.cur.translateY}};else if("fadeOutUpBig"===a)n={0:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY},1:{opacity:0*t.dom.style.opacity,translateY:-2e3+t.cur.translateY}};else if("flip"===a)n={0:{rotateY:-360+t.cur.rotateY,perspective:400},.4:{rotateY:-190+t.cur.rotateY,translateZ:150+t.cur.translateZ,perspective:400},.5:{rotateY:-170+t.cur.rotateY,translateZ:150+t.cur.translateZ,perspective:400},.8:{scaleX:.95*t.cur.scaleX,scaleY:.95*t.cur.scaleY,perspective:400},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,rotateY:0+t.cur.rotateY,translateZ:0+t.cur.translateZ,perspective:400}},r=["easeIn","easeIn","easeIn","easeIn","easeIn"];else if("flipInX"===a)n={0:{rotateX:90+t.cur.rotateX,perspective:400,opacity:0*t.dom.style.opacity},.4:{rotateX:-20+t.cur.rotateX,perspective:400,opacity:1*t.dom.style.opacity},.6:{rotateX:10+t.cur.rotateX,perspective:400,opacity:1*t.dom.style.opacity},.8:{rotateX:-5+t.cur.rotateX,perspective:400,opacity:1*t.dom.style.opacity},1:{rotateX:0+t.cur.rotateX,perspective:400,opacity:1*t.dom.style.opacity}},r=["easeIn","easeIn","easeIn","easeIn","easeIn"];else if("flipInY"===a)n={0:{rotateY:90+t.cur.rotateY,perspective:400,opacity:0*t.dom.style.opacity},.4:{rotateY:-20+t.cur.rotateY,perspective:400,opacity:1*t.dom.style.opacity},.6:{rotateY:10+t.cur.rotateY,perspective:400,opacity:1*t.dom.style.opacity},.8:{rotateY:-5+t.cur.rotateY,perspective:400,opacity:1*t.dom.style.opacity},1:{rotateY:0+t.cur.rotateY,perspective:400,opacity:1*t.dom.style.opacity}},r=["easeIn","easeIn","easeIn","easeIn","easeIn"];else if("flipOutX"===a)n={0:{perspective:400},.3:{perspective:400,rotateX:-20+t.cur.rotateX,opacity:1*t.dom.style.opacity},1:{perspective:400,rotateX:90+t.cur.rotateX,opacity:0*t.dom.style.opacity}};else if("flipOutY"===a)n={0:{perspective:400},.3:{perspective:400,rotateY:-15+t.cur.rotateY,opacity:1*t.dom.style.opacity},1:{perspective:400,rotateY:90+t.cur.rotateY,opacity:0*t.dom.style.opacity}};else if("lightSpeedIn"===a)n={0:{translateX:1*c+t.cur.translateX,skewX:-30+t.cur.skewX,opacity:0*t.dom.style.opacity},.6:{translateX:0+t.cur.translateX,skewX:20+t.cur.skewX,opacity:1*t.dom.style.opacity},.8:{translateX:0+t.cur.translateX,skewX:-5+t.cur.skewX,opacity:1*t.dom.style.opacity},1:{translateX:0+t.cur.translateX,skewX:0+t.cur.skewX,opacity:1*t.dom.style.opacity}};else if("lightSpeedOut"===a)n={0:{opacity:1*t.dom.style.opacity},1:{translateX:1*c+t.cur.translateX,skewX:30+t.cur.skewX,opacity:0*t.dom.style.opacity}};else if("rotateIn"===a)n={0:{rotateZ:-200+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="center";else if("rotateInDownLeft"===a)n={0:{rotateZ:-45+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="left bottom";else if("rotateInDownRight"===a)n={0:{rotateZ:45+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="right bottom";else if("rotateInUpLeft"===a)n={0:{rotateZ:45+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="left bottom";else if("rotateInUpRight"===a)n={0:{rotateZ:-90+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="right bottom";else if("rotateOut"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:200+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="center";else if("rotateOutDownLeft"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:45+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="left bottom";else if("rotateOutDownRight"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:-45+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="right bottom";else if("rotateOutUpLeft"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:-45+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="left bottom";else if("rotateOutUpRight"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:90+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="right bottom";else{if("hinge"!==a)throw Error("the name of animation is not exists");n={0:{opacity:1*t.dom.style.opacity},.2:{rotateZ:80+t.cur.rotateZ},.4:{rotateZ:60+t.cur.rotateZ,opacity:1*t.dom.style.opacity},.6:{rotateZ:80+t.cur.rotateZ},.8:{rotateZ:60+t.cur.rotateZ,opacity:1*t.dom.style.opacity},1:{translateY:700+t.cur.translateY,opacity:0*t.dom.style.opacity}},o="top left",r=["easeInOut","easeInOut","easeInOut","easeInOut","easeInOut","easeInOut"]}return[n,r,o,s]}};e.AnimationUtil=i}(t,e,e.base),function(t,e,i){var a,n=i.Class.extend({_init:function(){return void 0!==a?a=new this:(this.targetObjects=[],this)},addTarget:function(t){this.targetObjects.push(t),t.map=new e.base.WeakMap},getObject:function(t){if(t instanceof e.AnimationObject)return t;for(var i=0,a=this.targetObjects.length;a>i;i++)if(t instanceof this.targetObjects[i].$type){var n=this.targetObjects[i].map.get(t);return void 0===n&&(n=new e[this.targetObjects[i].$namespace](t),this.targetObjects[i].map.set(t,n)),n}throw"CannotCreateObject"},"static":{getInstance:function(){return void 0===a&&(a=new n),a},plugin:function(t){function i(){e.AnimationObject.call(this),t.$constructor.apply(this,arguments)}var a=/^\$(?:namespace|constructor|type)$/;if(t.$constructor){i.prototype=new e.AnimationObject,i.prototype.constructor=i;for(var n in t)a.test(n)||(i.prototype[n]="function"==typeof t[n]&&t[n]);return e[t.$namespace]=i,this.getInstance().addTarget(t),i}}}});e.ObjectManager=n}(t,e,e.base),function(t){"use strict";(function(t,e,i){var a=e.base.Class.extend({_init:function(){this.from=new e.Transform,this.cur=i.copy(this.from),this.updateSeek=!1,this.updateSeekProperty=[]},getFrom:function(t){var e={},t=t.animation;for(var i in t)e[i]=this.from[i],this.from[i]=t[i];return e},setFrom:function(t){this.from.set(t)},translate:function(){},rotate:function(){}});e.AnimationObject=a})(t,e,e.base)}(t),function(t,e,i){"use strict";var a=e.CssAnimationUtil.getInstance(),n=e.CssStringCreator.getInstance();e.ObjectManager.plugin({$namespace:"DomObject",$type:t.HTMLElement,$constructor:function(t){this.dom=t,this.unit={},this._perspective=!1},render:function(t){var e,i,a=t.updateProperty;for(e=0;i=a[e];e++)t.targetStyle[i]=n[i](this,t.unit)},objectRender:function(t){var e=!1;for(var i in t)this.isTransform(i)||void 0===this.dom.style[i]?e||(this.dom.style.WebkitTransform=n.WebkitTransform(t),e=!0):this.dom.style[i]=n[i](t,unit)},createTweenInfo:function(t,e,i){var a={fromTo:{},animationFromTo:t,cur:this.cur,option:e,name:[],unit:{},target:this,targetStyle:this.dom.style,updateProperty:[]};return i&&this.setAnimationFromTo(a),a},setAnimationFromTo:function(t){var e,n=!1,r=t.animationFromTo;for(e in r)this.isTransform(e)?(a.WebkitTransform(e,t),n||(t.updateProperty.push("WebkitTransform"),n=!0)):"perspective"===e?(this._perspective=i.isNumber(r[e])?r[e]:i.isNumber(r[e][1])?r[e][1]:0,this.cur.perspective=this._perspective):a[e]&&(a[e](t),t.updateProperty.push(e))},isTransform:function(t){return void 0!==t&&null!==t?"translateX"===t||"translateY"===t||"translateZ"===t||"rotateX"===t||"rotateY"===t||"rotateZ"===t||"scaleX"===t||"scaleY"===t||"skewX"===t||"skewY"===t?!0:!1:void 0},perspective:function(t){void 0!==t&&null!==t&&e.base.isNumber(t)&&(this._perspective=t,this.cur.perspective=t)},set:function(t){if(void 0!==t&&null!==t){for(var e in t)this.isTransform(e)?(this.from[e]=t[e],this.cur[e]=t[e]):"perspective"===e?this.perspective(t[e]):this.dom.style[e]=t[e];this.objectRender(i.deepCopy(this.from))}}})}(t,e,e.base),function(t,e,i){"use strict";function a(t){var i,a;for(this.target=[],this.len=t.length,i=0;this.len>i;i++)this.target[i]=(a=n.getObject(t[i]).simpleAnimation)?a:new e.SimpleAnimation(t[i])}var n=e.ObjectManager.getInstance(),r={tween:function(t,i,a){var n;return this.simpleAnimation||(this.simpleAnimation=this.length?new e.SimpleAnimationGroup(this):new e.SimpleAnimation(this)),n=e.AnimationUtil.optionAnalyzer(i,a),this.simpleAnimation.add(t,n),this.simpleAnimation.play(),this},stop:function(){this.simpleAnimation||this.simpleAnimation||(this.simpleAnimation=this.length?new e.SimpleAnimationGroup(this):new e.SimpleAnimation(this)),this.simpleAnimation.stop()},transform:function(t){this.simpleAnimation||(this.simpleAnimation=this.length?new e.SimpleAnimationGroup(this):new e.SimpleAnimation(this)),this.simpleAnimation.target.set(t)}},o=function(t){this.tweenAnimator=new e.TweenAnimator,this.target=n.getObject(t),this.target.simpleAnimation=this,this.target.render&&this.tweenAnimator.setRender(this.target.render),this.target.cur&&this.tweenAnimator.setUpdateTarget(this.target.cur)};o.prototype.add=function(t,a,n){var r,o,s,c,l=n||this.tweenAnimator,u=this;return"string"==typeof t?(r=e.AnimationUtil.effectAnalyzer(this.target,t),e.AnimationUtil.createKeyFrame(r[0],a,function(t,e,i){void 0!==r[1]&&(e.ease=r[1][i]),o=u.target.createTweenInfo(t,e,!0),l.add(o),void 0!==r[2]&&(0===i?o.startCallback.on(function(){u.target.dom.style.webkitTransformOrigin=r[2]}):i===r.length&&o.completeCallback.on(function(){u.target.dom.style.webkitTransformOrigin=""})),void 0!==r[3]&&o.completeCallback.on(function(){u.target.dom.style.visibility=r[3]})}),void 0):(t.effect&&(void 0===this.parTweensGroup?(this.parTweensGroup=[],c=new e.TweenAnimator,this.parTweensGroup.push(c)):c=this.parTweensGroup[0],this.target.render&&c.setRender(this.target.render),this.target.cur&&c.setUpdateTarget(this.target.cur),this.add(t.effect,i.deepCopy(a),c)),"running"===l.getState()?(o=u.target.createTweenInfo(t,a,!1),(s=l.getLastTweenInfo())&&s.completeCallback.on(function(){u.target.setAnimationFromTo(o)})):o=this.target.createTweenInfo(t,a,!0),l.add(o),void 0)},o.prototype.play=function(){var t,e;if(this.tweenAnimator.play(),this.parTweensGroup)for(t=0,e=this.parTweensGroup.length;e>t;t++)this.parTweensGroup[t].play()},o.prototype.stop=function(){var t,e;if(this.tweenAnimator.stop(),this.parTweensGroup)for(t=0,e=this.parTweensGroup.length;e>t;t++)this.parTweensGroup[t].stop()},a.prototype.add=function(t,i){var a=0,n=this;e.AnimationUtil.checkStagger(this.target,i,function(e,r){i.onComplete&&(r.onComplete=function(){a++,a===n.len&&e.tweenAnimator.getCurrentTweenInfo().completeCallback.on(i.onComplete)}),e.add(t,r)})},a.prototype.play=function(){var t;for(t=0;this.len>t;t++)this.target[t].play()},a.prototype.stop=function(){var t;for(t=0;this.len>t;t++)this.target[t].stop()},e.SimpleAnimation=o,e.SimpleAnimationGroup=a,e.SimpleAnimationMixinObject=r}(t,e,e.base),function(t,e){"use strict";function i(t){var e,i,a=["tween","stop","transform","simpleAnimation"];for(e=0,i=a.length;i>e;e++)if(t.hasOwnProperty(a[e]))return a[e];return!1}function a(t){var e="Function or Object can apply Mixin";e+=void 0!==t?': "'+t+'" is overrided.':".",console.warn(e)}var n=e.SimpleAnimationMixinObject,r=function(t){var e;if(void 0!==t.prototype){(e=i(t.prototype))&&a(e);for(var r in n)t.prototype[r]=n[r]}else if(t instanceof Object){(e=i(t))&&a(e);for(var r in n)n.hasOwnProperty(r)&&(t[r]=n[r])}else a();return t};e.SimpleMixin=r}(t,e),function(t,e){"use strict";var i=e.ObjectManager.getInstance();e.SimpleMixin(e.DomObject),e.target=function(a){if("string"==typeof a){var n,r=a.slice(0,1),o=a.slice(1);"."===r?(n=document.getElementsByClassName(o),n.tween||e.SimpleMixin(n,function(){return n})):"#"===r&&(n=document.getElementById(o),n=i.getObject(n))}else a instanceof t.HTMLElement&&(n=i.getObject(a));return n}}(t,e)})(window); \ No newline at end of file diff --git a/d2d_app/client/lib/tau/mobile/js/jquery.js b/d2d_app/client/lib/tau/mobile/js/jquery.js new file mode 100644 index 0000000..9f7b3d3 --- /dev/null +++ b/d2d_app/client/lib/tau/mobile/js/jquery.js @@ -0,0 +1,9190 @@ +/*! + * jQuery JavaScript Library v2.1.1 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-05-01T17:11Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + 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 ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var arr = []; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + version = "2.1.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + 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 ); + }, + + 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(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + 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; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; + }, + + isPlainObject: function( obj ) { + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + // Support: Android < 4.0, iOS < 6 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf("use strict") === 1 ) { + script = document.createElement("script"); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + 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; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v1.10.19 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-04-18 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "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" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { + div.innerHTML = "
"; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowclip^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + 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; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + 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.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + 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 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + 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 ); + + // Move the given value to match[3] whether quoted or unquoted + 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 ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + 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" ); + + // other types prohibit arguments + } 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; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + 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 !== strundefined && 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 + " " ).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 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + 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.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + 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; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + 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; + }; + }), + + // Miscellaneous + "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); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "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" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "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; + 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"]; + +// Add button/input type pseudos +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 ); +} + +// Easy API for creating new setFilters +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 ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + 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 the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + 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, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + 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 ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +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, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } 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, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + 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 ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + 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, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +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 || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && 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; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.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.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + len = this.length, + ret = [], + 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; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return 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, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + 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; + }, + + sibling: function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; + } +}); + +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 = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + 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 jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return elem.contentDocument || 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 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.unique( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * The ready event handler and self cleanup method + */ +function completed() { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + jQuery.ready(); +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } 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 ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[0], key ) : emptyGet; +}; + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( owner ) { + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + +function Data() { + // Support: Android < 4, + // Old WebKit does not have Object.preventExtensions/freeze method, + // return new empty object instead with no [[set]] accessor + Object.defineProperty( this.cache = {}, 0, { + get: function() { + return {}; + } + }); + + this.expando = jQuery.expando + Math.random(); +} + +Data.uid = 1; +Data.accepts = jQuery.acceptData; + +Data.prototype = { + key: function( owner ) { + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return the key for a frozen object. + if ( !Data.accepts( owner ) ) { + return 0; + } + + var descriptor = {}, + // Check if the owner object already has a cache key + unlock = owner[ this.expando ]; + + // If not, create one + if ( !unlock ) { + unlock = Data.uid++; + + // Secure it in a non-enumerable, non-writable property + try { + descriptor[ this.expando ] = { value: unlock }; + Object.defineProperties( owner, descriptor ); + + // Support: Android < 4 + // Fallback to a less secure definition + } catch ( e ) { + descriptor[ this.expando ] = unlock; + jQuery.extend( owner, descriptor ); + } + } + + // Ensure the cache object + if ( !this.cache[ unlock ] ) { + this.cache[ unlock ] = {}; + } + + return unlock; + }, + set: function( owner, data, value ) { + var prop, + // There may be an unlock assigned to this node, + // if there is no entry for this "owner", create one inline + // and set the unlock as though an owner entry had always existed + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + // Fresh assignments by object are shallow copied + if ( jQuery.isEmptyObject( cache ) ) { + jQuery.extend( this.cache[ unlock ], data ); + // Otherwise, copy the properties one-by-one to the cache object + } else { + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + } + return cache; + }, + get: function( owner, key ) { + // Either a valid cache is found, or will be created. + // New caches will be created and the unlock returned, + // allowing direct access to the newly created + // empty data object. A valid owner object must be provided. + var cache = this.cache[ this.key( owner ) ]; + + return key === undefined ? + cache : cache[ key ]; + }, + access: function( owner, key, value ) { + var stored; + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ((key && typeof key === "string") && value === undefined) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase(key) ); + } + + // [*]When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + if ( key === undefined ) { + this.cache[ unlock ] = {}; + + } else { + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + }, + hasData: function( owner ) { + return !jQuery.isEmptyObject( + this.cache[ owner[ this.expando ] ] || {} + ); + }, + discard: function( owner ) { + if ( owner[ this.expando ] ) { + delete this.cache[ owner[ this.expando ] ]; + } + } +}; +var data_priv = new Data(); + +var data_user = new Data(); + + + +/* + Implementation Summary + + 1. Enforce API surface and semantic compatibility with 1.9.x branch + 2. Improve the module's maintainability by reducing the storage + paths to a single mechanism. + 3. Use the same single mechanism to support "private" and "user" data. + 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) + 5. Avoid exposing implementation details on user objects (eg. expando properties) + 6. Provide a clear path for implementation upgrade to WeakMap in 2014 +*/ +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + data_user.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend({ + hasData: function( elem ) { + return data_user.hasData( elem ) || data_priv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return data_user.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + data_user.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to data_priv methods, these can be deprecated. + _data: function( elem, name, data ) { + return data_priv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + data_priv.remove( elem, name ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = data_user.get( elem ); + + if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + data_priv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + data_user.set( this, key ); + }); + } + + return access( this, function( value ) { + var data, + camelKey = jQuery.camelCase( key ); + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + // Attempt to get data from the cache + // with the key as-is + data = data_user.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to get data from the cache + // with the key camelized + data = data_user.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each(function() { + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = data_user.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + data_user.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf("-") !== -1 && data !== undefined ) { + data_user.set( this, key, value ); + } + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + data_user.remove( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = data_priv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = data_priv.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 the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return data_priv.get( elem, key ) || data_priv.access( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + data_priv.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 ); + + // ensure a hooks for this queue + 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", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + 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 = data_priv.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 cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + // Support: Windows Web Apps (WWA) + // `name` and `type` need .setAttribute for WWA + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE9-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +})(); +var strundefined = typeof undefined; + + + +support.focusinBubbles = "onfocusin" in window; + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + 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 ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.hasData( elem ) && data_priv.get( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + 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("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + 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 ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + data_priv.remove( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.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(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome < 28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } +}; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && e.preventDefault ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && e.stopPropagation ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// Support: Chrome 15+ +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; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// Create "bubbling" focus and blur events +// Support: Firefox, Chrome, Safari +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + data_priv.remove( doc, fix ); + + } else { + data_priv.access( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + 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" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + 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 ); + } + } +}); + + +var + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + + // Support: IE 9 + option: [ 1, "" ], + + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] + }; + +// Support: IE 9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: 1.x compatibility +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute("type"); + } + + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + data_priv.set( + elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) + ); + } +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( data_priv.hasData( src ) ) { + pdataOld = data_priv.access( src ); + pdataCur = data_priv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( data_user.hasData( src ) ) { + udataOld = data_user.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + data_user.set( dest, udataCur ); + } +} + +function getAll( context, tag ) { + var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : + context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + +// Support: IE >= 9 +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Support: IE >= 9 + // Fix Cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + 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 ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Fixes #12346 + // Support: Webkit, IE + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; + }, + + cleanData: function( elems ) { + var data, elem, type, key, + special = jQuery.event.special, + i = 0; + + for ( ; (elem = elems[ i ]) !== undefined; i++ ) { + if ( jQuery.acceptData( elem ) ) { + key = elem[ data_priv.expando ]; + + if ( key && (data = data_priv.cache[ key ]) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + if ( data_priv.cache[ key ] ) { + // Discard any remaining `private` data + delete data_priv.cache[ key ]; + } + } + } + // Discard any remaining `user` data + delete data_user.cache[ elem[ data_user.expando ] ]; + } + } +}); + +jQuery.fn.extend({ + 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 this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( 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 this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + 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; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return this; + } +}); + +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 ); + + // Support: QtWebKit + // .get() because push.apply(_, arraylike) throws + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "