From 754e7fbddc4624d53836afabf995f65f9eb91483 Mon Sep 17 00:00:00 2001 From: gbrodman Date: Tue, 28 Oct 2025 16:34:34 -0400 Subject: [PATCH] Remove old console soy/js and related files (#2861) We haven't been serving this for a while, let's finally get rid of them. We keep some Soy rules around in the presubmits file because we use some Soy files as XML templates for EPP actions. --- config/presubmits.py | 65 +- core/build.gradle | 1 - core/src/main/javascript/checks.js | 94 - .../google/registry/ui/compile_test.js | 24 - .../google/registry/ui/css/admin-settings.css | 84 - .../google/registry/ui/css/console.css | 81 - .../registry/ui/css/contact-settings.css | 58 - .../google/registry/ui/css/contact-us.css | 16 - .../google/registry/ui/css/dashboard.css | 63 - .../google/registry/ui/css/demo_css.css | 1 - .../javascript/google/registry/ui/css/epp.css | 61 - .../google/registry/ui/css/forms.css | 187 - .../google/registry/ui/css/kd_components.css | 4493 ----------------- .../registry/ui/css/registrar_imports_raw.css | 11 - .../google/registry/ui/css/registry-lock.css | 85 - .../google/registry/ui/css/registry.css | 326 -- .../google/registry/ui/css/resources.css | 28 - .../registry/ui/css/security-settings.css | 67 - .../google/registry/ui/externs/json.js | 187 - .../google/registry/ui/js/component.js | 79 - .../google/registry/ui/js/console.js | 144 - .../google/registry/ui/js/edit_item.js | 315 -- .../javascript/google/registry/ui/js/forms.js | 137 - .../google/registry/ui/js/menu_button.js | 137 - .../ui/js/registrar/admin_settings.js | 144 - .../registry/ui/js/registrar/console.js | 175 - .../ui/js/registrar/contact_settings.js | 277 - .../registry/ui/js/registrar/contact_us.js | 46 - .../registry/ui/js/registrar/dashboard.js | 89 - .../google/registry/ui/js/registrar/main.js | 61 - .../registry/ui/js/registrar/registry_lock.js | 228 - .../registry/ui/js/registrar/resources.js | 47 - .../ui/js/registrar/security_settings.js | 106 - .../ui/js/registrar/whois_settings.js | 46 - .../google/registry/ui/js/resource.js | 86 - .../registry/ui/js/resource_component.js | 191 - .../google/registry/ui/js/session.js | 107 - .../javascript/google/registry/ui/js/util.js | 215 - core/src/main/javascript/soyutils_usegoog.js | 2869 ----------- .../ui/soy/registrar/AdminSettings.soy | 144 - .../registry/ui/soy/registrar/Analytics.soy | 34 - .../registry/ui/soy/registrar/Console.soy | 367 -- .../ui/soy/registrar/ConsoleUtils.soy | 166 - .../ui/soy/registrar/ContactSettings.soy | 379 -- .../registry/ui/soy/registrar/Forms.soy | 348 -- .../ui/soy/registrar/OteSetupConsole.soy | 197 - .../soy/registrar/RegistrarCreateConsole.soy | 369 -- .../ui/soy/registrar/RegistryLock.soy | 169 - .../registrar/RegistryLockVerification.soy | 71 - .../ui/soy/registrar/SecuritySettings.soy | 184 - .../ui/soy/registrar/WhoisSettings.soy | 232 - package-lock.json | 21 - package.json | 22 - 53 files changed, 3 insertions(+), 14131 deletions(-) delete mode 100644 core/src/main/javascript/checks.js delete mode 100644 core/src/main/javascript/google/registry/ui/compile_test.js delete mode 100644 core/src/main/javascript/google/registry/ui/css/admin-settings.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/console.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/contact-settings.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/contact-us.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/dashboard.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/demo_css.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/epp.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/forms.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/kd_components.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/registrar_imports_raw.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/registry-lock.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/registry.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/resources.css delete mode 100644 core/src/main/javascript/google/registry/ui/css/security-settings.css delete mode 100644 core/src/main/javascript/google/registry/ui/externs/json.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/component.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/console.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/edit_item.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/forms.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/menu_button.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/admin_settings.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/console.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/contact_settings.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/contact_us.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/dashboard.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/main.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/registry_lock.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/resources.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/security_settings.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/registrar/whois_settings.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/resource.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/resource_component.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/session.js delete mode 100644 core/src/main/javascript/google/registry/ui/js/util.js delete mode 100644 core/src/main/javascript/soyutils_usegoog.js delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/AdminSettings.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/Analytics.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/Console.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/ConsoleUtils.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/ContactSettings.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/Forms.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/OteSetupConsole.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/RegistrarCreateConsole.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/RegistryLock.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/RegistryLockVerification.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/SecuritySettings.soy delete mode 100644 core/src/main/resources/google/registry/ui/soy/registrar/WhoisSettings.soy delete mode 100644 package-lock.json delete mode 100644 package.json diff --git a/config/presubmits.py b/config/presubmits.py index 7d91d830d..9e25464cc 100644 --- a/config/presubmits.py +++ b/config/presubmits.py @@ -105,9 +105,8 @@ PRESUBMITS = { # System.(out|err).println should only appear in tools/ or load-testing/ PresubmitCheck( r".*\bSystem\.(out|err)\.print", "java", { - "StackdriverDashboardBuilder.java", "/tools/", "/example/", - "/load-testing/", "RegistryTestServerMain.java", - "TestServerExtension.java", "FlowDocumentationTool.java" + "/tools/", "/example/", "/load-testing/", + "RegistryTestServerMain.java", "TestServerExtension.java" }): "System.(out|err).println is only allowed in tools/ packages. Please " "use a logger instead.", @@ -120,7 +119,7 @@ PRESUBMITS = { ): "In SOY please use the ({@param name: string} /** User name. */) style" " parameter passing instead of the ( * @param name User name.) style " - "parameter pasing.", + "parameter passing.", PresubmitCheck( r'.*\{[^}]+\w+:\s+"', "soy", @@ -139,41 +138,6 @@ PRESUBMITS = { {}, ): "All soy templates must use strict autoescaping", - - # various JS linting checks - PresubmitCheck( - r".*goog\.base\(", - "js", - {"/node_modules/"}, - ): - "Use of goog.base is not allowed.", - PresubmitCheck( - r".*goog\.dom\.classes", - "js", - {"/node_modules/"}, - ): - "Instead of goog.dom.classes, use goog.dom.classlist which is smaller " - "and faster.", - PresubmitCheck( - r".*goog\.getMsg", - "js", - {"/node_modules/"}, - ): - "Put messages in Soy, instead of using goog.getMsg().", - PresubmitCheck( - r".*(innerHTML|outerHTML)\s*(=|[+]=)([^=]|$)", - "js", - {"/node_modules/", "registrar_bin."}, - ): - "Do not assign directly to the dom. Use goog.dom.setTextContent to set" - " to plain text, goog.dom.removeChildren to clear, or " - "soy.renderElement to render anything else", - PresubmitCheck( - r".*console\.(log|info|warn|error)", - "js", - {"/node_modules/", "google/registry/ui/js/util.js", "registrar_bin."}, - ): - "JavaScript files should not include console logging.", PresubmitCheck( r".*\nimport (static )?.*\.shaded\..*", "java", @@ -303,26 +267,6 @@ def verify_flyway_index(): return not success -def verify_javascript_deps(): - """Verifies that we haven't introduced any new javascript dependencies.""" - with open('package.json') as f: - package = json.load(f) - - deps = list(package['dependencies'].keys()) - if deps != EXPECTED_JS_PACKAGES: - print('Unexpected javascript dependencies. Was expecting ' - '%s, got %s.' % (EXPECTED_JS_PACKAGES, deps)) - print(textwrap.dedent(""" - * If the new dependencies are intentional, please verify that the - * license is one of the allowed licenses (see - * config/dependency-license/allowed_licenses.json) and add an entry - * for the package (with the license in a comment) to the - * EXPECTED_JS_PACKAGES variable in config/presubmits.py. - """)) - return True - return False - - def get_files(): for root, dirnames, filenames in os.walk("."): for filename in filenames: @@ -347,8 +291,5 @@ if __name__ == "__main__": # when we put it here it fails fast before all of the tests are run. failed |= verify_flyway_index() - # Make sure we haven't introduced any javascript dependencies. - failed |= verify_javascript_deps() - if failed: sys.exit(1) diff --git a/core/build.gradle b/core/build.gradle index 9f0230a19..c40058ec8 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -30,7 +30,6 @@ def screenshotsForGoldensDir = "${project.buildDir}/screenshots_for_goldens" def newGoldensDir = "${project.buildDir}/new_golden_images" def goldensDir = "${javaTestDir}/google/registry/webdriver/goldens/chrome-linux" -def jsDir = "${project.projectDir}/src/main/javascript" // Tests that fail when running Gradle in a docker container, e. g. when // building the release artifacts in Google Cloud Build. diff --git a/core/src/main/javascript/checks.js b/core/src/main/javascript/checks.js deleted file mode 100644 index dadd95c2d..000000000 --- a/core/src/main/javascript/checks.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @fileoverview Provides Soy runtime checks for safe types. - * - * NOTE (gbrodman) this file is taken from the open source version located at - * https://github.com/google/closure-templates/blob/6c8cf1c7916abd0ab5d7e9d259985873f8af4fd2/javascript/checks.js - */ - -goog.provide('soy.checks'); - -goog.require('goog.asserts'); -goog.require('goog.soy.data.SanitizedContentKind'); -goog.require('goog.soy.data.SanitizedCss'); -goog.require('goog.soy.data.SanitizedHtml'); -goog.require('goog.soy.data.SanitizedHtmlAttribute'); -goog.require('goog.soy.data.SanitizedJs'); -goog.require('goog.soy.data.SanitizedTrustedResourceUri'); -goog.require('goog.soy.data.SanitizedUri'); - -/** - * Checks whether a given value is of a given content kind. - * - * @param {?} value The value to be examined. - * @param {!goog.soy.data.SanitizedContentKind} contentKind The desired content - * kind. - * @param {!Object} constructor - * @return {boolean} Whether the given value is of the given kind. - * @private - */ -soy.checks.isContentKind_ = function(value, contentKind, constructor) { - var ret = value != null && value.contentKind === contentKind; - if (ret) { - goog.asserts.assert(value.constructor === constructor); - } - return ret; -}; - -/** - * @param {?} value - * @return {boolean} - */ -soy.checks.isHtml = function(value) { - return soy.checks.isContentKind_( - value, goog.soy.data.SanitizedContentKind.HTML, - goog.soy.data.SanitizedHtml); -}; - -/** - * @param {?} value - * @return {boolean} - */ -soy.checks.isCss = function(value) { - return soy.checks.isContentKind_( - value, goog.soy.data.SanitizedContentKind.CSS, - goog.soy.data.SanitizedCss); -}; - -/** - * @param {?} value - * @return {boolean} - */ -soy.checks.isAttribute = function(value) { - return soy.checks.isContentKind_( - value, goog.soy.data.SanitizedContentKind.ATTRIBUTES, - goog.soy.data.SanitizedHtmlAttribute); -}; - -/** - * @param {?} value - * @return {boolean} - */ -soy.checks.isJS = function(value) { - return soy.checks.isContentKind_( - value, goog.soy.data.SanitizedContentKind.JS, goog.soy.data.SanitizedJs); -}; - -/** - * @param {?} value - * @return {boolean} - */ -soy.checks.isTrustedResourceURI = function(value) { - return soy.checks.isContentKind_( - value, goog.soy.data.SanitizedContentKind.TRUSTED_RESOURCE_URI, - goog.soy.data.SanitizedTrustedResourceUri); -}; - -/** - * @param {?} value - * @return {boolean} - */ -soy.checks.isURI = function(value) { - return soy.checks.isContentKind_( - value, goog.soy.data.SanitizedContentKind.URI, - goog.soy.data.SanitizedUri); -}; diff --git a/core/src/main/javascript/google/registry/ui/compile_test.js b/core/src/main/javascript/google/registry/ui/compile_test.js deleted file mode 100644 index ee392a5aa..000000000 --- a/core/src/main/javascript/google/registry/ui/compile_test.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -/** - * @fileoverview Test existing solely to run the :check BUILD rule. - */ - -goog.setTestOnly(); - -goog.require('goog.testing.jsunit'); - - -function testNothing() {} diff --git a/core/src/main/javascript/google/registry/ui/css/admin-settings.css b/core/src/main/javascript/google/registry/ui/css/admin-settings.css deleted file mode 100644 index 2b6f04207..000000000 --- a/core/src/main/javascript/google/registry/ui/css/admin-settings.css +++ /dev/null @@ -1,84 +0,0 @@ -/** Admin Settings */ - -div#tlds div.tld { - width: 209px; -} - -#newTld { - width: 187px; - margin-left: 0.5em; -} - -div#tlds div.tld input, -div#tlds div.tld button[type=button] { - height: 27px; - line-height: 27px; - background: #ebebeb; - vertical-align: top; - border: none; - border-bottom: solid 3px white; -} - -div#tlds div.tld input { - width: 169px; - margin: 0; - padding: 0; - color: #555; - padding-left: 5px ! important; -} - -div#tlds.editing div.tld input[readonly] { - margin-left: 0.5em; -} - -div#tlds.editing div.tld button[type=button] { - display: inline-block; - float: right; - margin-left: -2px; - width: 30px; - min-width: 30px; - height: 30px; - color: grey; - font-size: 1.1em; -} - -div#tlds.editing div.tld button[type=button]:hover { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -div#tlds.editing div.tld button[type=button] i { - font-style: normal; -} - -div#tlds.editing .kd-errormessage { - margin-left: 0.5em; -} - -#ote-results-table { - margin-left: 0.5em; - margin-top: -5px; - border-top: 0; - padding-top: 0; -} - -.ote-fulfilled { - background-color: #9df797; -} - -.ote-semifulfilled { - background-color: #fcd18e; -} - -.ote-unfulfilled { - background-color: #ffa9a9; -} - -.ote-results-header { - height: 20px; -} - -.ote-results-header-cell { - vertical-align: bottom; -} diff --git a/core/src/main/javascript/google/registry/ui/css/console.css b/core/src/main/javascript/google/registry/ui/css/console.css deleted file mode 100644 index ce3947f01..000000000 --- a/core/src/main/javascript/google/registry/ui/css/console.css +++ /dev/null @@ -1,81 +0,0 @@ -.description { - display: block; - clear: both; - font-size: 12px; - color: #999; - line-height: 140%; -} - -a:hover, a:focus { - text-decoration: underline -} - -.whoAreYou { - width: 50%; - margin: 5em auto; -} - -/* Console disabled page. */ -.whoAreYou-disabled { - width: 50%; - margin: 5em auto; -} - -.whoAreYou-disabled p img { - display: block; - margin: 3em auto; -} - -.whoAreYou-disabled h1 { - border-top: solid 1px #ebebeb; - margin-top: 1em; -} - -/* XXX: Should be re-enabled when search works. */ -#kd-search { - display: none; -} - -/* XXX: Should be generalized for use throughout console. */ -div.domain-registrar-contact div.tooltip { - visibility: hidden; - /* XXX: Should have auto-width. */ - width: 110px; - left: -55px; - height: 1em; - white-space: nowrap; - position: relative; - color: white; - background: #2d2d2d; - padding: 0.5em; - z-index: 2000; - margin-top: -30px; - font-style: normal; -} - -div.domain-registrar-contact div.tooltip .pointer { - outline: none; - display: block; - position: relative; - bottom: -7px; - left: 55px; - margin: 0 0 0 -5px; - width: 0; - height: 0; - line-height: 0px; - font-size: 0px; - /* This sets the tooptip pointer color */ - border-bottom: transparent; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-top: 5px solid #2d2d2d; -} - -.reg-cryingAndroid { - float: right; -} - -.reg-bullets { - padding-left: 1em; - list-style: disc inside; -} diff --git a/core/src/main/javascript/google/registry/ui/css/contact-settings.css b/core/src/main/javascript/google/registry/ui/css/contact-settings.css deleted file mode 100644 index 82ff6f17f..000000000 --- a/core/src/main/javascript/google/registry/ui/css/contact-settings.css +++ /dev/null @@ -1,58 +0,0 @@ -.domain-registrar-contacts { - vertical-align: top; - text-align: top; -} - -.domain-registrar-contact { - display: table-cell; - padding-right: 4em; - padding-bottom: 2em; -} - -.domain-registrar-contact div { - margin: 0.5em 0; -} - -.domain-registrar-contact + br { - display: table-row; -} - -.domain-registrar-contact-name { - font-weight: bold; - display: inline; - padding-right: 30px; -} - -.domain-registrar-contact-name i { - float: right; - width: 16px; - height: 16px; -} - -.domain-registrar-contact-name i.domain-registrar-contact-visible-in-whois { - background: url('/assets/images/visibleOn_16.png') no-repeat right; -} - -/** Postal style for address. */ -td.setting-group-compact div.contact-address-city, -td.setting-group-compact div.contact-address-state, -td.setting-group-compact div.contact-address-zip, -td.setting-group-compact div.contact-address-cc { - width: initial; - display: inline; -} - -/** Back to regular box flow for phone. */ -td.setting-group-compact input#phoneNumber { - clear: both; -} - -/** - * Vertical align shim for contact tds. Using border here instead of - * padding since this is a table and padding is ignored. - * - * @see td.setting p - */ -td.domain-registrar-contacts { - border-top: solid 0.5em white; -} diff --git a/core/src/main/javascript/google/registry/ui/css/contact-us.css b/core/src/main/javascript/google/registry/ui/css/contact-us.css deleted file mode 100644 index 7b17cd600..000000000 --- a/core/src/main/javascript/google/registry/ui/css/contact-us.css +++ /dev/null @@ -1,16 +0,0 @@ -#domain-registrar-contact-us .description * { - color: #999 !important; - line-height: 140%; -} - -#domain-registrar-contact-us p { - margin-bottom: 1.5em; - line-height: 140%; -} - -#registry-phone { - width: 100%; - margin: 0; - padding: 1em; - background-color: #eaeaea; -} diff --git a/core/src/main/javascript/google/registry/ui/css/dashboard.css b/core/src/main/javascript/google/registry/ui/css/dashboard.css deleted file mode 100644 index 76096b816..000000000 --- a/core/src/main/javascript/google/registry/ui/css/dashboard.css +++ /dev/null @@ -1,63 +0,0 @@ -#domain-registrar-dashboard { - text-align: center; -} - -#domain-registrar-dashboard p { - color: grey; -} - -#domain-registrar-dashboard super { - color: red; - font-size: 0.5em; - vertical-align: super; - font-weight: bold; - padding-left: 0.5em; -} - -#domain-registrar-dashboard table { - border-collapse: collapse; - margin: 3em auto; -} - -#domain-registrar-dashboard div.dashbox { - width: 230px; - min-width: 230px; - height: 260px; - padding: 1em 2em; - margin: 0 1.5em; - color: #777; - border-radius: 10px; - background-color: #f9f9f9; - text-align: center; - line-height: 140%; - font-size: 1.1em; -} - -#domain-registrar-dashboard div.dashbox h2 { - font-weight: bold; - color: #555; - margin: 2em auto 1em auto; -} - -#domain-registrar-dashboard div.dashbox a { - color: inherit; -} - -#domain-registrar-dashboard table img { - display: block; - margin: 1em auto; - padding: 1em auto; -} - -#domain-registrar-dashboard table + p { - margin: 2em auto; - width: 75%; - vertical-align: middle; - text-align: center; -} - -#domain-registrar-dashboard p img { - margin-right: 1em; - vertical-align: middle; - text-align: center; -} diff --git a/core/src/main/javascript/google/registry/ui/css/demo_css.css b/core/src/main/javascript/google/registry/ui/css/demo_css.css deleted file mode 100644 index 84760a071..000000000 --- a/core/src/main/javascript/google/registry/ui/css/demo_css.css +++ /dev/null @@ -1 +0,0 @@ -.goog-inline-block{position:relative;display:-moz-inline-box;display:inline-block}* html .goog-inline-block{display:inline}*:first-child+html .goog-inline-block{display:inline}.jfk-accordion .goog-zippy-header{-webkit-transition:background-color 0,opacity 0;-moz-transition:background-color 0,opacity 0;-o-transition:background-color 0,opacity 0;transition:background-color 0,opacity 0;color:#222;padding:7px 0 7px 15px;position:relative}.jfk-accordion .goog-zippy-expanded{color:#d14836;font-weight:bold}.jfk-accordion .goog-zippy-expanded:before{content:url(//ssl.gstatic.com/ui/v1/zippy/arrow_down_red.png)}.jfk-accordion .goog-zippy-collapsed{border-bottom:1px solid #ebebeb}.jfk-accordion .goog-zippy-content{border-bottom:1px solid #ebebeb;padding:15px 30px}.jfk-accordion .goog-zippy-expanded.goog-zippy-highlight,.jfk-accordion .goog-zippy-header:active,.jfk-accordion .goog-zippy-header:hover,.jfk-accordion .goog-zippy-header:focus{background-color:white;opacity:.8;outline:0}.jfk-accordion .goog-zippy-highlight.goog-zippy-collapsed{background-color:#ebebeb}.jfk-accordion .goog-zippy-header.goog-zippy-highlight{opacity:1}.jfk-activityIndicator{display:inline-block;position:relative;direction:ltr}.jfk-activityIndicator,.jfk-activityIndicator-icon,.jfk-activityIndicator-circle,.jfk-activityIndicator-circle-transition{height:19px;width:19px}.jfk-activityIndicator-small.jfk-activityIndicator,.jfk-activityIndicator-small .jfk-activityIndicator-icon,.jfk-activityIndicator-small .jfk-activityIndicator-circle,.jfk-activityIndicator-small .jfk-activityIndicator-circle-transition{height:16px;width:16px}.jfk-activityIndicator-icon{background:url(//ssl.gstatic.com/ui/v1/activityindicator/offline.png) center no-repeat}.jfk-activityIndicator-small .jfk-activityIndicator-icon{background:url(//ssl.gstatic.com/ui/v1/activityindicator/offline_16.png) center no-repeat}.jfk-activityIndicator-icon{-webkit-transition:opacity .218s linear .44s;-moz-transition:opacity .218s linear .44s;-o-transition:opacity .218s linear .44s;transition:opacity .218s linear .44s;top:0;left:0;position:absolute;opacity:0}.jfk-activityIndicator-circle{-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%;top:0;left:0;position:absolute}.jfk-activityIndicator-mask{overflow:hidden;position:absolute}.jfk-activityIndicator-circle-transition{position:relative}.jfk-activityIndicator-transition{-webkit-transition:all .22s ease-in;-moz-transition:all .22s ease-in;-o-transition:all .22s ease-in;transition:all .22s ease-in}.jfk-activityIndicator-transition-second{-webkit-transition:all .22s ease-out .22s;-moz-transition:all .22s ease-out .22s;-o-transition:all .22s ease-out .22s;transition:all .22s ease-out .22s}.jfk-bubble{-webkit-box-shadow:0 1px 3px rgba(0,0,0,.2);-moz-box-shadow:0 1px 3px rgba(0,0,0,.2);box-shadow:0 1px 3px rgba(0,0,0,.2);background-color:#fff;border:1px solid;border-color:#bbb #bbb #a8a8a8;padding:16px;position:absolute;z-index:1201!important}.jfk-bubble-closebtn{background:url("//ssl.gstatic.com/ui/v1/icons/common/x_8px.png") no-repeat;border:1px solid transparent;height:21px;opacity:.4;outline:0;position:absolute;right:2px;top:2px;width:21px}.jfk-bubble-closebtn:focus{border:1px solid #4d90fe;opacity:.8}.jfk-bubble-arrow{position:absolute}.jfk-bubble-arrow .jfk-bubble-arrowimplbefore,.jfk-bubble-arrow .jfk-bubble-arrowimplafter{display:block;height:0;position:absolute;width:0}.jfk-bubble-arrow .jfk-bubble-arrowimplbefore{border:9px solid}.jfk-bubble-arrow .jfk-bubble-arrowimplafter{border:8px solid}.jfk-bubble-arrowdown{bottom:0}.jfk-bubble-arrowup{top:-9px}.jfk-bubble-arrowleft{left:-9px}.jfk-bubble-arrowright{right:0}.jfk-bubble-arrowdown .jfk-bubble-arrowimplbefore,.jfk-bubble-arrowup .jfk-bubble-arrowimplbefore{border-color:#bbb transparent;left:-9px}.jfk-bubble-arrowdown .jfk-bubble-arrowimplbefore{border-color:#a8a8a8 transparent}.jfk-bubble-arrowdown .jfk-bubble-arrowimplafter,.jfk-bubble-arrowup .jfk-bubble-arrowimplafter{border-color:#fff transparent;left:-8px}.jfk-bubble-arrowdown .jfk-bubble-arrowimplbefore{border-bottom-width:0}.jfk-bubble-arrowdown .jfk-bubble-arrowimplafter{border-bottom-width:0}.jfk-bubble-arrowup .jfk-bubble-arrowimplbefore{border-top-width:0}.jfk-bubble-arrowup .jfk-bubble-arrowimplafter{border-top-width:0;top:1px}.jfk-bubble-arrowleft .jfk-bubble-arrowimplbefore,.jfk-bubble-arrowright .jfk-bubble-arrowimplbefore{border-color:transparent #bbb;top:-9px}.jfk-bubble-arrowleft .jfk-bubble-arrowimplafter,.jfk-bubble-arrowright .jfk-bubble-arrowimplafter{border-color:transparent #fff;top:-8px}.jfk-bubble-arrowleft .jfk-bubble-arrowimplbefore{border-left-width:0}.jfk-bubble-arrowleft .jfk-bubble-arrowimplafter{border-left-width:0;left:1px}.jfk-bubble-arrowright .jfk-bubble-arrowimplbefore{border-right-width:0}.jfk-bubble-arrowright .jfk-bubble-arrowimplafter{border-right-width:0}.jfk-bubble.jfk-bubble-promo{background-color:#f9edbe;border:1px solid #f0c36d}.jfk-bubble-promo .jfk-bubble-arrowdown .jfk-bubble-arrowimplbefore,.jfk-bubble-promo .jfk-bubble-arrowup .jfk-bubble-arrowimplbefore{border-color:#f0c36d transparent}.jfk-bubble-promo .jfk-bubble-arrowdown .jfk-bubble-arrowimplafter,.jfk-bubble-promo .jfk-bubble-arrowup .jfk-bubble-arrowimplafter{border-color:#f9edbe transparent}.jfk-bubble-promo .jfk-bubble-arrowleft .jfk-bubble-arrowimplbefore,.jfk-bubble-promo .jfk-bubble-arrowright .jfk-bubble-arrowimplbefore{border-color:transparent #f0c36d}.jfk-bubble-promo .jfk-bubble-arrowleft .jfk-bubble-arrowimplafter,.jfk-bubble-promo .jfk-bubble-arrowright .jfk-bubble-arrowimplafter{border-color:transparent #f9edbe}.jfk-butterBar{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;-webkit-box-shadow:0px 2px 4px rgba(0,0,0,0.2);-moz-box-shadow:0px 2px 4px rgba(0,0,0,0.2);box-shadow:0px 2px 4px rgba(0,0,0,0.2);-webkit-transition:all 0 linear 1s,opacity 1s;-moz-transition:all 0 linear 1s,opacity 1s;-o-transition:all 0 linear 1s,opacity 1s;transition:all 0 linear 1s,opacity 1s;border-style:solid;border-width:0;font-size:11px;height:0;opacity:0;visibility:hidden;overflow:hidden;padding:0;text-align:center}.jfk-butterBar-info{background-color:#f9edbe;border-color:#f0c36d;color:#333}.jfk-butterBar-error{background-color:#484848;border-color:#202020;color:#fff}.jfk-butterBar-promo{background-color:#d6e9f8;border-color:#4d90f0;color:#333}.jfk-butterBar-warning{background-color:#dd4b39;border-color:#602019;color:#fff}.jfk-butterBar-shown{-webkit-transition:opacity 0.218s;-moz-transition:opacity 0.218s;-o-transition:opacity 0.218s;transition:opacity 0.218s;border-width:1px;height:14px;opacity:1;visibility:visible;padding:6px 16px}.jfk-butterBar-mini.jfk-butterBar-shown{padding:2px 16px}.jfk-button-action{background-color:#4d90fe;background-image:-webkit-linear-gradient(top,#4d90fe,#4787ed);background-image:-moz-linear-gradient(top,#4d90fe,#4787ed);background-image:-ms-linear-gradient(top,#4d90fe,#4787ed);background-image:-o-linear-gradient(top,#4d90fe,#4787ed);background-image:linear-gradient(top,#4d90fe,#4787ed);border:1px solid #3079ed;color:#fff}.jfk-button-action.jfk-button-hover{background-color:#357ae8;background-image:-webkit-linear-gradient(top,#4d90fe,#357ae8);background-image:-moz-linear-gradient(top,#4d90fe,#357ae8);background-image:-ms-linear-gradient(top,#4d90fe,#357ae8);background-image:-o-linear-gradient(top,#4d90fe,#357ae8);background-image:linear-gradient(top,#4d90fe,#357ae8);border:1px solid #2f5bb7}.jfk-button-action:focus{-webkit-box-shadow:inset 0 0 0 1px #fff;-moz-box-shadow:inset 0 0 0 1px #fff;box-shadow:inset 0 0 0 1px #fff;border:1px solid #fff;border:1px solid rgba(0,0,0,0);outline:1px solid #4d90fe;outline:0 rgba(0,0,0,0)}.jfk-button-action.jfk-button-clear-outline{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.jfk-button-action:active{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);box-shadow:inset 0 1px 2px rgba(0,0,0,0.3)}.jfk-button-action.jfk-button-disabled{background:#4d90fe;filter:alpha(opacity=50);opacity:0.5}.jfk-button{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;cursor:default;font-size:11px;font-weight:bold;text-align:center;white-space:nowrap;margin-right:16px;height:27px;line-height:27px;min-width:54px;outline:0px;padding:0 8px}.jfk-button-hover{-webkit-box-shadow:0 1px 1px rgba(0,0,0,.1);-moz-box-shadow:0 1px 1px rgba(0,0,0,.1);box-shadow:0 1px 1px rgba(0,0,0,.1)}.jfk-button-selected{-webkit-box-shadow:inset 0px 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0px 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0px 1px 2px rgba(0,0,0,0.1)}.jfk-button .jfk-button-img{margin-top:-3px;vertical-align:middle}.jfk-button-label{margin-left:5px}.jfk-button-narrow{min-width:34px;padding:0}.jfk-button-collapse-left,.jfk-button-collapse-right{z-index:1}.jfk-button-collapse-left.jfk-button-disabled{z-index:0}.jfk-button-checked.jfk-button-collapse-left,.jfk-button-checked.jfk-button-collapse-right{z-index:2}.jfk-button-collapse-left:focus,.jfk-button-collapse-right:focus,.jfk-button-hover.jfk-button-collapse-left,.jfk-button-hover.jfk-button-collapse-right{z-index:3}.jfk-button-collapse-left{margin-left:-1px;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;border-bottom-left-radius:0;border-top-left-radius:0}.jfk-button-collapse-right{margin-right:0px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-top-right-radius:0;border-bottom-right-radius:0}.jfk-button.jfk-button-disabled:active{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.jfk-collapsiblebuttonbar{outline:none;position:relative;cursor:pointer;overflow:hidden;display:inline-block}.jfk-collapsiblebuttonbar .jfk-collapsiblebuttonbar-tab{-webkit-border-radius:2px 0 0 2px;-moz-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px;border:1px solid #ebebeb;background:url(//ssl.gstatic.com/ui/v1/button/collapsible_button_bar_tab.png) center no-repeat #f7f7f7;display:block;position:absolute;margin:0;top:0;width:16px}.jfk-collapsiblebuttonbar-tab.jfk-collapsiblebuttonbar-transition{-webkit-transition:left 0.218s linear 0.4s;-moz-transition:left 0.218s linear 0.4s;-o-transition:left 0.218s linear 0.4s;transition:left 0.218s linear 0.4s}.jfk-button.jfk-collapsiblebuttonbar-transition{-webkit-transition:left 0.13s ease 0.4s;-moz-transition:left 0.13s ease 0.4s;-o-transition:left 0.13s ease 0.4s;transition:left 0.13s ease 0.4s}.jfk-collapsiblebuttonbar .jfk-button{margin:0;position:absolute;right:0}.jfk-collapsiblebuttonbar:hover .jfk-collapsiblebuttonbar-tab{right:0}.jfk-collapsiblebuttonbar .jfk-button-standard.jfk-button-selected,.jfk-collapsiblebuttonbar .jfk-button-standard.jfk-button-clear-outline.jfk-button-selected{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1);background-color:#eee;background-image:-webkit-linear-gradient(top,#eee,#e0e0e0);background-image:-moz-linear-gradient(top,#eee,#e0e0e0);background-image:-ms-linear-gradient(top,#eee,#e0e0e0);background-image:-o-linear-gradient(top,#eee,#e0e0e0);background-image:linear-gradient(top,#eee,#e0e0e0);border:1px solid #ccc;color:#333}.jfk-button-default{background-color:#3d9400;background-image:-webkit-linear-gradient(top,#3d9400,#398a00);background-image:-moz-linear-gradient(top,#3d9400,#398a00);background-image:-ms-linear-gradient(top,#3d9400,#398a00);background-image:-o-linear-gradient(top,#3d9400,#398a00);background-image:linear-gradient(top,#3d9400,#398a00);border:1px solid #29691d;color:#fff;text-shadow:0px 1px rgba(0,0,0,0.1)}.jfk-button-default.jfk-button-hover{background-color:#368200;background-image:-webkit-linear-gradient(top,#3d9400,#368200);background-image:-moz-linear-gradient(top,#3d9400,#368200);background-image:-ms-linear-gradient(top,#3d9400,#368200);background-image:-o-linear-gradient(top,#3d9400,#368200);background-image:linear-gradient(top,#3d9400,#368200);border:1px solid #2d6200;text-shadow:0px 1px rgba(0,0,0,0.3)}.jfk-button-default:focus{-webkit-box-shadow:inset 0 0 0 1px #fff;-moz-box-shadow:inset 0 0 0 1px #fff;box-shadow:inset 0 0 0 1px #fff;border:1px solid #fff;border:1px solid rgba(0,0,0,0);outline:1px solid #3d9400;outline:0 rgba(0,0,0,0)}.jfk-button-default.jfk-button-clear-outline{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.jfk-button-default:active{-webkit-box-shadow:inset 0px 1px 2px rgba(0,0,0,0.3);-moz-box-shadow:inset 0px 1px 2px rgba(0,0,0,0.3);box-shadow:inset 0px 1px 2px rgba(0,0,0,0.3)}.jfk-button-default.jfk-button-disabled{background:#3d9400;filter:alpha(opacity=50);opacity:0.5}.jfk-button-flat{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;border:1px solid transparent;font-size:13px;font-weight:normal;height:21px;line-height:21px;margin-right:1px;min-width:0;padding:0}.jfk-button-flat.jfk-button-hover,.jfk-button-flat.jfk-button-selected,.jfk-button-flat:focus,.jfk-button-flat:active{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.jfk-button-flat .jfk-button-img{height:21px;opacity:.55;width:21px}.jfk-button-flat .jfk-button-label{display:inline-block;margin:0;padding:0 1px}.jfk-button-flat.jfk-button-selected .jfk-button-img,.jfk-button-flat.jfk-button-hover .jfk-button-img{opacity:0.9}.jfk-button-flat.jfk-button-disabled .jfk-button-img{filter:alpha(opacity=33);opacity:0.333}.jfk-button-flat:focus{border:1px solid #4d90fe}.jfk-button-flat.jfk-button-clear-outline{border:1px solid transparent}.jfk-button-mini{background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-moz-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-ms-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-o-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:linear-gradient(top,#f5f5f5,#f1f1f1);border:1px solid #dcdcdc;border:1px solid rgba(0,0,0,0.1);color:#444;height:17px;line-height:17px;min-width:22px;text-shadow:0px 1px rgba(0,0,0,0.1)}.jfk-button-mini.jfk-button-hover,.jfk-button-mini.jfk-button-clear-outline.jfk-button-hover{background-color:#f8f8f8;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1);border:1px solid #c6c6c6;text-shadow:0px 1px rgba(0,0,0,0.3)}.jfk-button-mini:active{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.jfk-button-mini.jfk-button-checked,.jfk-button-mini.jfk-button-clear-outline.jfk-button-checked{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1);background-color:#e0e0e0;background-image:-webkit-linear-gradient(top,#eee,#e0e0e0);background-image:-moz-linear-gradient(top,#eee,#e0e0e0);background-image:-ms-linear-gradient(top,#eee,#e0e0e0);background-image:-o-linear-gradient(top,#eee,#e0e0e0);background-image:linear-gradient(top,#eee,#e0e0e0);border:1px solid #ccc;color:#333}.jfk-button-mini:focus{border:1px solid #4d90fe}.jfk-button-mini.jfk-button-clear-outline{border:1px solid #dcdcdc}.jfk-button-mini.jfk-button-disabled{background:#fff;border:1px solid #f3f3f3;border:1px solid rgba(0,0,0,0.05);color:#b8b8b8}.jfk-button-primary{background-color:#d14836;background-image:-webkit-linear-gradient(top,#dd4b39,#d14836);background-image:-moz-linear-gradient(top,#dd4b39,#d14836);background-image:-ms-linear-gradient(top,#dd4b39,#d14836);background-image:-o-linear-gradient(top,#dd4b39,#d14836);background-image:linear-gradient(top,#dd4b39,#d14836);border:1px solid transparent;color:#fff;text-shadow:0px 1px rgba(0,0,0,0.1);text-transform:uppercase}.jfk-button-primary.jfk-button-hover{-webkit-box-shadow:0px 1px 1px rgba(0,0,0,0.2);-moz-box-shadow:0px 1px 1px rgba(0,0,0,0.2);box-shadow:0px 1px 1px rgba(0,0,0,0.2);background-color:#c53727;background-image:-webkit-linear-gradient(top,#dd4b39,#c53727);background-image:-moz-linear-gradient(top,#dd4b39,#c53727);background-image:-ms-linear-gradient(top,#dd4b39,#c53727);background-image:-o-linear-gradient(top,#dd4b39,#c53727);background-image:linear-gradient(top,#dd4b39,#c53727);border:1px solid #b0281a;border-bottom-color:#af301f}.jfk-button-primary:focus{-webkit-box-shadow:inset 0 0 0 1px #fff;-moz-box-shadow:inset 0 0 0 1px #fff;box-shadow:inset 0 0 0 1px #fff;border:1px solid #fff;border:1px solid rgba(0,0,0,0);outline:1px solid #d14836;outline:0 rgba(0,0,0,0)}.jfk-button-primary.jfk-button-clear-outline{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.jfk-button-primary:active{-webkit-box-shadow:inset 0px 1px 2px rgba(0,0,0,0.3);-moz-box-shadow:inset 0px 1px 2px rgba(0,0,0,0.3);box-shadow:inset 0px 1px 2px rgba(0,0,0,0.3);background-color:#b0281a;background-image:-webkit-linear-gradient(top,#dd4b39,#b0281a);background-image:-moz-linear-gradient(top,#dd4b39,#b0281a);background-image:-ms-linear-gradient(top,#dd4b39,#b0281a);background-image:-o-linear-gradient(top,#dd4b39,#b0281a);background-image:linear-gradient(top,#dd4b39,#b0281a);border:1px solid #992a1b}.jfk-button-primary.jfk-button-disabled{background:#d14836;filter:alpha(opacity=50);opacity:0.5}.jfk-slideToggle{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;-webkit-box-shadow:inset 0px 1px 2px 0 rgba(0,0,0,.1);-moz-box-shadow:inset 0px 1px 2px 0 rgba(0,0,0,.1);box-shadow:inset 0px 1px 2px 0 rgba(0,0,0,.1);background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#eee,#e0e0e0);background-image:-moz-linear-gradient(top,#eee,#e0e0e0);background-image:-ms-linear-gradient(top,#eee,#e0e0e0);background-image:-o-linear-gradient(top,#eee,#e0e0e0);background-image:linear-gradient(top,#eee,#e0e0e0);border:1px solid #ccc;color:#666;font-weight:bold;height:27px;line-height:27px;margin-right:16px;outline:none;overflow:hidden;padding:0;position:relative;width:94px}.jfk-slideToggle-on,.jfk-slideToggle-off,.jfk-slideToggle-thumb{display:inline-block;text-align:center;text-transform:uppercase;width:47px}.jfk-slideToggle-on{-webkit-box-shadow:inset 0 1px 2px 0 rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 2px 0 rgba(0,0,0,.1);background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#3b93ff,#3689ee);background-image:-moz-linear-gradient(top,#3b93ff,#3689ee);background-image:-ms-linear-gradient(top,#3b93ff,#3689ee);background-image:-o-linear-gradient(top,#3b93ff,#3689ee);background-image:linear-gradient(top,#3b93ff,#3689ee);color:#fff;height:27px}.jfk-slideToggle-off{-webkit-border-radius:2px 2px 0 0;-moz-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0}.jfk-slideToggle-thumb{-webkit-box-shadow:0px 1px 2px 0 rgba(0,0,0,.1);-moz-box-shadow:0px 1px 2px 0 rgba(0,0,0,.1);box-shadow:0px 1px 2px 0 rgba(0,0,0,.1);background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1);-webkit-transition:all .130s ease-out;-moz-transition:all .130s ease-out;-o-transition:all .130s ease-out;transition:all .130s ease-out;border:1px solid #ccc;display:block;height:27px;left:-1px;position:absolute;top:-1px}.jfk-slideToggle-thumb::after{content:'';background-image:-webkit-linear-gradient(left,#ccc 50%,transparent 50%),-webkit-linear-gradient(left,#ccc 50%,transparent 50%),-webkit-linear-gradient(left,#ccc 50%,transparent 50%),-webkit-linear-gradient(left,#ccc 50%,transparent 50%),-webkit-linear-gradient(left,#ccc 50%,transparent 50%);background-image:-moz-linear-gradient(left,#ccc 50%,transparent 50%),-moz-linear-gradient(left,#ccc 50%,transparent 50%),-moz-linear-gradient(left,#ccc 50%,transparent 50%),-moz-linear-gradient(left,#ccc 50%,transparent 50%),-moz-linear-gradient(left,#ccc 50%,transparent 50%);background-image:-ms-linear-gradient(left,#ccc 50%,transparent 50%),-ms-linear-gradient(left,#ccc 50%,transparent 50%),-ms-linear-gradient(left,#ccc 50%,transparent 50%),-ms-linear-gradient(left,#ccc 50%,transparent 50%),-ms-linear-gradient(left,#ccc 50%,transparent 50%);background-image:-o-linear-gradient(left,#ccc 50%,transparent 50%),-o-linear-gradient(left,#ccc 50%,transparent 50%),-o-linear-gradient(left,#ccc 50%,transparent 50%),-o-linear-gradient(left,#ccc 50%,transparent 50%),-o-linear-gradient(left,#ccc 50%,transparent 50%);background-image:linear-gradient(left,#ccc 50%,transparent 50%),linear-gradient(left,#ccc 50%,transparent 50%),linear-gradient(left,#ccc 50%,transparent 50%),linear-gradient(left,#ccc 50%,transparent 50%),linear-gradient(left,#ccc 50%,transparent 50%);background-position:0 0,0 2px,0 4px,0 6px,0 8px;background-repeat:repeat-x;background-size:2px 1px;display:block;height:9px;left:15px;position:absolute;top:9px;width:17px}.jfk-slideToggle.jfk-slideToggle-checked .jfk-slideToggle-thumb{left:47px}.jfk-slideToggle:focus{border:1px solid #4d90fe}.jfk-slideToggle.jfk-slideToggle-clearOutline{border:1px solid #ccc}.jfk-button-standard{background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-moz-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-ms-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-o-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:linear-gradient(top,#f5f5f5,#f1f1f1);color:#444;border:1px solid #dcdcdc;border:1px solid rgba(0,0,0,0.1)}.jfk-button-standard.jfk-button-hover,.jfk-button-standard.jfk-button-clear-outline.jfk-button-hover{background-color:#f8f8f8;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1);border:1px solid #c6c6c6;color:#333}.jfk-button-standard:active{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.jfk-button-standard.jfk-button-selected,.jfk-button-standard.jfk-button-clear-outline.jfk-button-selected{background-color:#eee;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1);border:1px solid #ccc;color:#333}.jfk-button-standard.jfk-button-checked,.jfk-button-standard.jfk-button-clear-outline.jfk-button-checked{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1);background-color:#eee;background-image:-webkit-linear-gradient(top,#eee,#e0e0e0);background-image:-moz-linear-gradient(top,#eee,#e0e0e0);background-image:-ms-linear-gradient(top,#eee,#e0e0e0);background-image:-o-linear-gradient(top,#eee,#e0e0e0);background-image:linear-gradient(top,#eee,#e0e0e0);border:1px solid #ccc;color:#333}.jfk-button-standard:focus{border:1px solid #4d90fe}.jfk-button-standard.jfk-button-clear-outline{border:1px solid #dcdcdc}.jfk-button-standard.jfk-button-disabled{background:#fff;border:1px solid #f3f3f3;border:1px solid rgba(0,0,0,0.05);color:#b8b8b8}.jfk-button-standard .jfk-button-img{opacity:.55}.jfk-button-standard.jfk-button-checked .jfk-button-img,.jfk-button-standard.jfk-button-selected .jfk-button-img,.jfk-button-standard.jfk-button-hover .jfk-button-img{opacity:0.9}.jfk-button-standard.jfk-button-disabled .jfk-button-img{filter:alpha(opacity=33);opacity:0.333}.jfk-checkbox{-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;background-color:rgba(255,255,255,.05);border:1px solid #c6c6c6;border:1px solid rgba(155,155,155,.57);font-size:1px;height:11px;margin:0px 4px 0px 1px;outline:0;vertical-align:text-bottom;width:11px}.jfk-checkbox-undetermined{background-color:#fff;background-color:rgba(255,255,255,.65)}.jfk-checkbox-checked{background-color:#fff;background-color:rgba(255,255,255,.65)}.jfk-checkbox-hover{-webkit-box-shadow:inset 0px 1px 1px rgba(0,0,0,.1);-moz-box-shadow:inset 0px 1px 1px rgba(0,0,0,.1);box-shadow:inset 0px 1px 1px rgba(0,0,0,.1);border:1px solid #b2b2b2}.jfk-checkbox-active{background-color:#ebebeb}.jfk-checkbox-focused{border:1px solid #4d90fe}.jfk-checkbox-clearOutline.jfk-checkbox-focused{border:1px solid #c6c6c6;border:1px solid rgba(155,155,155,.57)}.jfk-checkbox-disabled,.jfk-checkbox-clearOutline.jfk-checkbox-disabled{background-color:#fff;border:1px solid #f1f1f1;cursor:default}.jfk-checkbox-checkmark{height:15px;outline:0;width:15px;left:0;position:relative;top:-3px}.jfk-checkbox-undetermined .jfk-checkbox-checkmark{background:url(//ssl.gstatic.com/ui/v1/menu/checkmark-partial.png) no-repeat -5px -3px;background-image:-webkit-image-set(url(//ssl.gstatic.com/ui/v1/menu/checkmark-partial.png) 1x,url(//ssl.gstatic.com/ui/v1/menu/checkmark-partial_2x.png) 2x)}.jfk-checkbox-checked .jfk-checkbox-checkmark{background:url(//ssl.gstatic.com/ui/v1/menu/checkmark.png) no-repeat -5px -3px;background-image:-webkit-image-set(url(//ssl.gstatic.com/ui/v1/menu/checkmark.png) 1x,url(//ssl.gstatic.com/ui/v1/menu/checkmark_2x.png) 2x)}.jfk-colormenu.goog-menu{padding:0}.jfk-palette{cursor:default;outline:none}.jfk-palette-table{empty-cells:show;margin:16px}.jfk-palette-cell{border:1px solid transparent;cursor:pointer;margin:0;position:relative}.jfk-palette-cell-hover{border:1px solid #000}.jfk-palette-cell-selected{outline:1px solid #000}.jfk-palette-colorswatch{height:16px;width:16px}.jfk-palette-cell-selected>.jfk-palette-colorswatch{background:url(//ssl.gstatic.com/ui/v1/colorpicker/checkmark.png) no-repeat 50% 50%}.jfk-colorwell{border:1px solid #d9d9d9}.jfk-countrypicker-title{color:#222;font-size:16px}.jfk-countrypicker-description{color:#777;margin-top:6px}.jfk-countrypicker-content{border-top:1px solid #ebebeb;clear:both;margin-top:10px;max-height:170px;overflow:auto;padding-top:6px}.jfk-countrypicker-column{float:left;padding-right:20px;width:180px}.jfk-countrypicker-countryBlock{margin-top:6px}.jfk-countrypicker-link,.jfk-countrypicker-country{color:#15c;cursor:default;text-decoration:none}.jfk-countrypicker-link:hover,.jfk-countrypicker-country:hover{text-decoration:underline}.jfk-countrypicker-countryCurrent,.jfk-countrypicker-countryCurrent:hover{color:#666;cursor:default;font-weight:bold;outline:none;text-decoration:none}.jfk-countrypicker-auto{border-bottom:1px solid #ebebeb;margin:6px 0 16px;padding-bottom:10px}.jfk-countrypicker-flag{background:url(//ssl.gstatic.com/ui/v1/countrypicker/flags.png) no-repeat 0 1000px;display:inline-block;height:11px;margin-right:6px;width:16px}.jfk-datepicker{color:#999}.jfk-datepicker-controls{font-size:18px}.jfk-datepicker-header-table{width:100%}.jfk-datepicker-controls-cell{text-align:right}.jfk-monthview-date{cursor:pointer;text-align:left}td.jfk-monthview-date-selected{color:#dd4b39}td.jfk-monthview-date-current{color:#000}.jfk-dialog-bg{background-color:#fff;left:0;position:absolute;top:0;z-index:1100}.jfk-dialog{background-color:#fff;-webkit-box-shadow:0 4px 16px rgba(0,0,0,.2);-moz-box-shadow:0 4px 16px rgba(0,0,0,.2);box-shadow:0 4px 16px rgba(0,0,0,.2);border:solid 1px #acacac;border-bottom-color:#999;color:#000;outline:0;padding:30px 42px;position:absolute;top:0;width:512px;z-index:1101}.jfk-dialog-ie{border:solid 3px #acacac}.jfk-dialog-title{background-color:#fff;color:#000;cursor:default;font-size:16px;line-height:24px;margin-bottom:20px}.jfk-dialog-title-close{background:url(//ssl.gstatic.com/s2/profiles/images/Close.gif);cursor:pointer;height:15px;position:absolute;right:15px;top:10px;width:15px}.jfk-dialog-content{background-color:#fff;line-height:1.4em}.jfk-dialog-content .CSS_APP_ULINK,.jfk-dialog-content a{color:#36c!important}.jfk-dialog-buttons{padding-top:20px}.jfk-dialog-buttons button{border:solid 1px #d9d9d9;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;color:#666;font-weight:bold;margin:0 16px 0 0;padding:6px 12px;-webkit-transition:all 0.218s ease;-moz-transition:all 0.218s ease;-o-transition:all 0.218s ease;transition:all 0.218s ease}.jfk-dialog-buttons button:hover{border:solid 1px #c0c0c0;box-shadow:0 1px 1px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 1px rgba(0,0,0,0.1);-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);color:#333}.jfk-dialog-buttons button:active{border:solid 1px #bbb;box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);color:#333}.jfk-dialog-buttons button[disabled]{background-color:#f6f6f6;border:solid 1px #ddd;color:#bbb}.jfk-dialog-buttons .goog-buttonset-default{border:solid 1px #29691d;color:#fff}.jfk-dialog-buttons .goog-buttonset-default:hover{border:solid 1px #2d6200;box-shadow:0 1px 1px rgba(0,0,0,0.2);-moz-box-shadow:0 1px 1px rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.2);color:#fff;text-shadow:0 1px rgba(0,0,0,0.3)}.jfk-dialog-buttons .goog-buttonset-default:active{border:solid 1px #29691d;box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);color:#fff}.jfk-dialog-buttons .goog-buttonset-default[disabled]{border:solid 1px #c8c8c8;color:#fff;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none;text-shadow:none}.jfk-dialog-promptmsg{margin-bottom:18px}.jfk-dialog-promptlabel{width:100%}.jfk-errorbox-clearfloats{clear:both}.jfk-errorbox{background-color:#d32f40;background-image:-webkit-linear-gradient(top,#d32f40,#bf1730);background-image:-moz-linear-gradient(top,#d32f40,#bf1730);background-image:-ms-linear-gradient(top,#d32f40,#bf1730);background-image:-o-linear-gradient(top,#d32f40,#bf1730);background-image:linear-gradient(top,#d32f40,#bf1730);border:solid 1px #b1212d;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;color:#fff;margin-top:20px;padding:4px 6px;text-align:center}.modal-dialog{color:#000;padding:30px 42px}.modal-dialog-title{background-color:#fff;color:#000;cursor:default;font-size:16px;font-weight:normal;line-height:24px;margin:0 0 16px}.modal-dialog-title-close{height:11px;opacity:0.7;padding:17px;position:absolute;right:0px;top:0px;width:11px}.modal-dialog-title-close:after{content:'';background:url(//ssl.gstatic.com/ui/v1/dialog/close-x.png);position:absolute;height:11px;width:11px;right:17px}.modal-dialog-title-close:hover{opacity:1}.modal-dialog-content{background-color:#fff;line-height:1.4em}.modal-dialog-buttons{margin-top:16px}.modal-dialog-buttons button{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-moz-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-ms-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-o-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:linear-gradient(top,#f5f5f5,#f1f1f1);border:1px solid #dcdcdc;border:1px solid rgba(0,0,0,0.1);color:#444;cursor:default;font-size:11px;font-weight:bold;height:29px;line-height:27px;margin:0 16px 0 0;min-width:72px;outline:0;padding:0 8px}.modal-dialog-buttons button:hover,.modal-dialog-buttons button:active{-webkit-box-shadow:0px 1px 1px rgba(0,0,0,0.1);-moz-box-shadow:0px 1px 1px rgba(0,0,0,0.1);box-shadow:0px 1px 1px rgba(0,0,0,0.1);background-color:#f8f8f8;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1);border:1px solid #c6c6c6;color:#333}.modal-dialog-buttons button:active{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.modal-dialog-buttons button:focus{border:1px solid #4d90fe}.modal-dialog-buttons button[disabled]{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:#fff;background-image:none;border:1px solid #f3f3f3;border:1px solid rgba(0,0,0,0.05);color:#b8b8b8}.modal-dialog-buttons .goog-buttonset-action{background-color:#4d90fe;background-image:-webkit-linear-gradient(top,#4d90fe,#4787ed);background-image:-moz-linear-gradient(top,#4d90fe,#4787ed);background-image:-ms-linear-gradient(top,#4d90fe,#4787ed);background-image:-o-linear-gradient(top,#4d90fe,#4787ed);background-image:linear-gradient(top,#4d90fe,#4787ed);border:1px solid #3079ed;color:#fff}.modal-dialog-buttons .goog-buttonset-action:hover,.modal-dialog-buttons .goog-buttonset-action:active{background-color:#357ae8;background-image:-webkit-linear-gradient(top,#4d90fe,#357ae8);background-image:-moz-linear-gradient(top,#4d90fe,#357ae8);background-image:-ms-linear-gradient(top,#4d90fe,#357ae8);background-image:-o-linear-gradient(top,#4d90fe,#357ae8);background-image:linear-gradient(top,#4d90fe,#357ae8);border:1px solid #2f5bb7;color:#fff}.modal-dialog-buttons .goog-buttonset-action:active{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);box-shadow:inset 0 1px 2px rgba(0,0,0,0.3)}.modal-dialog-buttons .goog-buttonset-action:focus{-webkit-box-shadow:inset 0 0 0 1px #fff;-moz-box-shadow:inset 0 0 0 1px #fff;box-shadow:inset 0 0 0 1px #fff;border:1px solid #fff;border:1px solid rgba(0,0,0,0);outline:1px solid #4d90fe;outline:0 rgba(0,0,0,0)}.modal-dialog-buttons .goog-buttonset-action[disabled]{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:#4d90fe;color:#fff;filter:alpha(opacity=50);opacity:0.5}.jfk-alert,.jfk-confirm,.jfk-prompt{width:512px}hr{border:1px solid #ebebeb}.goog-link-button{position:relative;color:#15c;text-decoration:underline;cursor:pointer}.goog-link-button-disabled{color:#ccc;text-decoration:none;cursor:default}.goog-menu{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:0 2px 4px rgba(0,0,0,0.2);-moz-box-shadow:0 2px 4px rgba(0,0,0,0.2);box-shadow:0 2px 4px rgba(0,0,0,0.2);-webkit-transition:opacity 0.218s;-moz-transition:opacity 0.218s;-o-transition:opacity 0.218s;transition:opacity 0.218s;background:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);cursor:default;font-size:13px;margin:0;outline:none;padding:6px 0;position:absolute}.goog-flat-menu-button{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-moz-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-ms-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-o-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:linear-gradient(top,#f5f5f5,#f1f1f1);border:1px solid #dcdcdc;color:#444;cursor:default;font-size:11px;font-weight:bold;line-height:27px;list-style:none;margin:0 2px;min-width:46px;outline:none;padding:0 18px 0 6px;text-align:center;text-decoration:none;vertical-align:middle}.goog-flat-menu-button-disabled{background-color:#fff;border-color:#f3f3f3;color:#b8b8b8}.goog-flat-menu-button.goog-flat-menu-button-hover{background-color:#f8f8f8;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1);-webkit-box-shadow:0 1px 1px rgba(0,0,0,.1);-moz-box-shadow:0 1px 1px rgba(0,0,0,.1);box-shadow:0 1px 1px rgba(0,0,0,.1);border-color:#c6c6c6;color:#333}.goog-flat-menu-button.goog-flat-menu-button-focused{border-color:#4d90fe}.goog-flat-menu-button.goog-flat-menu-button-open,.goog-flat-menu-button.goog-flat-menu-button-active{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1);background-color:#eee;background-image:-webkit-linear-gradient(top,#eee,#e0e0e0);background-image:-moz-linear-gradient(top,#eee,#e0e0e0);background-image:-ms-linear-gradient(top,#eee,#e0e0e0);background-image:-o-linear-gradient(top,#eee,#e0e0e0);background-image:linear-gradient(top,#eee,#e0e0e0);border:1px solid #ccc;color:#333;z-index:2}.goog-flat-menu-button-caption{vertical-align:top;white-space:nowrap}.goog-flat-menu-button-dropdown{border-color:#777 transparent;border-style:solid;border-width:4px 4px 0 4px;height:0;width:0;position:absolute;right:5px;top:12px}.goog-flat-menu-button .goog-flat-menu-button-img{margin-top:-3px;opacity:.55;vertical-align:middle}.goog-flat-menu-button-active .goog-flat-menu-button-img,.goog-flat-menu-button-open .goog-flat-menu-button-img,.goog-flat-menu-button-selected .goog-flat-menu-button-img,.goog-flat-menu-button-hover .goog-flat-menu-button-img{opacity:0.9}.goog-flat-menu-button-active .goog-flat-menu-button-dropdown,.goog-flat-menu-button-open .goog-flat-menu-button-dropdown,.goog-flat-menu-button-selected .goog-flat-menu-button-dropdown,.goog-flat-menu-button-hover .goog-flat-menu-button-dropdown{border-color:#595959 transparent}.goog-flat-menu-button-left,.goog-flat-menu-button-right{z-index:1}.goog-flat-menu-button-left.goog-flat-menu-button-disabled{z-index:0}.goog-flat-menu-button-right:focus,.goog-flat-menu-button-hover.goog-flat-menu-button-collapse-right{z-index:2}.goog-flat-menu-button-left:focus,.goog-flat-menu-button-hover.goog-flat-menu-button-collapse-left{z-index:2}.goog-flat-menu-button-collapse-left{margin-left:-1px;-moz-border-radius-bottomleft:0;-moz-border-radius-topleft:0;-webkit-border-bottom-left-radius:0;-webkit-border-top-left-radius:0;border-bottom-left-radius:0;border-top-left-radius:0;min-width:0;padding-left:0;vertical-align:top}.goog-flat-menu-button-collapse-right{margin-right:0px;-moz-border-radius-topright:0;-moz-border-radius-bottomright:0;-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-top-right-radius:0;border-bottom-right-radius:0}.goog-menuitem,.goog-tristatemenuitem,.goog-filterobsmenuitem{position:relative;color:#333;cursor:pointer;list-style:none;margin:0;padding:6px 8em 6px 30px;white-space:nowrap}.goog-menu-nocheckbox .goog-menuitem,.goog-menu-noicon .goog-menuitem{padding-left:16px;vertical-align:middle}.goog-menu-noaccel .goog-menuitem{padding-right:44px}.goog-menuitem-disabled{cursor:default}.goog-menuitem-disabled .goog-menuitem-accel,.goog-menuitem-disabled .goog-menuitem-content{color:#ccc!important}.goog-menuitem-disabled .goog-menuitem-icon{filter:alpha(opacity=30);opacity:0.3}.goog-menuitem-highlight,.goog-menuitem-hover{background-color:#eee;border-color:#eee;border-style:dotted;border-width:1px 0;padding-top:5px;padding-bottom:5px}.goog-menuitem-highlight .goog-menuitem-content,.goog-menuitem-hover .goog-menuitem-content{color:#333}.goog-menuitem-checkbox,.goog-menuitem-icon{background-repeat:no-repeat;height:21px;left:3px;position:absolute;right:auto;top:3px;vertical-align:middle;width:21px}.goog-option-selected{background-image:url(//ssl.gstatic.com/ui/v1/menu/checkmark.png);background-repeat:no-repeat;background-position:left center}.goog-option-selected .goog-menuitem-content,.goog-option-selected .goog-menuitem-content{color:#333}.goog-menuitem-accel{color:#777;direction:ltr;left:auto;padding:0 6px;position:absolute;right:0;text-align:right}.goog-menuitem-mnemonic-hint{text-decoration:underline}.goog-menuitem-mnemonic-separator{color:#777;font-size:12px;padding-left:4px}.goog-menuseparator{border-top:1px solid #ebebeb;margin-top:6px;margin-bottom:6px}.goog-modalpopup,.modal-dialog{-webkit-box-shadow:0 4px 16px rgba(0,0,0,.2);-moz-box-shadow:0 4px 16px rgba(0,0,0,.2);box-shadow:0 4px 16px rgba(0,0,0,.2);background:#fff;background-clip:padding-box;border:1px solid #acacac;border:1px solid rgba(0,0,0,.333);outline:0;position:absolute}.goog-modalpopup-bg,.modal-dialog-bg{background:#fff;left:0;position:absolute;top:0}div.goog-modalpopup-bg,div.modal-dialog-bg{filter:alpha(opacity=75);-moz-opacity:.75;opacity:.75}.goog-slider{position:relative;outline:0}.goog-slider-horizontal{height:18px}.goog-slider-vertical{width:18px}.goog-slider-thumb{background-color:#f5f5f5;background-image:-webkit-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-moz-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-ms-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-o-linear-gradient(top,#f5f5f5,#f1f1f1);background-image:linear-gradient(top,#f5f5f5,#f1f1f1);-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;-webkit-transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;-moz-transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;-o-transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;border:1px solid #dcdcdc;height:16px;position:absolute;width:16px}.goog-slider-thumb:hover{background-color:#f8f8f8;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1);border-color:#c6c6c6}.goog-slider-scale{position:absolute}.goog-slider-horizontal .goog-slider-scale{border-top:1px solid #ccc;top:8px;width:100%}.goog-slider-vertical .goog-slider-scale{border-left:1px solid #ccc;height:100%;left:8px}.goog-submenu-arrow{-webkit-transition:all 0.218s;-moz-transition:all 0.218s;-o-transition:all 0.218s;transition:all 0.218s;font-size:70%;left:auto;right:10px;padding-top:3px;padding-right:0;position:absolute;text-align:right;opacity:.5;filter:alpha(opacity=50)}.goog-menuitem-highlight .goog-submenu-arrow,.goog-menuitem-hover .goog-submenu-arrow{-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;border-left-color:#999;opacity:1.0}.goog-menuitem-disabled .goog-submenu-arrow{color:inherit;opacity:1.0}.jfk-textinput{-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;border:1px solid #d9d9d9;border-top:1px solid #c0c0c0;font-size:13px;height:25px;padding:1px 8px}.jfk-textinput:focus{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);box-shadow:inset 0 1px 2px rgba(0,0,0,0.3);border:1px solid #4d90fe;outline:none}.jfk-textinput::-ms-clear{display:none}.goog-toolbar{background:#f5f5f5;border-top:1px solid #e5e5e5;border-bottom:1px solid #ebebeb;outline:0;padding:8px 0 4px 0;position:relative;zoom:1}.goog-toolbar-button,.goog-toolbar-menu-button{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;background:0;border-color:transparent;border-style:solid;border-width:1px;outline:none;padding:0;height:24px;color:#444;line-height:24px;list-style:none;font-size:11px;font-weight:bold;text-decoration:none;vertical-align:middle;cursor:default}.goog-toolbar-button-outer-box,.goog-toolbar-button-inner-box .goog-toolbar-menu-button-outer-box,.goog-toolbar-menu-button-inner-box{border:0;vertical-align:top}.goog-toolbar-button-outer-box,.goog-toolbar-menu-button-outer-box{margin:0;padding:0}.goog-toolbar-button-inner-box,.goog-toolbar-menu-button-inner-box{padding:0 2px}.goog-toolbar-button-hover,.goog-toolbar-button-active,.goog-toolbar-button-checked,.goog-toolbar-button-selected{color:#222;padding:0}.goog-toolbar-button-hover,.goog-toolbar-menu-button-hover{border-color:#c6c6c6!important;color:#222}.goog-toolbar-menu-button-open{color:#222}.goog-toolbar-button-hover,.goog-toolbar-menu-button-hover{-webkit-box-shadow:0 1px 1px rgba(0,0,0,.1);-moz-box-shadow:0 1px 1px rgba(0,0,0,.1);box-shadow:0 1px 1px rgba(0,0,0,.1);background-color:#f8f8f8;background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-moz-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-ms-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);background-image:linear-gradient(top,#f8f8f8,#f1f1f1)}.goog-toolbar-button-active,.goog-toolbar-menu-button-active{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1);background-color:#f6f6f6;background-image:-webkit-linear-gradient(top,#f6f6f6,#f1f1f1);background-image:-moz-linear-gradient(top,#f6f6f6,#f1f1f1);background-image:-ms-linear-gradient(top,#f6f6f6,#f1f1f1);background-image:-o-linear-gradient(top,#f6f6f6,#f1f1f1);background-image:linear-gradient(top,#f6f6f6,#f1f1f1);border-color:#c6c6c6}.goog-toolbar-button-selected,.goog-toolbar-button-checked,.goog-toolbar-menu-button-open{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1);background-color:#eee;background-image:-webkit-linear-gradient(top,#eee,#e0e0e0);background-image:-moz-linear-gradient(top,#eee,#e0e0e0);background-image:-ms-linear-gradient(top,#eee,#e0e0e0);background-image:-o-linear-gradient(top,#eee,#e0e0e0);background-image:linear-gradient(top,#eee,#e0e0e0);border-color:#ccc}.goog-toolbar-button-disabled,.goog-toolbar-menu-button-disabled{color:#222!important;opacity:0.3;filter:alpha(opacity=30)}.goog-toolbar-button-collapse-right,.goog-toolbar-button-collapse-right .goog-toolbar-button-outer-box,.goog-toolbar-button-collapse-right .goog-toolbar-button-inner-box{margin-right:0}.goog-toolbar-button-collapse-left,.goog-toolbar-button-collapse-left .goog-toolbar-button-outer-box,.goog-toolbar-button-collapse-left .goog-toolbar-button-inner-box{margin-left:0}.goog-toolbar-menu-button-dropdown{background:url(//ssl.gstatic.com/ui/v1/disclosure/small-grey-disclosure-arrow-down.png) center no-repeat;float:right;margin:10px 2px 0 3px;padding:0;opacity:.8;vertical-align:middle;width:5px;height:7px;*float:none;*position:relative;*top:-3px}.goog-toolbar-separator{border-left:1px solid #ccc;height:17px;line-height:normal;list-style:none;margin:0 2px;outline:none;overflow:hidden;padding:0;text-decoration:none;vertical-align:middle;width:0}.goog-toolbar-select .goog-toolbar-menu-button-dropdown{background:url(//ssl.gstatic.com/ui/v1/disclosure/small-grey-disclosure-arrow-down.png) center no-repeat;height:11px;margin-top:7px;width:7px;-webkit-transform:none;-moz-transform:none;transform:none;filter:none}.goog-toolbar-menu-button-caption{padding:0;margin:0}.goog-tristatemenuitem-highlight,.goog-tristatemenuitem-hover,.goog-filterobsmenuitem-highlight,.goog-filterobsmenuitem-hover{background-color:#eee;border-color:#eee;border-style:dotted;border-width:1px 0;padding-top:5px;padding-bottom:5px}.goog-menuitem-highlight .goog-menuitem-content,.goog-menuitem-hover .goog-menuitem-content{color:#333}.goog-tristatemenuitem-checkbox{background-repeat:no-repeat;height:21px;left:3px;position:absolute;right:auto;vertical-align:middle;width:21px}.goog-tristatemenuitem,.goog-tristatemenuitem-partially-checked,.goog-tristatemenuitem-fully-checked{background-repeat:no-repeat;background-position:left center}.goog-tristatemenuitem{background-image:url(//ssl.gstatic.com/ui/v1/menu/tristate-unchecked.png)}.goog-tristatemenuitem-partially-checked{background-image:url(//ssl.gstatic.com/ui/v1/menu/tristate-partial.png)}.goog-tristatemenuitem-fully-checked{background-image:url(//ssl.gstatic.com/ui/v1/menu/tristate-checked.png)}.goog-zippy-header{-webkit-transition:background-color .218s,opacity .218s;-moz-transition:background-color .218s,opacity .218s;-o-transition:background-color .218s,opacity .218s;transition:background-color .218s,opacity .218s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:default;opacity:0.8;outline:0;padding:7px 0 7px 17px;position:relative}.goog-zippy-header:focus,.goog-zippy-header:hover{outline:0;background-color:#eee;opacity:1}.goog-zippy-expanded:before{content:url(//ssl.gstatic.com/ui/v1/zippy/arrow_down.png);left:5px;top:5px;position:absolute}.goog-zippy-collapsed:before{content:url(//ssl.gstatic.com/ui/v1/zippy/arrow_right.png);left:7px;top:6px;position:absolute}.goog-zippy-content,.jfk-zippy-content{padding-left:17px}.jfk-freestanding-menu-button{-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;background:url(//ssl.gstatic.com/ui/v1/disclosure/light-grey-disclosure-arrow-down.png) center no-repeat;border:1px solid #e5e5e5;height:11px;width:11px;cursor:pointer}.jfk-freestanding-menu-button-hover,.jfk-freestanding-menu-button-active,.jfk-freestanding-menu-button-open{background:url(//ssl.gstatic.com/ui/v1/disclosure/dark-grey-disclosure-arrow-down.png) center no-repeat #eee;border-color:#c6c6c6}.jfk-select .goog-flat-menu-button-caption{overflow:hidden;width:100%}.jfk-select .goog-flat-menu-button-dropdown{background:url(//ssl.gstatic.com/ui/v1/disclosure/grey-disclosure-arrow-up-down.png) center no-repeat;border:none;height:11px;margin-top:-4px;width:7px}.jfk-progressStatus{color:#202020}.jfk-progressText{color:#999}.jfk-progressStatus,.jfk-progressText{line-height:18px}.jfk-progressBar-blocking .progress-bar-horizontal,.jfk-progressBar-nonBlocking .progress-bar-horizontal{border:1px solid #999;padding:1px;width:320px}.jfk-progressBar-blocking .progress-bar-thumb{background-color:#6188f5;height:5px}.jfk-progressBar-nonBlocking .progress-bar-thumb{background-color:#ccc;height:5px}.jfk-progressBar-blocking.jfk-progressBar-tall .progress-bar-thumb,.jfk-progressBar-nonBlocking.jfk-progressBar-tall .progress-bar-thumb{height:8px}.jfk-progressBar-blocking .progress-bar-thumb{-webkit-animation:jfk-progressBar-bg 0.8s linear 0s infinite;-moz-animation:jfk-progressBar-bg 0.8s linear 0s infinite;-o-animation:jfk-progressBar-bg 0.8s linear 0s infinite;animation:jfk-progressBar-bg 0.8s linear 0s infinite;background-position:0 0;background-repeat:repeat-x;background-size:16px 8px;background-color:auto;background-image:-webkit-linear-gradient(315deg,transparent,transparent 33%,rgba(0,0,0,.12) 33%,rgba(0,0,0,.12) 66%,transparent 66%,transparent);background-image:-moz-linear-gradient(315deg,transparent,transparent 33%,rgba(0,0,0,.12) 33%,rgba(0,0,0,.12) 66%,transparent 66%,transparent);background-image:-ms-linear-gradient(315deg,transparent,transparent 33%,rgba(0,0,0,.12) 33%,rgba(0,0,0,.12) 66%,transparent 66%,transparent);background-image:-o-linear-gradient(315deg,transparent,transparent 33%,rgba(0,0,0,.12) 33%,rgba(0,0,0,.12) 66%,transparent 66%,transparent);background-image:linear-gradient(315deg,transparent,transparent 33%,rgba(0,0,0,.12) 33%,rgba(0,0,0,.12) 66%,transparent 66%,transparent)}.jfk-progressBar-blocking.jfk-progressBar-tall .progress-bar-thumb{-webkit-animation:jfk-progressBar-bg-tall 0.8s linear 0s infinite;-moz-animation:jfk-progressBar-bg-tall 0.8s linear 0s infinite;-o-animation:jfk-progressBar-bg-tall 0.8s linear 0s infinite;animation:jfk-progressBar-bg-tall 0.8s linear 0s infinite;background-size:20px 10px}@-webkit-keyframes jfk-progressBar-bg{0%{background-position:0 0}100%{background-position:-16px 0}}@-moz-keyframes jfk-progressBar-bg{0%{background-position:0 0}100%{background-position:-16px 0}}@-o-keyframes jfk-progressBar-bg{0%{background-position:0 0}100%{background-position:-16px 0}}@keyframes jfk-progressBar-bg{0%{background-position:0 0}100%{background-position:-16px 0}}@-webkit-keyframes jfk-progressBar-bg-tall{0%{background-position:0 0}100%{background-position:-20px 0}}@-moz-keyframes jfk-progressBar-bg-tall{0%{background-position:0 0}100%{background-position:-20px 0}}@-o-keyframes jfk-progressBar-bg-tall{0%{background-position:0 0}100%{background-position:-20px 0}}@keyframes jfk-progressBar-bg-tall{0%{background-position:0 0}100%{background-position:-20px 0}}.jfk-progressbar .progress-bar-horizontal,.jfk-progressbar .progress-bar-vertical{border-color:#999}.jfk-progressbar .progress-bar-thumb{background-color:#ccc}.jfk-radiobutton{display:inline-block;outline:none;padding:5px 7px;position:relative}.jfk-radiobutton-radio{-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background:url(//ssl.gstatic.com/ui/v1/radiobutton/unchecked.png) -3px -3px;background:rgba(255,255,255,0);border:1px solid rgba(198,198,198,1);height:15px;left:7px;margin:0;outline:none;position:absolute;text-align:left;top:6px;width:15px}.jfk-radiobutton:active .jfk-radiobutton-radio{background:rgba(235,235,235,1);border-color:rgba(182,182,182,1)}.jfk-radiobutton:hover .jfk-radiobutton-radio{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.1);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.1);box-shadow:inset 0 1px 1px rgba(0,0,0,.1);border-color:rgba(182,182,182,1)}.jfk-radiobutton:focus .jfk-radiobutton-radio{border-color:rgba(77,144,254,1)}.jfk-radiobutton-checked .jfk-radiobutton-radio{background:url(//ssl.gstatic.com/ui/v1/radiobutton/checked.png) -3px -3px;background:rgba(255,255,255,0)}.jfk-radiobutton.jfk-radiobutton:focus .jfk-radiobutton-radio{background:url(//ssl.gstatic.com/ui/v1/radiobutton/unchecked_focused.png) -3px -3px;background:rgba(255,255,255,0)}.jfk-radiobutton-checked.jfk-radiobutton:focus .jfk-radiobutton-radio{background:url(//ssl.gstatic.com/ui/v1/radiobutton/checked_focused.png) -3px -3px;background:rgba(255,255,255,0)}.jfk-radiobutton-checked .jfk-radiobutton-radio::after{-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%;background:rgba(96,96,96,1);content:'';display:block;height:7px;left:3px;position:relative;top:3px;width:7px}.jfk-radiobutton .jfk-radiobutton-label{cursor:default;margin-left:22px}.jfk-radiobutton-disabled .jfk-radiobutton-radio{background:url(//ssl.gstatic.com/ui/v1/radiobutton/unchecked-disabled.png) -3px -3px;background:rgba(255,255,255,0);border-color:rgba(241,241,241,1)}.jfk-radiobutton-disabled.jfk-radiobutton-checked .jfk-radiobutton-radio{background:url(//ssl.gstatic.com/ui/v1/radiobutton/checked-disabled.png) -3px -3px;background:rgba(255,255,255,0)}.jfk-radiobutton-disabled.jfk-radiobutton-checked .jfk-radiobutton-radio::after{background:rgba(184,184,184,1)}.jfk-radiobutton-disabled .jfk-radiobutton-label{color:rgb(184,184,184)}.jfk-radiobutton-disabled:active .jfk-radiobutton-radio,.jfk-radiobutton-disabled:hover .jfk-radiobutton-radio{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:rgba(255,255,255,1);border-color:rgba(241,241,241,1)}.jfk-rating{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;display:inline-block;outline:none}.jfk-rating:hover{}.jfk-rating:focus{}.jfk-rating-star{display:inline-block;height:13px;margin:0 3px;text-align:center;width:13px}.jfk-rating-actionable .jfk-rating-star{cursor:pointer}.jfk-rating .jfk-rating-star{background:url(//ssl.gstatic.com/ui/v1/rating/rating-blank.png) no-repeat}.jfk-rating .jfk-rating-star-half{background:url(//ssl.gstatic.com/ui/v1/rating/rating-half.png) no-repeat}.jfk-rating .jfk-rating-star-full{background:url(//ssl.gstatic.com/ui/v1/rating/rating-full.png) no-repeat}.jfkScrollable{height:100%;padding:0;position:relative}.jfkScrollable-inner{height:100%;overflow:auto;width:100%}.jfkScrollable-topShadow,.jfkScrollable-bottomShadow{left:0;opacity:0;pointer-events:none;position:absolute;width:100%}.jfkScrollable-topShadow{background:-webkit-linear-gradient(rgba(0,0,0,.2),transparent);background:-moz-linear-gradient(rgba(0,0,0,.1),transparent);height:6px;top:0;-webkit-mask-box-image:-webkit-linear-gradient(left,rgba(0,0,0,.1),rgba(0,0,0,.8),rgba(0,0,0,.1))}.jfkScrollable-bottomShadow{background:-webkit-linear-gradient(transparent,rgba(0,0,0,.2));background:-moz-linear-gradient(transparent,rgba(0,0,0,.1));bottom:0;height:4px;-webkit-mask-box-image:-webkit-linear-gradient(left,rgba(0,0,0,.1),rgba(0,0,0,.8),rgba(0,0,0,.1))}.jfkScrollable-top>.jfkScrollable-topShadow,.jfkScrollable-bottom>.jfkScrollable-bottomShadow{display:block}.jfk-scroll-shadow{background-image:-webkit-linear-gradient(rgb(255,255,255) 30%,rgba(255,255,255,0)),-webkit-linear-gradient(rgba(255,255,255,0),rgb(255,255,255) 70%),-webkit-radial-gradient(50% 0,farthest-side,rgba(0,0,0,.2),transparent),-webkit-radial-gradient(50% 100%,farthest-side,rgba(0,0,0,.2),transparent);background-attachment:local,local,scroll,scroll;background-position:top,bottom,top,bottom;background-color:rgb(255,255,255);background-repeat:no-repeat;background-size:100% 15px,100% 15px,100% 6px,100% 6px}::-webkit-scrollbar{height:16px;overflow:visible;width:16px}::-webkit-scrollbar-button{height:0;width:0}::-webkit-scrollbar-track{background-clip:padding-box;border:solid transparent;border-width:0 0 0 4px}::-webkit-scrollbar-track:horizontal{border-width:4px 0 0}::-webkit-scrollbar-track:hover{background-color:rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(0,0,0,.1)}::-webkit-scrollbar-track:horizontal:hover{box-shadow:inset 0 1px 0 rgba(0,0,0,.1)}::-webkit-scrollbar-track:active{background-color:rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(0,0,0,.14),inset -1px 0 0 rgba(0,0,0,.07)}::-webkit-scrollbar-track:horizontal:active{box-shadow:inset 0 1px 0 rgba(0,0,0,.14),inset 0 -1px 0 rgba(0,0,0,.07)}.jfk-scrollbar-dark::-webkit-scrollbar-track:hover{background-color:rgba(255,255,255,.1);box-shadow:inset 1px 0 0 rgba(255,255,255,.2)}.jfk-scrollbar-dark::-webkit-scrollbar-track:horizontal:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,.2)}.jfk-scrollbar-dark::-webkit-scrollbar-track:active{background-color:rgba(255,255,255,.1);box-shadow:inset 1px 0 0 rgba(255,255,255,.25),inset -1px 0 0 rgba(255,255,255,.15)}.jfk-scrollbar-dark::-webkit-scrollbar-track:horizontal:active{box-shadow:inset 0 1px 0 rgba(255,255,255,.25),inset 0 -1px 0 rgba(255,255,255,.15)}::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.2);background-clip:padding-box;border:solid transparent;border-width:1px 1px 1px 6px;min-height:28px;padding:100px 0 0;box-shadow:inset 1px 1px 0 rgba(0,0,0,.1),inset 0 -1px 0 rgba(0,0,0,.07)}::-webkit-scrollbar-thumb:horizontal{border-width:6px 1px 1px;padding:0 0 0 100px;box-shadow:inset 1px 1px 0 rgba(0,0,0,.1),inset -1px 0 0 rgba(0,0,0,.07)}::-webkit-scrollbar-thumb:hover{background-color:rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.25)}::-webkit-scrollbar-thumb:active{background-color:rgba(0,0,0,0.5);box-shadow:inset 1px 1px 3px rgba(0,0,0,0.35)}.jfk-scrollbar-dark::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.3);box-shadow:inset 1px 1px 0 rgba(255,255,255,.15),inset 0 -1px 0 rgba(255,255,255,.1)}.jfk-scrollbar-dark::-webkit-scrollbar-thumb:horizontal{box-shadow:inset 1px 1px 0 rgba(255,255,255,.15),inset -1px 0 0 rgba(255,255,255,.1)}.jfk-scrollbar-dark::-webkit-scrollbar-thumb:hover{background-color:rgba(255,255,255,.6);box-shadow:inset 1px 1px 1px rgba(255,255,255,.37)}.jfk-scrollbar-dark::-webkit-scrollbar-thumb:active{background-color:rgba(255,255,255,.75);box-shadow:inset 1px 1px 3px rgba(255,255,255,.5)}.jfk-scrollbar-borderless::-webkit-scrollbar-track{border-width:0 1px 0 6px}.jfk-scrollbar-borderless::-webkit-scrollbar-track:horizontal{border-width:6px 0 1px}.jfk-scrollbar-borderless::-webkit-scrollbar-track:hover{background-color:rgba(0,0,0,.035);box-shadow:inset 1px 1px 0 rgba(0,0,0,.14),inset -1px -1px 0 rgba(0,0,0,.07)}.jfk-scrollbar-borderless.jfk-scrollbar-dark::-webkit-scrollbar-track:hover{background-color:rgba(255,255,255,.07);box-shadow:inset 1px 1px 0 rgba(255,255,255,.25),inset -1px -1px 0 rgba(255,255,255,.15)}.jfk-scrollbar-borderless::-webkit-scrollbar-thumb{border-width:0 1px 0 6px}.jfk-scrollbar-borderless::-webkit-scrollbar-thumb:horizontal{border-width:6px 0 1px}::-webkit-scrollbar-corner{background:transparent}body::-webkit-scrollbar-track-piece{background-clip:padding-box;background-color:#f5f5f5;border:solid #fff;border-width:0 0 0 3px;box-shadow:inset 1px 0 0 rgba(0,0,0,.14),inset -1px 0 0 rgba(0,0,0,.07)}body::-webkit-scrollbar-track-piece:horizontal{border-width:3px 0 0;box-shadow:inset 0 1px 0 rgba(0,0,0,.14),inset 0 -1px 0 rgba(0,0,0,.07)}body::-webkit-scrollbar-thumb{border-width:1px 1px 1px 5px}body::-webkit-scrollbar-thumb:horizontal{border-width:5px 1px 1px}body::-webkit-scrollbar-corner{background-clip:padding-box;background-color:#f5f5f5;border:solid #fff;border-width:3px 0 0 3px;box-shadow:inset 1px 1px 0 rgba(0,0,0,.14)}.jfk-scrollbar::-webkit-scrollbar{height:16px;overflow:visible;width:16px}.jfk-scrollbar::-webkit-scrollbar-button{height:0;width:0}.jfk-scrollbar::-webkit-scrollbar-track{background-clip:padding-box;border:solid transparent;border-width:0 0 0 4px}.jfk-scrollbar::-webkit-scrollbar-track:horizontal{border-width:4px 0 0}.jfk-scrollbar::-webkit-scrollbar-track:hover{background-color:rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(0,0,0,.1)}.jfk-scrollbar::-webkit-scrollbar-track:horizontal:hover{box-shadow:inset 0 1px 0 rgba(0,0,0,.1)}.jfk-scrollbar::-webkit-scrollbar-track:active{background-color:rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(0,0,0,.14),inset -1px 0 0 rgba(0,0,0,.07)}.jfk-scrollbar::-webkit-scrollbar-track:horizontal:active{box-shadow:inset 0 1px 0 rgba(0,0,0,.14),inset 0 -1px 0 rgba(0,0,0,.07)}.jfk-scrollbar-dark.jfk-scrollbar::-webkit-scrollbar-track:hover{background-color:rgba(255,255,255,.1);box-shadow:inset 1px 0 0 rgba(255,255,255,.2)}.jfk-scrollbar-dark.jfk-scrollbar::-webkit-scrollbar-track:horizontal:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,.2)}.jfk-scrollbar-dark.jfk-scrollbar::-webkit-scrollbar-track:active{background-color:rgba(255,255,255,.1);box-shadow:inset 1px 0 0 rgba(255,255,255,.25),inset -1px 0 0 rgba(255,255,255,.15)}.jfk-scrollbar-dark.jfk-scrollbar::-webkit-scrollbar-track:horizontal:active{box-shadow:inset 0 1px 0 rgba(255,255,255,.25),inset 0 -1px 0 rgba(255,255,255,.15)}.jfk-scrollbar::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.2);background-clip:padding-box;border:solid transparent;border-width:1px 1px 1px 6px;min-height:28px;padding:100px 0 0;box-shadow:inset 1px 1px 0 rgba(0,0,0,.1),inset 0 -1px 0 rgba(0,0,0,.07)}.jfk-scrollbar::-webkit-scrollbar-thumb:horizontal{border-width:6px 1px 1px;padding:0 0 0 100px;box-shadow:inset 1px 1px 0 rgba(0,0,0,.1),inset -1px 0 0 rgba(0,0,0,.07)}.jfk-scrollbar::-webkit-scrollbar-thumb:hover{background-color:rgba(0,0,0,.4);box-shadow:inset 1px 1px 1px rgba(0,0,0,.25)}.jfk-scrollbar::-webkit-scrollbar-thumb:active{background-color:rgba(0,0,0,0.5);box-shadow:inset 1px 1px 3px rgba(0,0,0,0.35)}.jfk-scrollbar-dark.jfk-scrollbar::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.3);box-shadow:inset 1px 1px 0 rgba(255,255,255,.15),inset 0 -1px 0 rgba(255,255,255,.1)}.jfk-scrollbar-dark.jfk-scrollbar::-webkit-scrollbar-thumb:horizontal{box-shadow:inset 1px 1px 0 rgba(255,255,255,.15),inset -1px 0 0 rgba(255,255,255,.1)}.jfk-scrollbar-dark.jfk-scrollbar::-webkit-scrollbar-thumb:hover{background-color:rgba(255,255,255,.6);box-shadow:inset 1px 1px 1px rgba(255,255,255,.37)}.jfk-scrollbar-dark.jfk-scrollbar::-webkit-scrollbar-thumb:active{background-color:rgba(255,255,255,.75);box-shadow:inset 1px 1px 3px rgba(255,255,255,.5)}.jfk-scrollbar-borderless.jfk-scrollbar::-webkit-scrollbar-track{border-width:0 1px 0 6px}.jfk-scrollbar-borderless.jfk-scrollbar::-webkit-scrollbar-track:horizontal{border-width:6px 0 1px}.jfk-scrollbar-borderless.jfk-scrollbar::-webkit-scrollbar-track:hover{background-color:rgba(0,0,0,.035);box-shadow:inset 1px 1px 0 rgba(0,0,0,.14),inset -1px -1px 0 rgba(0,0,0,.07)}.jfk-scrollbar-borderless.jfk-scrollbar-dark.jfk-scrollbar::-webkit-scrollbar-track:hover{background-color:rgba(255,255,255,.07);box-shadow:inset 1px 1px 0 rgba(255,255,255,.25),inset -1px -1px 0 rgba(255,255,255,.15)}.jfk-scrollbar-borderless.jfk-scrollbar::-webkit-scrollbar-thumb{border-width:0 1px 0 6px}.jfk-scrollbar-borderless.jfk-scrollbar::-webkit-scrollbar-thumb:horizontal{border-width:6px 0 1px}.jfk-scrollbar::-webkit-scrollbar-corner{background:transparent}body.jfk-scrollbar::-webkit-scrollbar-track-piece{background-clip:padding-box;background-color:#f5f5f5;border:solid #fff;border-width:0 0 0 3px;box-shadow:inset 1px 0 0 rgba(0,0,0,.14),inset -1px 0 0 rgba(0,0,0,.07)}body.jfk-scrollbar::-webkit-scrollbar-track-piece:horizontal{border-width:3px 0 0;box-shadow:inset 0 1px 0 rgba(0,0,0,.14),inset 0 -1px 0 rgba(0,0,0,.07)}body.jfk-scrollbar::-webkit-scrollbar-thumb{border-width:1px 1px 1px 5px}body.jfk-scrollbar::-webkit-scrollbar-thumb:horizontal{border-width:5px 1px 1px}body.jfk-scrollbar::-webkit-scrollbar-corner{background-clip:padding-box;background-color:#f5f5f5;border:solid #fff;border-width:3px 0 0 3px;box-shadow:inset 1px 1px 0 rgba(0,0,0,.14)}.jfk-twothumbslider{position:relative;outline:0}.goog-twothumbslider-horizontal{height:18px}.goog-twothumbslider-vertical{width:18px}.goog-twothumbslider-horizontal .goog-twothumbslider-value-thumb,.goog-twothumbslider-horizontal .goog-twothumbslider-extent-thumb{position:absolute;height:0;width:16px}.goog-twothumbslider-vertical .goog-twothumbslider-value-thumb,.goog-twothumbslider-vertical .goog-twothumbslider-extent-thumb{position:absolute;height:16px;width:0}.jfk-slider-thumbimpl{background-color:#999;border:1px solid #999;-webkit-transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;-moz-transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;-o-transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;transition:background-color 0.218s,border-color 0.218s,background-image 0.218s}.jfk-twothumbslider:hover .jfk-slider-thumbimpl,.jfk-twothumbslider.goog-slider-dragging .jfk-slider-thumbimpl{background-color:#fff}.jfk-twothumbslider.goog-slider-dragging .goog-slider-thumb-dragging .jfk-slider-thumbimpl{background-color:#535252;border-color:#535252}.goog-twothumbslider-horizontal .jfk-slider-thumbimpl{height:16px;width:8px}.goog-twothumbslider-horizontal .goog-twothumbslider-value-thumb .jfk-slider-thumbimpl{-webkit-border-radius:8px 0 0 8px;-moz-border-radius:8px 0 0 8px;border-radius:8px 0 0 8px}.goog-twothumbslider-horizontal .goog-twothumbslider-extent-thumb .jfk-slider-thumbimpl{-webkit-border-radius:0 8px 8px 0;-moz-border-radius:0 8px 8px 0;border-radius:0 8px 8px 0;margin-left:8px}.goog-twothumbslider-vertical .jfk-slider-thumbimpl{height:8px;width:16px}.goog-twothumbslider-vertical .goog-twothumbslider-value-thumb .jfk-slider-thumbimpl{margin-top:8px;-webkit-border-radius:0 0 8px 8px;-moz-border-radius:0 0 8px 8px;border-radius:0 0 8px 8px}.goog-twothumbslider-vertical .goog-twothumbslider-extent-thumb .jfk-slider-thumbimpl{-webkit-border-radius:8px 8px 0 0;-moz-border-radius:8px 8px 0 0;border-radius:8px 8px 0 0}.jfk-slider-scale{background-color:#e5e5e5;position:absolute;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.goog-twothumbslider-horizontal .jfk-slider-scale{height:6px;top:6px;width:100%}.goog-twothumbslider-vertical .jfk-slider-scale{height:100%;left:6px;width:6px}.goog-twothumbslider-rangehighlight{background-color:#c6c6c6;position:absolute;-webkit-transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;-moz-transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;-o-transition:background-color 0.218s,border-color 0.218s,background-image 0.218s;transition:background-color 0.218s,border-color 0.218s,background-image 0.218s}.jfk-twothumbslider:hover .goog-twothumbslider-rangehighlight,.jfk-twothumbslider.goog-slider-dragging .goog-twothumbslider-rangehighlight{background-color:#535252}.jfk-twothumbslider.goog-slider-dragging .goog-twothumbslider-rangehighlight{background-image:url(//ssl.gstatic.com/ui/v1/slider/rangehighlight-active-gray.png)}.goog-twothumbslider-horizontal .goog-twothumbslider-rangehighlight{height:6px;top:6px}.goog-twothumbslider-vertical .goog-twothumbslider-rangehighlight{left:6px;width:6px}.jfk-star{display:inline-block;height:19px;text-align:center;width:19px;padding:2px}.jfk-star:before{content:url(//ssl.gstatic.com/ui/v1/star/star4.png);content:-webkit-image-set(url(//ssl.gstatic.com/ui/v1/star/star4.png) 1x,url(//ssl.gstatic.com/ui/v1/star/star4_2x.png) 2x)}.jfk-star-hover:before{content:url(//ssl.gstatic.com/ui/v1/star/star-hover4.png);content:-webkit-image-set(url(//ssl.gstatic.com/ui/v1/star/star-hover4.png) 1x,url(//ssl.gstatic.com/ui/v1/star/star-hover4_2x.png) 2x)}.jfk-star-active:before{content:url(//ssl.gstatic.com/ui/v1/star/star-active4.png);content:-webkit-image-set(url(//ssl.gstatic.com/ui/v1/star/star-active4.png) 1x,url(//ssl.gstatic.com/ui/v1/star/star-active4_2x.png) 2x)}.jfk-star-checked:before{content:url(//ssl.gstatic.com/ui/v1/star/star-lit4.png);content:-webkit-image-set(url(//ssl.gstatic.com/ui/v1/star/star-lit4.png) 1x,url(//ssl.gstatic.com/ui/v1/star/star-lit4_2x.png) 2x)}.jfk-star-checked.jfk-star-hover:before{content:url(//ssl.gstatic.com/ui/v1/star/star-lit-hover4.png);content:-webkit-image-set(url(//ssl.gstatic.com/ui/v1/star/star-lit-hover4.png) 1x,url(//ssl.gstatic.com/ui/v1/star/star-lit-hover4_2x.png) 2x)}.jfk-star-checked.jfk-star-active:before{content:url(//ssl.gstatic.com/ui/v1/star/star-lit-active4.png);content:-webkit-image-set(url(//ssl.gstatic.com/ui/v1/star/star-lit-active4.png) 1x,url(//ssl.gstatic.com/ui/v1/star/star-lit-active4_2x.png) 2x)}.jfk-tooltip{background-color:#2a2a2a;border:1px solid #fff;color:#fff;display:block;font-size:11px;font-weight:bold;opacity:1;padding:7px 9px;pointer-events:none;position:absolute;-webkit-transition:visibility 0,opacity .13s ease-in;-moz-transition:visibility 0,opacity .13s ease-in;-o-transition:visibility 0,opacity .13s ease-in;transition:visibility 0,opacity .13s ease-in;visibility:visible;word-break:break-all;word-break:break-word}.jfk-tooltip-hide{left:20px!important;top:20px!important;opacity:0;-webkit-transition:visibility .13s,opacity .13s ease-out,left 0 linear .13s,top 0 linear .13s;-moz-transition:visibility .13s,opacity .13s ease-out,left 0 linear .13s,top 0 linear .13s;-o-transition:visibility .13s,opacity .13s ease-out,left 0 linear .13s,top 0 linear .13s;transition:visibility .13s,opacity .13s ease-out,left 0 linear .13s,top 0 linear .13s;visibility:hidden}.jfk-tooltip-arrow{position:absolute}.jfk-tooltip-arrow .jfk-tooltip-arrowimplbefore,.jfk-tooltip-arrow .jfk-tooltip-arrowimplafter{content:'';display:block;height:0;position:absolute;width:0}.jfk-tooltip-arrow .jfk-tooltip-arrowimplbefore{border:6px solid}.jfk-tooltip-arrow .jfk-tooltip-arrowimplafter{border:5px solid}.jfk-tooltip-arrowdown{bottom:0}.jfk-tooltip-arrowup{top:-6px}.jfk-tooltip-arrowleft{left:-6px}.jfk-tooltip-arrowright{right:0}.jfk-tooltip-arrowdown .jfk-tooltip-arrowimplbefore,.jfk-tooltip-arrowup .jfk-tooltip-arrowimplbefore{border-color:#fff transparent;left:-6px}.jfk-tooltip-arrowdown .jfk-tooltip-arrowimplafter,.jfk-tooltip-arrowup .jfk-tooltip-arrowimplafter{border-color:#2a2a2a transparent;left:-5px}.jfk-tooltip-arrowdown .jfk-tooltip-arrowimplbefore{border-bottom-width:0}.jfk-tooltip-arrowdown .jfk-tooltip-arrowimplafter{border-bottom-width:0}.jfk-tooltip-arrowup .jfk-tooltip-arrowimplbefore{border-top-width:0}.jfk-tooltip-arrowup .jfk-tooltip-arrowimplafter{border-top-width:0;top:1px}.jfk-tooltip-arrowleft .jfk-tooltip-arrowimplbefore,.jfk-tooltip-arrowright .jfk-tooltip-arrowimplbefore{border-color:transparent #fff;top:-6px}.jfk-tooltip-arrowleft .jfk-tooltip-arrowimplafter,.jfk-tooltip-arrowright .jfk-tooltip-arrowimplafter{border-color:transparent #2a2a2a;top:-5px}.jfk-tooltip-arrowleft .jfk-tooltip-arrowimplbefore{border-left-width:0}.jfk-tooltip-arrowleft .jfk-tooltip-arrowimplafter{border-left-width:0;left:1px}.jfk-tooltip-arrowright .jfk-tooltip-arrowimplbefore{border-right-width:0}.jfk-tooltip-arrowright .jfk-tooltip-arrowimplafter{border-right-width:0}a{text-decoration:none}a:link{color:#15c}a:visited{color:#61c}a:active{color:#d14836}a:hover{text-decoration:underline}b,strong{color:#000;font-weight:bold}.jfk-productName{color:#dd4b39;font-size:20px}.jfk-sectionHeader{color:#222;font-size:16px}.jfk-titleLink{color:#15c;font-size:16px;font-weight:bold;text-decoration:none}.jfk-greyText{color:#555}.jfk-secondaryText{color:#777;font-size:11px}.jfk-sourceLink{color:#093;font-size:11px;text-decoration:none}body{font:13px Arial,sans-serif}.logdiv{direction:ltr;height:300px;overflow-y:scroll}.jfk-rtlDemo{background:#fff;background-clip:padding-box;border:solid #ccc;border-width:1px 0 0 1px;bottom:0;box-shadow:0 4px 16px rgba(0,0,0,.2);height:30px;padding:21px;position:fixed;right:0}.jfk-rtlDemo-message{background:#fff;font-size:16px;font-weight:bold;left:0;height:51px;padding-top:21px;position:absolute;text-align:center;top:0;width:100%;z-index:3;filter:alpha(opacity=75);opacity:.75}.jfk-rtlDemo-buttons{display:inline-block;padding-left:16px}.jfk-scroll-shadow-blue-on-beige{background-image:-webkit-linear-gradient(rgb(245,245,220) 30%,rgba(245,245,220,0)),-webkit-linear-gradient(rgba(245,245,220,0),rgb(245,245,220) 70%),-webkit-radial-gradient(50% 0,farthest-side,blue,transparent),-webkit-radial-gradient(50% 100%,farthest-side,blue,transparent);background-attachment:local,local,scroll,scroll;background-position:top,bottom,top,bottom;background-color:rgb(245,245,220);background-repeat:no-repeat;background-size:100% 15px,100% 15px,100% 6px,100% 6px} diff --git a/core/src/main/javascript/google/registry/ui/css/epp.css b/core/src/main/javascript/google/registry/ui/css/epp.css deleted file mode 100644 index d53f4323d..000000000 --- a/core/src/main/javascript/google/registry/ui/css/epp.css +++ /dev/null @@ -1,61 +0,0 @@ -/* EPP styles */ - -.reg-add:before { - content: '+ '; -} - -.contact h1 { - width: 650px; - background: url('/assets/images/ic_contacts_blue_12.png') no-repeat 0 0.7em; - padding-left: 2em; - margin-left: 0.75em; -} - -/* Remove button. */ -#contact-postalInfo table button { - margin: 1em; - float: right; -} - -#contact-postalInfoHeader { - color: #777; - font-weight: normal; -} - -#contact-postalInfo .info { - font-size: 11px; - color: #666; -} - -#contact-postalInfo table { - margin: 0 0 1em 0; - padding: 1em; -} - -#contact-postalInfo tr { - margin: auto 2em; -} - -#contact-postalInfo tr:first-child { - margin-top: 1em; -} - -#contact-postalInfo tr:last-child { - margin-bottom: 1em; -} - -#contact-postalInfo table, -#contact-postalInfo input[readonly], -#contact-postalInfo textarea[readonly] { - background-color: #f1f1f1; - border-color: #f1f1f1; -} - -#contact-postalInfoHeader button { - display: block; - margin: 1em 0; -} - -#contact-postalInfoHeader button[disabled] { - display: none; -} diff --git a/core/src/main/javascript/google/registry/ui/css/forms.css b/core/src/main/javascript/google/registry/ui/css/forms.css deleted file mode 100644 index 29c5ca559..000000000 --- a/core/src/main/javascript/google/registry/ui/css/forms.css +++ /dev/null @@ -1,187 +0,0 @@ -form.set, -form.item, -div.set, -div.item { - width: 700px; -} - -.set table, -.item table { - width: 100%; - border-collapse: separate; - border-spacing: 0; -} - -/* Going to play some games here to get section leads to float left, - * followed by their next rows in floated right column. */ -.item table, -.set table { - padding-top: 2em; - margin-top: 1em; - border-top: solid 1px #ebebeb; -} - -.set tr, -.item tr { - margin: 0; - padding: 0; - min-height: 28px; -} - -.set td, -.item td { - padding: 0.5em 0; -} - -.item tr.section-lead th h2, -.item tr.section-lead th h3 { - font-size: 1em; - font-weight: bold; - color: #15c; -} - -tr.subsection h3::first-letter { - text-transform: capitalize; -} - -.set td:first-child, -.item td:first-child { - width: 260px; -} - -.set td:first-child span.description, -.item td:first-child span.description { - width: 170px; -} - -.description ol { - list-style-type: decimal; - margin-left: 2em; -} - - -/* Setting groups and labels. */ - -.set .kd-settings-pane-section td { - border-bottom: solid 1px #ebebeb; -} - -td.setting-group-compact { - padding-left: 0.5em; -} - -.setting-group-compact div { - line-height: 140%; -} - -.item label { - font-weight: bold; -} - -.set label + input { - margin-left: 1em; -} - -.kd-settings-pane-section td label.setting-label { - padding-top: 0.5em; -} - -td.label { - width: 70%; -} - -/* Compact sequence of labels. */ -.setting label + label { - margin-left: 2em; -} - -form label, -.setting-label { - line-height: 13px; - margin-bottom: 5px; -} - -.setting label { - display: inline-block; - font-weight: normal; - margin-right: 1em; - vertical-align: top; -} - -div.checkbox-with-label { - margin-bottom: 1em; -} - - -/* Controls */ - -.set input:not([type="submit"]), -.item input:not([type="submit"]) { - width: 250px; - padding: 0.5em; -} - -.item input[type='checkbox'], -.item input[type='radio'] { - width: auto; -} - -input[readonly] { - border: solid 1px white; - margin-left: 0.5em; - padding-top: 0 !important; - padding-left: 0 !important; -} - -.setting input[type=radio] { -} - -.setting input[type=radio], -.setting input[type=checkbox] { - position: relative; - top: -3px; -} - -/** - * Consistent top space in second column items. Input elements need to - * switch from using margin to padding when they're edit toggled, so that - * the text doesn't move. The other elements are just defined here for - * consistency. - * @see td.domain-registrar-contacts - */ -input[readonly], -td.setting p { - margin-top: 0.5em; - margin-left: 0.5em; -} - -.item button[disabled] { - display: none; -} - -div.checkbox-with-label input[type='checkbox'], -div.checkbox-with-label input[type='checkbox'] + label { - display: inline-block; -} - -/* - * 3 line street has just inputs in a row - * @see td padding-bottom - */ -.setting input + input, -.setting div { - margin-top: 1em; -} - -.setting div { - margin-top: 0.5em; -} - -.setting input[type='checkbox'] { - display: inline; -} - -.setting input + button, -.setting-item-list { - margin-left: 0.5em; -} diff --git a/core/src/main/javascript/google/registry/ui/css/kd_components.css b/core/src/main/javascript/google/registry/ui/css/kd_components.css deleted file mode 100644 index 8c98d96f5..000000000 --- a/core/src/main/javascript/google/registry/ui/css/kd_components.css +++ /dev/null @@ -1,4493 +0,0 @@ -/*------------------------------------------------------------------ -eric meyer's reset -------------------------------------------------------------------*/ -html,body,div,span,applet,object,iframe, -h1,h2,h3,h4,h5,h6,p,blockquote,pre, -a,abbr,acronym,address,big,cite,code, -del,dfn,em,font,img,ins,kbd,q,s,samp, -small,strike,strong,sub,sup,tt,var, -dl,dt,dd,ol,ul,li, -fieldset,form,label,legend, -table,caption,tbody,tfoot,thead,tr,th,td { - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-weight: inherit; - font-style: inherit; - font-size: 100%; - font-family: inherit; - vertical-align: baseline; -} -body { - line-height: 1; - color: black; - background: white; -} -ol,ul { - list-style: none; -} -table { - border-collapse: separate; - border-spacing: 0; -} -caption,th,td { - text-align: left; - font-weight: normal; -} -blockquote:before,blockquote:after, -q:before,q:after { - content: ""; -} -blockquote,q { - quotes: "" ""; -} -input::-moz-focus-inner { - border: 0; -} - - -/*------------------------------------------------------------------ -@global Type -------------------------------------------------------------------*/ -body,body input,body button,body td { - font-family: "Arial", "Helvetica", sans-serif; - color: #222; - font-size:13px; - -webkit-tap-highlight-color: rgba(0,0,0,0); -} -h1,h2,h3,h4,h5 { - font-size: 16px; - line-height:24px; - font-weight: normal; - color: #222; -} -p { - margin: 0 0 1em; - font-size: 13px; - line-height: 18px; -} -p.nonLatin { - font-size: 14px; - line-height: 21px; -} -li { - line-height: 17px; -} -a { - text-decoration: none; - color: #15c; - cursor: pointer; -} -a:visited { - color: #61c; -} -a:active { - color: #d14836; -} -a.secondary { - text-decoration: none; - color: #2D9AE3; -} -iframe { - border: 0px; -} -strong, b { - color: #000; - font-weight:bold; -} -em { - font-style: italic; -} - -div.mobile { - width:320px; -} - -.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; } /*i'm leaving these in case we end up needing them*/ -.clearfix:after { clear: both; } -.clearfix { zoom: 1; } - -/*------------------------------------------------------------------ -Stickersheet global styles -------------------------------------------------------------------*/ -#stickersheet #siteTitle { - padding: 30px 40px; -} -#stickers > ul > li { - padding: 30px 0; - border-bottom: 1px solid #DDD; - position: relative; -} -.componentName { - display: block; - height: 29px; - float: none; - font-size: 20px; - line-height: 24px; - color: #222; - margin-bottom: 21px; - margin-left: 0px; - margin-right: 0px; -} -.option { - float: left; - width: 336px; - margin-right: 16px; -} -.option .componentName { - margin-bottom: 0; -} -#stickersheet h2.componentName a { - color: #222; -} -#stickers > ul { - margin: 0 44px; -} -/* stickersheet specific positioning */ -.kd-modaldialog.demo, -.kd-settings.demo { - position: relative; - top: 0; - left: 0; - margin-left: 0; - z-index: 0; -} -#stickers #kd-tooltip { - top: 75px; - margin-left: 0; -} -#wrap { - overflow: auto; - height: 100%; -} -#stickers > ul > li ol { - margin: 5px 10px; -} -#stickers > ul > li ol li { - margin-bottom: 5px; -} -#stickers .kd-buttonbar { - margin-bottom: 16px; -} -#modaldemo { - display: none; -} -.sectionTitle { - float: left; - width: 160px; - margin-right: 16px; - clear: left; - margin-bottom: 16px; -} -.sectionContent { - float: left; - clear: right; - margin-bottom: 16px; -} - -/*------------------------------------------------------------------ -Styleguide container -------------------------------------------------------------------*/ -.styleguide { - padding: 0 44px 44px; -} -.styleguide .section { - position:relative; - padding: 44px 0; - height: 100%; - overflow:visible; - border-bottom: 1px solid #ebebeb; -} -.styleguide .section.clearfix { - overflow:hidden; -} -.styleguide .section .section { - padding: 16px 0; - border-bottom: 0; -} -.styleguide .section h3 { -/* margin: 16px 0;*/ -} -#styleGuideNav { - width:156px; - position:fixed; - left:0; - top:28px; -} -#styleGuideNav li li a{ - width:144px; - overflow:hidden; - white-space:nowrap; - text-overflow:ellipsis; -} -#styleGuideNav li li a.selected{ - color:#d14836; -} - -/*------------------------------------------------------------------ -Notes And Metrics -------------------------------------------------------------------*/ -.notesBox .kd-zippy{ - margin-top:-20px; -} -.notesBox .kd-zippy .row{ - float:right; - display: block; - clear:both; -} -.notesBox .kd-disclosureindicator { - position:relative; - top:-2px; - cursor:default; -} -.notesBox .kd-disclosureindicator + h3{ - display: inline; - margin-left:6px; - cursor:default; -} -.notesBox .kd-zippycontent{ - height:100%; - overflow:hidden; - margin-bottom: 20px; - margin-left:16px; - background-color: #F5F5F5; - clear:both; -} -.notesBox .notes{ - width:320px; - float:left; - padding-top:10px; - padding-bottom:10px; - padding-left:16px; -} - -.notesBox h3{ -margin-bottom:10px; -margin-top:10px; -} - -.notesBox .metrics{ - width:320px; - float:left; - padding-top:10px; - padding-bottom:10px; - padding-left:16px; - -} - -.notesBox ul { - list-style:disc outside; - padding: 0 16px 16px; -} - -.notesBox ul li { - margin-bottom: 5px; -} - -/*------------------------------------------------------------------ -Grid -------------------------------------------------------------------*/ -#grid { - border-left: 44px solid rgba(255,255,0,0.1); - border-right: 44px solid rgba(255,255,0,0.1); - left: 0; - top: 0; - bottom: 0; - z-index: 100; - -webkit-box-sizing: content-box; - overflow: hidden; -} -html.x-expand #grid { - border-left: 72px solid rgba(255,255,0,0.05); - border-right: 72px solid rgba(255,255,0,0.05); -} -.gridline { - width: 72px; - height: 117px; - background-color: rgba(0,0,127,0.04); - border-left: 28px solid rgba(0,0,127,0.01); - border-right: 28px solid rgba(0,0,127,0.01); - margin-right: 16px; - float: left; - -webkit-box-sizing: border-box; -} -.gridline-right { - float: right; - margin-right: 0; - margin-left: 16px; -} -.gridfill { - background: red; -} - -/*------------------------------------------------------------------ -Component: Typography -------------------------------------------------------------------*/ -.productName{ - font-size: 20px; - line-height: 24px; - color: #DD4B39; -} -.title{ - color:#1155CC; - font-weight:normal; -} -.greytext{ - color:#777777; -} -.bodylink{ - color:#1155CC; -} -.searchlink{ - color:#1122CC; -} -.visitedlink{ - color:#6611CC; -} -.redlink{ - color:#DD4B39; -} -.secondary{ - font-size:11px; - color:#777777; -} -.secondary.nonLatin{ - font-size:12px; - color:#777777; -} -.source{ - color:#009933; -} - -#typography p { - line-height: 170%; - margin-bottom: 0; -} - -/*------------------------------------------------------------------ -Component: Colors -------------------------------------------------------------------*/ -#colorTable { - border-left:1px solid #ebebeb; - border-bottom:1px solid #ebebeb; -} -#colorTable th{ - background:#f5f5f5; - border:1px solid #e5e5e5; - border-right:1px solid #e5e5e5; - border-top:1px solid #e5e5e5; - font-weight:bold; - color:#222; -} -#colorTable td, #colorTable th{ - text-align:left; - border-top:1px solid #ebebeb; - border-right:1px solid #ebebeb; - padding:4px 4px; -} -.colorBlock { - color: #FFF; - font-weight: bold; -} -.colorBlock.dark { - color: #222; -} -.colorBlock span { - text-align: left; - display: inline-block; - width: 100%; -} -.colorBlock:first-child { - margin-left: 0; -} - - -/* Background Color Changer */ -#bgColorChanger{ - display:block; - position: relative; - width:250px; - margin-bottom:40px; - - background: #FFF; - outline: 1px solid rgba(0,0,0,0.2); - -webkit-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - box-shadow: 0 2px 4px rgba(0,0,0,0.2); - padding: 16px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -#bgColorChanger .title { - padding-right:10px; -} - -#otherColor{ - display:none; - width:auto; - margin-top:16px; -} -#otherColor input[type=text]{ - width:auto; -} -#otherColor ul li, #otherColor label{display:inline-block; margin-bottom:0;} -#otherColor ul li{margin-left:8px;} -#otherColor ul li:first-child{margin-left:0;} -#otherColor .kd-errormessage{display:block; position:absolute; top:35px; left:141px; text-align:right; display:none;} - -/*------------------------------------------------------------------ -Component: Horizontal Rules -------------------------------------------------------------------*/ -.whiteBox,.greyBox { - padding: 16px 0; - margin-bottom: 16px; -} -.greyBox { - background: #f1f1f1; -} -.kd-ruledBox { - width: 100%; -} -.kd-greyRuled { - border-top: 1px solid #e5e5e5; -} -.kd-whiteRuled { - border-top: 1px solid #ebebeb; -} - -/*------------------------------------------------------------------ -Component: Shadows -------------------------------------------------------------------*/ -.shadowList{ - padding:16px; - list-style:disc inside; -} -.shadowList > li{ - margin-bottom:16px; - position:relative; -} -.shadowList .kd-modaldialog{ - display:block; - position:relative; - top:0; - left:0; - opacity:1; - margin:16px 0; -} - -/*------------------------------------------------------------------ -Component: Search Bar (Google Bar) -------------------------------------------------------------------*/ -#kd-searchbar, -#kd-googlebar{ - position:relative; - background:#f1f1f1; - height:29px; - padding:21px 0; - border-bottom:1px solid #e5e5e5; - z-index:40; -} -#kd-googlebar.alternate{ - z-index:30; -} - -/* Search area */ -#kd-search { - position:absolute; - left:220px; - right:308px; - bottom:21px; - max-width:600px; - height:29px; -} -#kd-searchfield { - position:absolute; - left:0; - right:88px; - margin:0; - font-size:16px; - color:#000; -} -::-webkit-input-placeholder{ - color:#999; -} -#kd-searchfield:-moz-placeholder, input:-moz-placeholder{ - color:#999; -} -#kd-searchbutton { - position:absolute; - top:0; - right:0; -} -#kd-searchbutton img { - opacity:1; -} -#kd-googlebar.alternate #kd-search { - left:414px; - max-width:406px; -} -.kd-googlebuttonbar .kd-button{ - min-width:0; - width:28px; -} -.kd-googlebuttonbar .kd-button .maskedIcon{ - background:#7b7b7b; - display:inline-block; - width:21px; - height:21px; - margin:4px 0 0; -} -.kd-googlebuttonbar .kd-button:hover .maskedIcon, .kd-googlebuttonbar .kd-button:active .maskedIcon, .kd-googlebuttonbar .kd-button.selected .maskedIcon{ - background:#DD4B39; -} -.kd-googlebuttonbar .kd-button .maskedIcon img{visibility:hidden;} -.kd-googlebuttonbar .kd-button .maskedIcon.icon_images{ - -webkit-mask-image:url('../images/icons/corpus-images.png'); -} -.kd-googlebuttonbar .kd-button .maskedIcon.icon_shopping{ - -webkit-mask-image:url('../images/icons/corpus-shopping.png'); -} -.kd-googlebuttonbar .kd-button .maskedIcon.icon_search{ - -webkit-mask-image:url('../images/icons/corpus-search.png'); -} -.kd-googlebuttonbar .kd-button .maskedIcon.icon_news{ - -webkit-mask-image:url('../images/icons/corpus-news.png'); -} -/*.kd-googlebuttonbar .kd-button .maskedIcon.icon_images{ - -webkit-mask-image:url('../images/icons/svg/Search/images.svg'); -} -.kd-googlebuttonbar .kd-button .maskedIcon.icon_shopping{ - -webkit-mask-image:url('../images/icons/svg/Search/shopping.svg'); -} -.kd-googlebuttonbar .kd-button .maskedIcon.icon_search{ - -webkit-mask-image:url('../images/icons/svg/Search/everything.svg'); -} -.kd-googlebuttonbar .kd-button .maskedIcon.icon_news{ - -webkit-mask-image:url('../images/icons/svg/Search/news.svg'); -}*/ -.kd-googlebuttonbar.kd-segmentedcontrol{ - display:inline-block; - float:none; - margin-left:0; -} - -/* Social controls */ -#kd-social .kd-name { - float:left; - font-size:12px; - font-weight:bold; - line-height: 29px; - color: #666; -} -#kd-social .kd-notifications { - width:27px; - min-width:27px; - margin-left:9px; - font-size:14px; - font-weight:bold; -} -#kd-social .kd-share { - position:relative; - padding-left:2px; - margin-left:7px; - border-color:transparent; - background:#dcdcdc; -} -#kd-social .kd-share:hover { - border-color:#b0b0b0; -} -#kd-social .kd-share:after { - content:''; - display:block; - position:absolute; - top:9px; - right:-6px; - width:8px; - height:9px; - background:url('../images/social_share_nubbin.png') left 0px no-repeat; -} -#kd-social .kd-share:hover:after { - background-position:left -9px; -} -#kd-social .kd-share:active:after { - background-position:left -18px; -} -#kd-social .kd-avatar { - width:27px; - min-width:27px; - margin-left:11px; - padding:0; - border:1px solid rgba(0,0,0,0.3); - background-clip:border-box; - background:url('../images/profile_fpo_small.jpg') no-repeat; -} -#kd-social .kd-avatar:hover, -#kd-social .kd-avatar.hover { - border:1px solid rgba(0,0,0,0.4); -} -#kd-social .kd-avatar .kd-disclosureindicator { - position:relative; - right:-24px; - opacity:0.5; -} -#kd-social .kd-avatar:hover .kd-disclosureindicator { - opacity:1; -} - -/* Mobile variations */ -.mobile #kd-searchbar, -.mobile #kd-googlebar { - height:29px; - padding:14px 0; -} -.mobile #kd-searchbar .kd-buttonbar.right, -.mobile #kd-googlebar .kd-buttonbar.right{ - margin-right:7px; -} -.mobile #kd-searchbar #kd-social .kd-share, -.mobile #kd-googlebar #kd-social .kd-share{ - padding-left:0; - margin-left:9px; -} -.mobile #kd-searchbar #kd-social .kd-notifications, -.mobile #kd-googlebar #kd-social .kd-notifications{ - min-width:19px; - width:19px; -} -.mobile #kd-searchbar #kd-social .kd-share, -.mobile #kd-googlebar #kd-social .kd-share{ - min-width:19px; - width:19px; -} -.mobile #kd-searchbar #kd-social .kd-avatar, -.mobile #kd-googlebar #kd-social .kd-avatar{ - margin-left:9px; -} - -/*------------------------------------------------------------------ -Subcomponent: App Switcher -------------------------------------------------------------------*/ -.kd-appswitcher { - position:relative; - top:-21px; - width:160px; - height:71px; - margin:0 0 0 44px; - float:left; -} -.kd-appswitcher .logo { - display:block; - width:160px; - height:71px; - cursor:pointer; -} -.kd-appswitcher .logo img { - display:block; - margin-top:1px; - width:117px; - height:71px; - float:left; - image-rendering:optimizeQuality; -} -.kd-appswitcher .logo .kd-disclosureindicator { - display:block; - position:relative; - top:50%; - float:left; - margin-top:-2px; - margin-left:6px; - background-position:0 0; - opacity:0.3; -} -.kd-appswitcher:hover .logo .kd-disclosureindicator { - opacity:1; -} -/*.kd-appswitcher.open .logo .kd-disclosureindicator { - opacity:0; - background-position:7px 0; - -webkit-transition-property:opacity, background-position; - -webkit-transition-duration:0.218s; - -webkit-transition-delay:0s; - -webkit-transition-timing-function:linear, ease-out; - -moz-transition-property:opacity, background-position; - -moz-transition-duration:0.218s; - -moz-transition-delay:0s; - -moz-transition-timing-function:linear, ease-out; - transition-property:opacity, background-position; - transition-duration:0.218s; - transition-delay:0s; - transition-timing-function:linear, ease-out; -}*/ -.kd-appswitcher.open span.logo { - cursor:default; -} - -.kd-appswitcher-menu { - position:absolute; - top:71px; - left:-4000px; - max-height:44px; - margin-top:-10px; - - background:#2d2d2d; - border-bottom:1px solid #686868; - - -webkit-box-shadow: 2px 2px 5px rgba(0,0,0,0.2); - -moz-box-shadow: 2px 2px 5px rgba(0,0,0,0.2); - box-shadow: 2px 2px 5px rgba(0,0,0,0.2); - - z-index:9999; - opacity:0; -} -.kd-appswitcher.open .kd-appswitcher-menu { - left:-18px; - max-height:400px; - opacity:1; - margin-top:0; -} -.kd-appswitcher-menu:before { - content:""; - display:block; - position:absolute; - top:-12px; - left:133px; - margin-left:-1px; - border-style:solid; - border-color:#777 transparent; - border-width:0 12px 12px; - z-index:20; -} -.kd-appswitcher-menu:after { - content:""; - display:block; - position:absolute; - top:-11px; - left:133px; - border-style:solid; - border-color:#2d2d2d transparent; - border-width:0 11px 11px; - z-index:21; -} -.kd-app { - width:192px; - height:43px; - border-top:1px solid #7d7d7d; -} -.kd-app:first-child { - border-top-color:#2d2d2d; -} -.kd-app > a { - display:block; - width:135px; - height:43px; - line-height:43px; - padding-left:57px; - background-position:12px center; - background-repeat:no-repeat; - color:#fff; -} -.kd-app:hover > a, -a.logo:hover + .kd-appswitcher-menu .kd-app-search > a { - background-color:#4c4c4c; -} -.kd-app-double > a { - height:34px; - padding-top:9px; - line-height:13px; -} -.app-caption { - font-size:10px; - color:rgba(255,255,255,0.5); -} -.kd-app-search > a { background-image:url('../images/more_menu_search.png'); } -.kd-app-plus > a { background-image:url('../images/apps/plus.jpg'); } -.kd-app-calendar > a { background-image:url('../images/apps/calendar.png'); } -.kd-app-maps > a { background-image:url('../images/apps/maps.png'); } -.kd-app-reader > a { background-image:url('../images/apps/reader.png'); } -.kd-app-docs > a { background-image:url('../images/apps/docs.png'); } -.kd-app-mail > a { background-image:url('../images/apps/mail.png'); } -.kd-app-more > a { padding-left:16px; width:176px; } - -.kd-app-search-everything > a { background-image:url('../images/more_menu_search_everything.png'); } -.kd-app-search-images > a { background-image:url('../images/more_menu_search_images.png'); } -.kd-app-search-video > a { background-image:url('../images/more_menu_search_video.png'); } -.kd-app-search-news > a { background-image:url('../images/more_menu_search_news.png'); } -.kd-app-search-shopping > a { background-image:url('../images/more_menu_search_shopping.png'); } -.kd-app-search-books > a { background-image:url('../images/more_menu_search_books.png'); } -.kd-app-search-places > a { background-image:url('../images/more_menu_search_places.png'); } -.kd-app-search-blogs > a { background-image:url('../images/more_menu_search_blogs.png'); } - -.kd-app-plus-home > a { background-image:url('../images/more_menu_plus_home.png'); } -.kd-app-plus-profile > a { background-image:url('../images/more_menu_plus_profile.png'); } -.kd-app-plus-photos > a { background-image:url('../images/more_menu_plus_photos.png'); } -.kd-app-plus-circles > a { background-image:url('../images/more_menu_plus_circles.png'); } -.kd-app-plus-hangouts > a { background-image:url('../images/more_menu_plus_hangouts.png'); } -.kd-app-plus-games > a { background-image:url('../images/more_menu_plus_games.png'); } - -.kd-app-youtube > a { background-image:url('../images/more_menu_youtube.png'); } -.kd-app-photos > a { background-image:url('../images/more_menu_picasa.png'); } -.kd-app-sites > a { background-image:url('../images/more_menu_sites.png'); } -.kd-app-groups > a { background-image:url('../images/more_menu_groups.png'); } -.kd-app-earth > a { background-image:url('../images/more_menu_earth.png'); } -.kd-app-voice > a { background-image:url('../images/more_menu_voice.png'); } -.kd-app-blogger > a { background-image:url('../images/more_menu_blogger.png'); } -.kd-app-talk > a { background-image:url('../images/more_menu_talk.png'); } -.kd-app-igoogle > a { background-image:url('../images/more_menu_igoogle.png'); } -.kd-app-directory > a { background-image:url('../images/more_menu_directory.png'); } -.kd-app-chrome > a { background-image:url('../images/more_menu_chrome.png'); } -.kd-app-toolbar > a { background-image:url('../images/more_menu_toolbar.png'); } -.kd-app-bookmarks > a { background-image:url('../images/more_menu_bookmarks.png'); } -.kd-app-latitude > a { background-image:url('../images/more_menu_latitude.png'); } -.kd-app-panoramio > a { background-image:url('../images/more_menu_panoramio.png'); } -.kd-app-checkout > a { background-image:url('../images/more_menu_checkout.png'); } -.kd-app-translate > a { background-image:url('../images/more_menu_translate.png'); } -.kd-app-sketchup > a { background-image:url('../images/more_menu_sketchup.png'); } -.kd-app-pack > a { background-image:url('../images/more_menu_pack.png'); } -.kd-app-health > a { background-image:url('../images/more_menu_health.png'); } -.kd-app-fusiontables > a { background-image:url('../images/more_menu_fusiontables.png'); } -.kd-app-labs > a { background-image:url('../images/more_menu_labs.png'); } -.kd-app-code > a { background-image:url('../images/more_menu_code.png'); } - -.kd-more-menu { - position:absolute; - top:0; - bottom:-1px; - left:-1000%; - width:0; - overflow:hidden; - - background:#fff; - border:1px solid #e5e5e5; - - -webkit-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - box-shadow: 0 2px 4px rgba(0,0,0,0.2); -} -.kd-app:hover > .kd-more-menu, -.kd-app .kd-more-menu.open { - width:192px; - left:100%; -} -.kd-more-menu .kd-more-container { - position:absolute; - top:0; - right:0; - width:192px; -} -.kd-more-container ul{ - float:left; -} -.kd-appswitcher-menu .kd-app-more:hover .kd-more-menu, -.kd-appswitcher-menu .kd-app-more .kd-more-container { - width:576px; -} -.kd-more-menu .kd-app { border-top:1px solid #e5e5e5; } -.kd-more-menu .kd-app:first-child { border-top:none; } -.kd-more-menu .kd-app:hover > a { background-color:rgba(0,0,0,0.05); } - -.kd-more-menu .kd-app > a { color:#2d2d2d; } - - -.mobile .kd-appswitcher { - position:absolute; - top:0; - left:0; - margin:0 0 0 16px; - float:none; - width:120px; - height:57px; -} -.mobile .kd-appswitcher .kd-appswitcher-menu { top:57px; } -.mobile .kd-appswitcher.open .kd-appswitcher-menu { left:-10px; } - -.mobile .kd-appswitcher .kd-appswitcher-menu:before { - top:-8px; - left:15px; - border-width:0 8px 8px; -} -.mobile .kd-appswitcher .kd-appswitcher-menu:after { - top:-7px; - left:15px; - border-width:0 7px 7px; -} -.mobile .kd-appswitcher .logo { width:120px; height:60px; } -.mobile .kd-appswitcher .logo img { width:99px; height:60px; } - -.mobile .kd-more-menu { left:-9999px; } -.mobile .kd-appswitcher-menu .kd-app-more .kd-more-container { width:192px; } - -.mobile .kd-app:hover > .kd-more-menu, -.mobile .kd-app .kd-more-menu.open { - width:192px; - left:50px; -} - -/*------------------------------------------------------------------ -Component: Sidebars -------------------------------------------------------------------*/ -#styleguide #sidebars { - overflow: visible; - height: 544px; -} -.sidebarHolder { - width: 220px; - float: left; -/* border-left:1px solid #ebebeb; - border-right:1px solid #ebebeb;*/ -} -.sidebarHolder h4 { - padding: 16px 0; -} - -.kd-content-sidebar { - width:160px; - padding:16px 0px 16px 44px; - border-left:1px solid #ebebeb; -} -.kd-content-sidebar li { - position:relative; - margin-left: -16px; - border-bottom:1px solid transparent; -} -.kd-content-sidebar li a { - display: block; - line-height: 29px; - color: #333; - font-size: 13px; - cursor:default; -} - -.kd-content-sidebar .kd-zippy .row a { - margin-left: 16px; -} -.kd-content-sidebar li, -.kd-content-sidebar ul ul{ - margin-left:28px; -} -.kd-content-sidebar ul ul li, -.kd-content-sidebar ul ul li a{ - line-height:19px; -} -.kd-content-sidebar ul ul li a{ - padding-left: 12px; - margin-left: 32px; -} -.kd-content-sidebar ul ul li .kd-disclosureindicator{ - top:0; - height:19px; -} -.kd-content-sidebar ul ul li:hover .kd-disclosureindicator{ -/* height:16px;*/ -} -.kd-content-sidebar li.selected .kd-disclosureindicator, -.kd-disclosureindicator.down { -} - -.kd-content-sidebar li .kd-disclosureindicator { - position: relative; - display: block; - float: left; - width:15px; - height:29px; - background-position:center; - margin-left:-1px; - opacity: 0.8; - cursor:default; -} -.kd-content-sidebar li:hover > .kd-disclosureindicator { - opacity: 1.0; -} - -.kd-content-sidebar ul > li > a { - padding-left: 16px; -} - -.kd-content-sidebar ul > li > a:hover { - background-color: #eee; -} -.kd-content-sidebar span.row { - display: block; -} -.kd-content-sidebar span.row.split:hover { - background-color: transparent; -} - -.kd-content-sidebar span.row:hover, -.kd-content-sidebar .kd-zippycontent li a:hover, -.kd-content-sidebar span.row.split a:hover, -.kd-content-sidebar span.row.split .kd-disclosureindicator:hover { - background-color: #eee; - color: #222; -} - -.kd-content-sidebar .kd-zippy span.row:hover .kd-disclosureindicator, -.kd-content-sidebar .kd-zippy span.row.split .kd-disclosureindicator:hover { - opacity: 1.0; -} - -.kd-content-sidebar li.selected a { - color: #d14836; -} -ul.iconlist li a, li.kd-labellistitem a { - background-position: 25px 50%; - background-repeat: no-repeat; -} -li.kd-labellistitem.selected a{ - background-position:20px 50%; -} -ul.iconlist li.kd-sidebarlistitem a{ - background-position: 44px 50%; - padding-left:75px; -} -ul.iconlist li.kd-sidebarlistitem.selected a{ - background-position: 39px 50%; - padding-left:70px; -} -.kd-menulabel{ - position:absolute; - height:11px; - width:11px; - top:11px; - right:11px; - cursor:default; - border-radius:1px; - -moz-border-radius:1px; - -webkit-border-radius:1px; -} -.kd-menulabel.red{ - background:#DD4B39; -} -.kd-menulabel.grey{ - background:#999999; -} -.kd-menulabel.blue{ - background:#4D90F0; -} - -/* Flyout triggers */ -.kd-flyouttrigger.clear { - border:1px solid #b5b5b5; - background:url('/assets/images/disclosure_arrow_md_grey_down.png') center no-repeat; -} -.kd-flyouttrigger.clear:hover, .kd-flyouttrigger.clear.selected{ - border-color:#666; - background:url('../images/disclosure_arrow_dk_grey_444_down.png') center no-repeat #DDD; -} -.kd-flyouttrigger:hover, .kd-flyouttrigger.selected{ - background-image:url('../images/disclosure_arrow_down_white.png'); - background-position:center; - background-repeat:no-repeat; -} - -.kd-flyouttrigger .kd-menulist{ - position:absolute; - display:none; - left:0px; - top:100%; - z-index:3; -} -.kd-content-sidebar .kd-menulist li{ - margin-left:0; -} -.kd-flyouttrigger.selected .kd-menulist{ - display:block; -} -.kd-flyouttrigger.selected .kd-menulist.clip{ - overflow-y:auto; -} -/*sidebars - extended hover and selected states*/ -.kd-content-sidebar .kd-sidebarlistitem{ - margin-left:-44px; -} -.kd-content-sidebar .kd-sidebarlistitem > a{ - padding-left:44px; -} -.kd-content-sidebar .kd-sidebarlistitem.selected > a/*, .kd-content-sidebar .kd-sidebarlistitem.kd-zippy.expanded > .row*/{ - border-left:5px solid #999; - padding-left:39px; -} -.kd-content-sidebar .kd-sidebarlistitem > .row{ - padding-left:28px; -} -/*.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.expanded > .row{ - padding-left:23px; -}*/ -.kd-content-sidebar .selected .kd-disclosureindicator { - background-image: url('../images/disclosure_arrow_orange_rt.png'); -} -/*sidebar zippy*/ -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy .kd-zippycontent{ - margin-left:29px; -} - -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split:hover .row{ - background-color:transparent; -} -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split .row{ - padding-left:0; -} -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split .kd-disclosureindicator{ - padding-left:28px; - background-position:34px center; - margin-left:0; -} - -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split .kd-disclosureindicator{ - width:13px; - border-right:1px solid #FFF; -} -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split .label > a{ - margin-left:41px; - padding-left:3px; -} -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split .kd-disclosureindicator:hover, -/*.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split .kd-disclosureindicator.down,*/ -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split .label:hover{ - background-color:#EEE; - color: #222; -} -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split .label{ - display:block; -} -.kd-content-sidebar .kd-sidebarlistitem.kd-zippy.split .kd-disclosureindicator.down{ - background-position:32px center; -} - -/*Gmail*/ -li.kd-labellistitem a.kd-label-red { - background-image: url('../images/icons/label_red.png'); -} -li.kd-labellistitem a.kd-label-grey { - background-image: url('../images/icons/label_grey.png'); -} -li.kd-labellistitem a.kd-label-blue { - background-image: url('../images/icons/label_blue.png'); -} -.kd-button.compose { - width: 97px; -} - -/*------------------------------------------------------------------ -Component: App bars -------------------------------------------------------------------*/ -.kd-appbar { - position: relative; - padding: 21px 0; - border-bottom: 1px solid #ebebeb; - height: 66px; - z-index: 20; - background: #fff; -} -.kd-appbar .kd-appname { - width: 160px; - margin-right: 16px; - margin-left: 44px; - height: 29px; - float: left; - font-size: 20px; - font-weight: normal; - line-height: 29px; - color: #666; - white-space:nowrap; -} -.kd-appbar .kd-description { - height: 29px; - font-size: 20px; - font-weight: normal; - line-height: 29px; - padding-bottom: 8px; - color: #666; - white-space:nowrap; -} -.kd-appbar .kd-description .kd-value { - color: black; - font-weight: bold; -} -.kd-appbar .kd-description form { - display: inline; -} -.kd-appbar .kd-appname a { color: #666; cursor:pointer; } -#stickers .kd-appbar .kd-buttonbar { - margin-bottom: 0; -} -.kd-buttonbar{ - height:29px; - line-height:29px; -} -.kd-buttonbar.right { - float: right; - margin-right: 44px; -} -.kd-buttonbar.left { - float: left; -} -.kd-buttonbar span.kd-count, .kd-buttonbar span.kd-count strong { - line-height: 29px; - color: #666; -} -.kd-buttonbar.right span.kd-count { - float: left; -} -.kd-buttonbar.left span.kd-count { - float: right; - margin-left: 16px; -} -#styleguide .section .kd-appbar h4 { - margin-bottom: 16px; -} - -/* Maps (mini) app bar */ -.maps .kd-appbar { width:380px; } -.maps .kd-appbar .kd-appname { width:auto; } -.maps .kd-maps-collapser { - display:block; - position:absolute; - top:0; - bottom:0; - right:0; - width:15px; - line-height:71px; - vertical-align:middle; - text-align:center; - border: 1px solid #ebebeb; - border-width:0 1px; - background:#fff; - cursor:pointer; -} -.maps .kd-maps-collapser:hover { - background:#f1f1f1; -} - -/* Mobile app bar */ -.mobile .kd-appbar { - padding:7px 0; -} -.mobile .kd-appbar .kd-appname{ - width:auto; - margin-left:16px; - margin-right:7px; - - font-size:16px; -} -.mobile .kd-appbar .kd-appname.arrowed:before { - display:inline-block; - content:"‹"; - text-align:right; - width:12px; - margin:0 4px 0 -16px; -} -.mobile .kd-appbar .kd-buttonbar.right{ - margin-right:7px; -} -.mobile .kd-appbar .kd-button-action img, -.mobile .kd-appbar .kd-button-share img, -.mobile .kd-appbar .kd-button-submit img{ - opacity:1; -} -.mobile .kd-appbar .kd-button.mid { margin-left:-1px; } -.mobile .kd-appbar .kd-button.right { margin-left:-1px; } -.mobile .kd-appbar .kd-button:first-child { margin-left:0; } -.mobile .kd-appbar .cancel-button{ - display:inline-block; - height:27px; - width:34px; - line-height:27px; - padding:4px 0; - text-align:center; - margin-left:6px; - margin-right:-6px; -} -.mobile .kd-appbar .cancel-button img{ - opacity:.667; -} - -/*------------------------------------------------------------------ -Component: Toolbar -------------------------------------------------------------------*/ -.kd-toolbar { - height: 29px; - background: #f1f1f1; - border-top: 1px solid #e5e5e5; - border-bottom: 1px solid #ebebeb; - margin-bottom: 44px; - padding: 8px 44px 4px; -} -.kd-toolbar .kd-select .kd-disclosureindicator{ - margin-top:7px; -} -.kd-toolbarbutton { - border-color: transparent; - background: 0; -} -.kd-toolbar .kd-button{ - margin-left:0; -} -.kd-toolbar .kd-button.right{ - margin-left:0; -} -.kd-toolbarbutton.small, .kd-toolbar .kd-button.small{ - width:24px; - min-width:24px; -} -.kd-toolbarbutton, .kd-toolbar .kd-button{ - height:24px; - line-height:24px; -} -.kd-toolbar .kd-menubutton.small{ - width:34px; -} -.kd-toolbar .kd-button{ - min-width:0; -} -.kd-toolbarbutton:hover { - border: 1px solid #C6C6C6; - color: #333; - background-color: #f8f8f8; - background-image: -webkit-gradient(linear,left top,left bottom,from(#f8f8f8),to(#f1f1f1)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: linear-gradient(top,#f8f8f8,#f1f1f1); - -webkit-box-shadow: 0px 1px 1px rgba(0,0,0,0.1); - -moz-box-shadow: 0px 1px 1px rgba(0,0,0,0.1); - box-shadow: 0px 1px 1px rgba(0,0,0,0.1); -} -.kd-toolbarbutton:active { - background-color: #f6f6f6; - background-image: -webkit-gradient(linear,left top,left bottom,from(#f6f6f6),to(#f1f1f1)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#f6f6f6,#f1f1f1); - /* @alternate */ background-image: -moz-linear-gradient(top,#f6f6f6,#f1f1f1); - /* @alternate */ background-image: -ms-linear-gradient(top,#f6f6f6,#f1f1f1); - /* @alternate */ background-image: -o-linear-gradient(top,#f6f6f6,#f1f1f1); - /* @alternate */ background-image: linear-gradient(top,#f6f6f6,#f1f1f1); - -webkit-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); -} -.kd-toolbarbutton:visited { - color: #666; -} -.kd-toolbarbutton.focus { - outline: none; - border: 1px solid #4d90fe; -} - -.kd-toolbarbutton.selected, .kd-toolbar .kd-menubutton.selected { - background-color: #EEEEEE; - background-image: -webkit-gradient(linear,left top,left bottom,from(#EEEEEE),to(#E0E0E0)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#EEEEEE,#E0E0E0); - /* @alternate */ background-image: -moz-linear-gradient(top,#EEEEEE,#E0E0E0); - /* @alternate */ background-image: -ms-linear-gradient(top,#EEEEEE,#E0E0E0); - /* @alternate */ background-image: -o-linear-gradient(top,#EEEEEE,#E0E0E0); - /* @alternate */ background-image: linear-gradient(top,#EEEEEE,#E0E0E0); - -webkit-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - border: 1px solid #CCC; - color: #333; -} - -.kd-toolbar .kd-select, -.kd-toolbar .kd-menubutton { -/* background: #fdfdfd;*/ - border-color:transparent; -} -.kd-toolbar .kd-select:hover, .kd-toolbar .kd-menubutton:hover{ - border: 1px solid #C6C6C6; -} - -.kd-toolbarseparator { - display: inline-block; - float: left; - height: 17px; - margin: 5px 6px 0 6px; - border-left: 1px solid #CCC; -} -.kd-toolbarseparator.no-margin{ - margin:5px 0 0 0; -} -.buttongroup{ - margin:0 6px; - float:left; -} -.buttongroup.first{ - margin-left:0; -} -.kd-toolbarseparator + .kd-select.kd-menubutton { - margin-left: -1px; -} -.kd-select.kd-menubutton + .kd-toolbarseparator { - margin-left: -1px; -} -.kd-toolbar .kd-select.kd-menubutton { - background-color: transparent; - background-image: none; -} - -/*------------------------------------------------------------------ -Component: Tabs -------------------------------------------------------------------*/ -#stickersheet .kd-tabbar-horz { - margin-bottom: 40px; -} -.kd-tabbar-horz { - border-bottom: 1px solid #ccc; - height: 28px; -} -.kd-tabbar-vert { - border-right: 1px solid #ccc; - display: inline-block; - width: 71px; - height: 100%; -} -.kd-tabbutton { - display: inline-block; - min-width: 54px; - text-align: center; - color: #666; - font-size: 11px; - font-weight: bold; - height: 27px; - padding: 0 8px; - line-height: 27px; - -webkit-user-select:none; - -moz-user-select:none; - cursor:default; - - border: 1px solid transparent; -} - -.kd-tabbutton:hover { - color: #222; -} - -.kd-tabbutton:active { - color: #333; -} - -.kd-tabbutton.selected { - color: #202020; - border: 1px solid #ccc; -} - -.kd-tabbar-horz .kd-tabbutton { - -webkit-border-top-left-radius:2px; - -webkit-border-top-right-radius:2px; - -moz-border-radius-topleft: 2px; - -moz-border-radius-topright: 2px; - border-top-left-radius: 2px; - border-top-right-radius: 2px; -} - -.kd-tabbar-vert .kd-tabbutton { - -webkit-border-top-left-radius:2px; - -webkit-border-bottom-left-radius:2px; - -moz-border-radius-topleft: 2px; - -moz-border-radius-bottomleft: 2px; - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; -} - -.kd-tabbar-horz .kd-tabbutton.selected { - border-bottom: 1px solid #fff; - -} - -.kd-tabbar-vert .kd-tabbutton.selected { - border-right: 1px solid #fff; -} - -/*------------------------------------------------------------------ -Component: Buttons -------------------------------------------------------------------*/ -.kd-button { - display: inline-block; - min-width: 54px; - border:1px solid #DCDCDC; - /* @alternate */ border: 1px solid rgba(0,0,0,0.1); - text-align: center; - color: #444; - font-size: 11px; - font-weight: bold; - height: 27px; - padding: 0 8px; - line-height: 27px; - -webkit-border-radius:2px; - -moz-border-radius: 2px; - border-radius: 2px; - background-color: #f5f5f5; - background-image: -webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#f1f1f1)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1); - /* @alternate */ background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1); - /* @alternate */ background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1); - /* @alternate */ background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1); - /* @alternate */ background-image: linear-gradient(top,#f5f5f5,#f1f1f1); - -webkit-user-select:none; - -moz-user-select:none; - cursor:default; -} -.kd-button:hover, .kd-button.hover { - border: 1px solid #C6C6C6; - color: #222; - background-color: #f8f8f8; - background-image: -webkit-gradient(linear,left top,left bottom,from(#f8f8f8),to(#f1f1f1)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: linear-gradient(top,#f8f8f8,#f1f1f1); - -webkit-box-shadow: 0px 1px 1px rgba(0,0,0,0.1); - -moz-box-shadow: 0px 1px 1px rgba(0,0,0,0.1); - box-shadow: 0px 1px 1px rgba(0,0,0,0.1); -} -.kd-button:active, .kd-button.active { - background-color: #f6f6f6; - background-image: -webkit-gradient(linear,left top,left bottom,from(#f6f6f6),to(#f1f1f1)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#f6f6f6,#f1f1f1); - /* @alternate */ background-image: -moz-linear-gradient(top,#f6f6f6,#f1f1f1); - /* @alternate */ background-image: -ms-linear-gradient(top,#f6f6f6,#f1f1f1); - /* @alternate */ background-image: -o-linear-gradient(top,#f6f6f6,#f1f1f1); - /* @alternate */ background-image: linear-gradient(top,#f6f6f6,#f1f1f1); - -webkit-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); -} -.kd-button.active{ - border: 1px solid #C6C6C6; - color: #333; -} - -.kd-button:visited { - color: #666; -} -.kd-button.focus, .kd-button.right.focus, .kd-button.mid.focus, .kd-button.left.focus{ - outline: none; - border: 1px solid #4d90fe; - z-index:4 !important; -} - -.kd-button.selected { - background-color: #EEEEEE; - background-image: -webkit-gradient(linear,left top,left bottom,from(#EEEEEE),to(#E0E0E0)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#EEEEEE,#E0E0E0); - /* @alternate */ background-image: -moz-linear-gradient(top,#EEEEEE,#E0E0E0); - /* @alternate */ background-image: -ms-linear-gradient(top,#EEEEEE,#E0E0E0); - /* @alternate */ background-image: -o-linear-gradient(top,#EEEEEE,#E0E0E0); - /* @alternate */ background-image: linear-gradient(top,#EEEEEE,#E0E0E0); - -webkit-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - border: 1px solid #CCC; - color: #333; -} -.kd-button input[type=checkbox] { - position: relative; - top: 3px; -} - -.kd-button img { - display: inline-block; - margin: -3px 0 0; - opacity: 0.55; - margin-left: 0px; - margin-right: 0px; - vertical-align: middle; -} - -.kd-button.selected img { - opacity: 0.9; -} -.kd-button:hover img { - opacity: 0.72; -} -.kd-button:active img { - opacity: 1.0; -} - -/* Disabled buttons */ -.kd-button.disabled, .kd-button.disabled:hover, .kd-button.disabled:active { - background: none; - color: #b8b8b8; - border: 1px solid #f3f3f3; - /* @alternate */ border: 1px solid rgba(0,0,0,0.05); - cursor: default; - pointer-events: none; -} -.kd-button.disabled.active{ - -webkit-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); -} -.kd-button-submit.disabled, .kd-button-submit.disabled:hover, .kd-button-submit.disabled:active, -.kd-button-share.disabled, .kd-button-share.disabled:hover, .kd-button-share.disabled:active, -.kd-button-action.disabled, .kd-button-action.disabled:hover, .kd-button-action.disabled:active { - border: 1px solid #505050; - background-color: #666; - color: #FFF; - opacity: 0.5; -} -.kd-button.disabled img { - opacity: 0.5; -} - -/* Colored Buttons */ -.kd-button-submit:focus, .kd-button-submit.focus, -.kd-button-share:focus, .kd-button-share.focus, -.kd-button-action:focus, .kd-button-action.focus{ - box-shadow:inset 0 0 0 1px rgba(255,255,255,0.5); - -webkit-box-shadow:inset 0 0 0 1px rgba(255,255,255,0.5); - -moz-box-shadow:inset 0 0 0 1px rgba(255,255,255,0.5); -} -.kd-button-submit:focus, .kd-button-submit.focus, -.kd-button-share:focus, .kd-button-share.focus, -.kd-button-action:focus, .kd-button-action.focus { - border-color:#404040; -} - -.kd-button-submit:focus:hover, .kd-button-submit.focus:hover, -.kd-button-share:focus:hover, .kd-button-share.focus:hover, -.kd-button-action:focus:hover, .kd-button-action.focus:hover{ - box-shadow:inset 0 0 0 1px #fff, 0px 1px 1px rgba(0,0,0,0.1); - -webkit-box-shadow:inset 0 0 0 1px #fff, 0px 1px 1px rgba(0,0,0,0.1); - -moz-box-shadow:inset 0 0 0 1px #fff, 0px 1px 1px rgba(0,0,0,0.1); -} - -.kd-button-submit, -.kd-button-share, -.kd-button-action { - border: 1px solid #505050; - color: #FFF; - background-color: #666; - background-image: -webkit-gradient(linear,left top,left bottom,from(#777),to(#555)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#777,#555); - /* @alternate */ background-image: -moz-linear-gradient(top,#777,#555); - /* @alternate */ background-image: -ms-linear-gradient(top,#777,#555); - /* @alternate */ background-image: -o-linear-gradient(top,#777,#555); - /* @alternate */ background-image: linear-gradient(top,#777,#555); -} -.kd-button-submit:hover, -.kd-button-share:hover, -.kd-button-action:hover { - border: 1px solid #404040; - color: #FFF; - background-color: #555; - background-image: -webkit-gradient(linear,left top,left bottom,from(#666),to(#444)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#666,#444); - /* @alternate */ background-image: -moz-linear-gradient(top,#666,#444); - /* @alternate */ background-image: -ms-linear-gradient(top,#666,#444); - /* @alternate */ background-image: -o-linear-gradient(top,#666,#444); - /* @alternate */ background-image: linear-gradient(top,#666,#444); -} -.kd-button-submit:active, .kd-button-submit:focus:active, .kd-button-submit.focus:active, -.kd-button-share:active, .kd-button-share:focus:active, .kd-button-share.focus:active, -.kd-button-action:active, .kd-button-action:focus:active, .kd-button-action.focus:active { - -webkit-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.3); - -moz-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.3); - box-shadow: inset 0px 1px 2px rgba(0,0,0,0.3); -} - -.kd-button-share { - text-shadow: 0px 1px rgba(0,0,0,0.1); -} -.kd-button-share:hover { - text-shadow: 0px 1px rgba(0,0,0,0.3); -} -.kd-button-action { - margin-bottom: 16px; - text-transform: uppercase; - letter-spacing:1; - text-shadow: 0px 1px rgba(0,0,0,0.1); -} -.kd-button-action:hover { - -webkit-box-shadow: 0px 1px 1px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 1px 1px rgba(0,0,0,0.2); - box-shadow: 0px 1px 1px rgba(0,0,0,0.2); -} -.kd-button-action:visited, -.kd-button-share:visited, -.kd-button-submit:visited { - color: #FFF; -} -.kd-button.kd-button-action img, -.kd-button.kd-button-action.selected img, -.kd-button.kd-button-action:hover img, -.kd-button.kd-button-action:active img, -.kd-button.kd-button-submit img, -.kd-button.kd-button-submit.selected img, -.kd-button.kd-button-submit:hover img, -.kd-button.kd-button-submit:active img, -.kd-button.kd-button-share img, -.kd-button.kd-button-share.selected img, -.kd-button.kd-button-share:hover img, -.kd-button.kd-button-share:active img { - opacity: 1.0; -} - -/* Disclosure indicator */ -.kd-disclosureindicator { - display: inline-block; - width: 5px; - height: 7px; - background: url('/assets/images/disclosure_arrow_dk_grey.png') center no-repeat; -} - -/* Buttons of all styles */ -.kd-buttonbar .kd-button, -.kd-buttonbar .kd-combobutton, -.kd-buttonbar .kd-expandbutton { - float: left; - margin: 0; - margin-right: 16px; - position: relative; - z-index: 1; -} -.left + .kd-combobutton{ - margin-left:0; -} - -.kd-buttonbar .kd-button:hover { - z-index: 2; -} - -.kd-button.small, -.mobile .kd-button.small { - min-width: 34px; - width: 34px; - padding: 0; -} -.mobile .kd-button { - min-width:30px; - width:30px; - padding:0 8px; - margin-left:7px; -} -.kd-menubutton { - position: relative; -} -.kd-menubutton .kd-disclosureindicator { - float: right; - margin-top: 10px; - margin-left: 7px; - opacity: .8; - -/* ie hacks*/ - *float:none; - *position:relative; - *top:-3px; -/* margin-top:12px\0/; */ -} -.kd-select { position:relative; } -.kd-select .kd-disclosureindicator{ - background:url('/assets/images/disclosure_arrow_dk_grey_up_down.png'); - width:7px; - height:11px; - margin-top:8px; -} - -.kd-menubutton.small img { - margin-left: -8px; -} -.kd-menubutton.small .kd-disclosureindicator { - position: absolute; - margin: 10px 0; - right: 4px; -} -.kd-menubutton .kd-menulist .kd-disclosureindicator { - float: none; - opacity: .8; -} -.kd-menubutton img + .label{ - margin-left:5px; -} - -.kd-menubutton img { - display: inline-block; -} -.kd-menubutton:hover .kd-disclosureindicator { - border-left-color: #999; - opacity: 1; -} -.kd-menubutton span.label { - display: inline-block; -} -.kd-combobutton .kd-menubutton:first-child { - -webkit-border-radius: 2px 0 0 2px; - -moz-border-radius: 2px 0 0 2px; - border-radius: 2px 0 0 2px; -} -.kd-combobutton .kd-menutrigger, -.mobile .kd-combobutton .kd-menutrigger { - margin-left: -1px; - border-left-color: transparent; - padding: 0 8px 0 2px; - width:auto; - min-width: 0; - -webkit-border-radius: 0 2px 2px 0; - -moz-border-radius: 0 2px 2px 0; - border-radius: 0 2px 2px 0; - z-index: 0; -} -.kd-combobutton .kd-menutrigger:hover { - border-left-color: #c6c6c6; -} - -.kd-expandbutton { - display: inline-block; - overflow: hidden; - z-index: 0; - width: 88px; - height: 29px; - position: relative; - cursor:pointer; -} -.kd-expandbutton:hover { - width: 210px; - margin-left: -100px; -} -.kd-expandbutton:hover .expand-options{ - border-color: #e5e5e5; -} -.kd-expandbutton .expand-options { - display: inline-block; - background: #f7f7f7; - border: 1px solid #f0f0f0; - padding-left: 16px; - -webkit-border-radius: 2px 0 0 2px; - -moz-border-radius: 2px 0 0 2px; - border-radius: 2px 0 0 2px; - position: absolute; - left: 0; - width: 144px; - font-size:11px; -} -.kd-expandbutton .expand-options span { - float:left; - padding: 0 8px; - line-height: 27px; - color:#666; -/* border-left:1px solid transparent;*/ -} - -.kd-expandbutton .expand-options span:hover, .kd-expandbutton .expand-options span.selected{ - background-color:#e5e5e5; - color: #222; -} -.kd-expandbutton .expand-options .kd-disclosureindicator { - position: absolute; - top: 50%; - margin-top: -3px; - left: -3px; - opacity: .5; -} -.kd-expandbutton .main { - z-index: 1; - position: absolute; - right: 0; -} -.kd-expandbutton:hover .kd-button.main{ - border: 1px solid #C6C6C6; - color: #333; - background-color: #f8f8f8; - background-image: -webkit-gradient(linear,left top,left bottom,from(#f8f8f8),to(#f1f1f1)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1); - /* @alternate */ background-image: linear-gradient(top,#f8f8f8,#f1f1f1); - -webkit-box-shadow: 0px 1px 1px rgba(0,0,0,0.1); - -moz-box-shadow: 0px 1px 1px rgba(0,0,0,0.1); - box-shadow: 0px 1px 1px rgba(0,0,0,0.1); -} - -/* Combo/segmented buttons */ -.kd-combobutton .kd-button-action.small { - margin: 0 0 0 1px; -} -.kd-button.left { - border-right-color: transparent; - margin-right: 0; - -webkit-border-radius: 2px 0 0 2px; - -moz-border-radius: 2px 0 0 2px; - border-radius: 2px 0 0 2px; -} -.kd-button.left:hover { - border-right: 1px solid #c6c6c6; -} -.kd-button.mid { - -webkit-border-radius: 0; - -moz-border-radius: 0; - border-radius: 0; - margin-left:0; - margin-right:0; -} -.kd-button.mid + .kd-button.mid, .kd-button.left + .kd-button.mid{ - margin-left: -1px; -} -.kd-button.right { - -webkit-border-radius: 0 2px 2px 0; - -moz-border-radius: 0 2px 2px 0; - border-radius: 0 2px 2px 0; - margin-left:-1px; -} -.kd-button.right:hover { - border-left: 1px solid #c6c6c6; -} -.kd-segmentedcontrol{ - float:left; - margin-left:16px; -} -.kd-segmentedcontrol:first-child{ - margin-left:0; -} -.kd-button.left.kd-button-action:hover { - border-right: 1px solid transparent; -} -.kd-button.right.kd-button-action:hover { - border-left: 1px solid transparent; -} - -/* Mini buttons */ -.kd-button.mini{ - height:17px; - line-height:17px; - min-width:0; -} -/* Mini text input */ -input[type="text"].mini{ - height:17px; - line-height:17px; - display:inline-block; - padding:0 2px; - -webkit-box-sizing:content-box; - font-size:11px; -} - -/* View toggle buttonset */ -.kd-viewtoggle{ - display:block; - height:29px; - position:relative; -} -.kd-viewtoggle .kd-button{ - position:absolute; - margin:0; -} -.kd-viewtoggle .kd-button.selected{ - z-index:3; -} -.kd-viewtoggle .tab{ - position: absolute; - top: 0; - right: 36px; - display:block; - height:27px; - width:16px; - background: url('../images/disclosure_arrow_lt_grey_left.png') center no-repeat #f7f7f7; - border: 1px solid #ebebeb; - -webkit-border-radius: 2px 0 0 2px; - -moz-border-radius: 2px 0 0 2px; - border-radius: 2px 0 0 2px; -} -.kd-viewtoggle.wide .tab{ - right:72px; -} - -.kd-viewtoggle:hover .tab{ - right:0; -} -.kd-viewtoggle .kd-button.selected{ - border-color:#CCC; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} - -/* Colored button bar */ -.kd-buttonbar-colored { - padding:10px; - height:19px; - background: #4D90FE; -} -.kd-buttonbar-colored span { - font-size: 13px; - font-weight: bold; - color: white; - float: left; - line-height: 19px; - height:19px; - background: #4D90FE; - text-shadow: 0px 1px 0px rgba(0,0,0,0.3); -} -.kd-buttonbar-colored .kd-button{ - color: white; - height:19px; - font-size: 11px; - margin-top:-1px; - background: none; - background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0.16)), to(rgba(0,0,0,0.2))); - /* @alternate */ background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.16), rgba(0,0,0,0.2)); - /* @alternate */ background-image: -moz-linear-gradient(top, rgba(0,0,0,0.16), rgba(0,0,0,0.2)); - /* @alternate */ background-image: -ms-linear-gradient(top, rgba(0,0,0,0.16), rgba(0,0,0,0.2)); - /* @alternate */ background-image: -o-linear-gradient(top, rgba(0,0,0,0.16), rgba(0,0,0,0.2)); - /* @alternate */ background-image: linear-gradient(top, rgba(0,0,0,0.16), rgba(0,0,0,0.2)); -} -.kd-buttonbar-colored .kd-button:hover, -.kd-buttonbar-colored .kd-button.hover { - color: white; - background: none; - border: 1px solid rgba(0,0,0,0.2); - - background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0.14)), to(rgba(0,0,0,0.2))); - /* @alternate */ background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.14), rgba(0,0,0,0.2)); - /* @alternate */ background-image: -moz-linear-gradient(top, rgba(0,0,0,0.14), rgba(0,0,0,0.2)); - /* @alternate */ background-image: -ms-linear-gradient(top, rgba(0,0,0,0.14), rgba(0,0,0,0.2)); - /* @alternate */ background-image: -o-linear-gradient(top, rgba(0,0,0,0.14), rgba(0,0,0,0.2)); - /* @alternate */ background-image: linear-gradient(top, rgba(0,0,0,0.14), rgba(0,0,0,0.2)); -} -.kd-buttonbar-colored .kd-button.focus, .kd-button.right.focus, -.kd-buttonbar-colored .kd-button.mid.focus, .kd-button.left.focus{ - outline: none; - border: 1px solid white; - z-index:4 !important; -} -.kd-buttonbar-colored .kd-button.disabled, -.kd-buttonbar-colored .kd-button.disabled:hover, -.kd-buttonbar-colored .kd-button.disabled:active { - color: rgba(255, 255, 255, 0.5); -} - -/* Slide toggle button */ -.kd-slidetoggle{ - height: 27px; - line-height: 27px; - width:94px; - padding:0; - -webkit-border-radius:2px; - -moz-border-radius: 2px; - border-radius: 2px; - border:1px solid #CCC; - font-weight:bold; - color:#666; - position:relative; - overflow:hidden; - - background-image: -webkit-gradient(linear, left top, left bottom, from(#EEEEEE), to(#e0e0e0)); - /* @alternate */ background-image: -webkit-linear-gradient(top, #EEEEEE, #e0e0e0); - /* @alternate */ background-image: -moz-linear-gradient(top, #EEEEEE, #e0e0e0); - /* @alternate */ background-image: -ms-linear-gradient(top, #EEEEEE, #e0e0e0); - /* @alternate */ background-image: -o-linear-gradient(top, #EEEEEE, #e0e0e0); - /* @alternate */ background-image: linear-gradient(top, #EEEEEE, #e0e0e0); - - -webkit-box-shadow: inset 0px 1px 2px 0 rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 2px 0 rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 2px 0 rgba(0,0,0,0.1); -} -.kd-slidetoggle span { - display: inline-block; - width: 45px; - text-align: center; - - -webkit-border-radius:2px 2px 0 0; - -moz-border-radius: 2px 2px 0 0; - border-radius: 2px 2px 0 0; -} -.kd-slidetoggle span.on{ - background-image: -webkit-gradient(linear, left top, left bottom, from(#3b93ff), to(#3689EE)); - /* @alternate */ background-image: -webkit-linear-gradient(top, #3b93ff, #3689EE); - /* @alternate */ background-image: -moz-linear-gradient(top, #3b93ff, #3689EE); - /* @alternate */ background-image: -ms-linear-gradient(top, #3b93ff, #3689EE); - /* @alternate */ background-image: -o-linear-gradient(top, #3b93ff, #3689EE); - /* @alternate */ background-image: linear-gradient(top, #3b93ff, #3689EE); - - color:#FFF; - - width:47px; - margin-right:-2px; - - -webkit-box-shadow: inset 0px 1px 2px 0 rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 2px 0 rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 2px 0 rgba(0,0,0,0.1); - - -webkit-border-radius:2px 0 0 2px; - -moz-border-radius: 2px 0 0 2px; - border-radius: 2px 0 0 2px; -} -.kd-slidetoggle .thumb{ - content:''; - position:absolute; - display:block; - top:-1px; - left:-1px; - height:27px; - width:47px; - border:1px solid #CCC; - -webkit-border-radius:2px; - -moz-border-radius: 2px; - border-radius: 2px; - - -webkit-box-shadow: 0px 1px 2px 0 rgba(0,0,0,0.1); - -moz-box-shadow: 0px 1px 2px 0 rgba(0,0,0,0.1); - box-shadow: 0px 1px 2px 0 rgba(0,0,0,0.1); - - background-image: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f1f1f1)); - /* @alternate */ background-image: -webkit-linear-gradient(top, #f8f8f8, #f1f1f1); - /* @alternate */ background-image: -moz-linear-gradient(top, #f8f8f8, #f1f1f1); - /* @alternate */ background-image: -ms-linear-gradient(top, #f8f8f8, #f1f1f1); - /* @alternate */ background-image: -o-linear-gradient(top, #f8f8f8, #f1f1f1); - /* @alternate */ background-image: linear-gradient(top, #f8f8f8, #f1f1f1); -} -.kd-slidetoggle.on .thumb{ - left:46px; -} -.kd-slidetoggle .thumb::after{ - content:""; - position:absolute; - display:block; - top:9px; - left:15px; - height:9px; - width:17px; - background-image: - -webkit-linear-gradient(left, #ccc 50%, transparent 50%), - -webkit-linear-gradient(left, #ccc 50%, transparent 50%), - -webkit-linear-gradient(left, #ccc 50%, transparent 50%), - -webkit-linear-gradient(left, #ccc 50%, transparent 50%), - -webkit-linear-gradient(left, #ccc 50%, transparent 50%); - background-size:2px 0; - background-position:0 0, 0 2px, 0 4px, 0 6px, 0 8px; - background-repeat:repeat-x; -} - -/*------------------------------------------------------------------ -Component: Butter Bar -------------------------------------------------------------------*/ -.kd-butterbar { - position: absolute; - text-align:center; - bottom:0; - padding:0 16px; - background:#F9EDBE; - border:1px solid #F0C36D; - margin-bottom:-15px; - left:-1000%; - - -webkit-border-radius:2px; - -moz-border-radius:2px; - border-radius:2px; - - margin-left:-190px; - opacity:0; - - -webkit-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - box-shadow: 0 2px 4px rgba(0,0,0,0.2); -} -.kd-butterbar.shown{ - opacity:1; - left:496px; -} -.kd-butterbar p{ - margin-bottom:0; - line-height:29px; - font-size:11px; -} - -.kd-butterbar a{ - color:#333; - text-decoration:underline; -} -.kd-butterbar a:hover{ - color:#202020; -} - -.kd-butterbar.mini{ - margin-bottom:-5px; -} -.kd-butterbar.mini p{ - line-height:19px; -} - -.kd-butterbar.fatal { - background: #ff3636; - border: 1px solid #9b1e1e; - color: white; - font-weight: bold; -} - -.kd-butterbar.fatal a { - color: white; - padding-left: 0.5em; -} - -.kd-butterbar.fatal a:hover { - color: white; -} - -/*------------------------------------------------------------------ -Component: Text Field, Autocomplete -------------------------------------------------------------------*/ -input[type=text] { - height: 29px; - background-color: #FFF; - line-height: 27px; - padding-left: 8px; - color: #333; - border: 1px solid #d9d9d9; - border-top: 1px solid #c0c0c0; - display: inline-block; - vertical-align: top; - -webkit-box-sizing: border-box; - box-sizing: border-box; - -webkit-border-radius: 1px; -} -input[type=text]:hover { - border: 1px solid #b9b9b9; - border-top: 1px solid #a0a0a0; - -webkit-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); -} -input[type=text]:focus { - -webkit-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.3); - -moz-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.3); - box-shadow: inset 0px 1px 2px rgba(0,0,0,0.3); - outline: none; - border: 1px solid #4d90fe; -} -input#fakesearch { - width: 512px; - font-size: 16px; -} -input#fakesearch:focus + .kd-autocomplete { - display: block; -} -.kd-search-form { - position: relative; -} -.kd-autocomplete { - width: 510px; - padding: 0; - display: none; - position: absolute; - left: 1px; - top: 29px; - z-index: 100; -} -.kd-autocompletelistitem { - font-size: 16px; - line-height: 30px; - padding-left: 10px; -} -.kd-autocompletelistitem:hover { - background: #eee; -} - -/*------------------------------------------------------------------ -Component: Zippy -------------------------------------------------------------------*/ -.kd-zippycontent { - position: relative; - overflow: hidden; - height: 0; -} -.kd-zippycontent > *{position:absolute;bottom:0; left:0; width:100%;} -.kd-zippy.expanded .kd-zippycontent{} - -.kd-zippycontent ul.iconList li a { - padding-left: 30px; - margin-left: 32px; - background-repeat: no-repeat; - background-position: 2px center; - line-height: 23px; -} - -.kd-zippycontent ul.iconList li a.images { - background-image: url(../images/icons/corpus-images.png); -} - -.kd-zippycontent ul.iconList li a.news { - background-image: url(../images/icons/corpus-news.png); -} - -.kd-zippycontent ul.iconList li a.places { - background-image: url(../images/icons/corpus-places.png); -} - -/* zippy as folder */ -.kd-zippy.kd-parent img.icon{ float:left; position:relative; top:2px; margin-right:5px; opacity:.6;} -.kd-zippy.kd-parent ul li a{line-height:23px; padding-left:0;} -.kd-zippy.kd-parent.has_icon ul li a{padding-left:23px;} -.kd-zippy.kd-parent ul li img.icon{top:-1px;} - -/*------------------------------------------------------------------ -Component: Accordion -------------------------------------------------------------------*/ -.kd-accordion .kd-zippy{ - border-bottom:1px solid #ebebeb; -} -.kd-accordion label{ - display:block; -} -.kd-accordion .kd-zippycontent{ -} -.kd-accordion .kd-zippycontent > ul{ - bottom:auto; - top:0; -} -.kd-accordion .kd-zippycontent ul li{ - margin-left:28px; - line-height:29px; -} -.kd-accordion .kd-zippycontent ul li input[type=radio]{ - margin-bottom:-2px; -} -.kd-accordion .expanded .row > a{ - color:#222; - font-weight:bold; -} -.kd-accordion .expanded .row .kd-disclosureindicator{ - - -} - -/*------------------------------------------------------------------ -Compondent: Slider -------------------------------------------------------------------*/ -.kd-slider { - position:relative; - width:137px; - height:5px; - padding:5px 0; - margin-bottom:20px; - - cursor:default; - -webkit-user-select:none; - -moz-user-select:none; -} -.kd-slider:before { - content:""; - display:block; - width:141px; - height:5px; - margin-left:-2px; - -webkit-border-radius:3px; - -moz-border-radius:3px; - border-radius:3px; - background:#e5e5e5; -} -.kd-slider:hover:before { - background:#d1d1d1; -} - -.kd-slider .kd-sliderhandle { - display:block; - position:absolute; - top:50%; - left:0; - z-index:1; - - background:#999; - cursor:pointer; - cursor:col-resize; - - -webkit-box-shadow:0px 1px 1px rgba(0,0,0,0.1); - -moz-box-shadow:0px 1px 1px rgba(0,0,0,0.1); - box-shadow:0px 1px 1px rgba(0,0,0,0.1); -} -.kd-slider .kd-sliderhandle-inner { - display:block; - position:absolute; - top:1px; - left:1px; - - background:#999; - text-align:center; - text-indent:-9999px; - line-height:15px; -} -.kd-slider:hover .kd-sliderhandle-inner { - background:#fff; -} -.kd-slider .kd-sliderhandle:active { - background:#535252; -} -.kd-slider .kd-sliderhandle:active .kd-sliderhandle-inner { - background:#535252; -} -.kd-slider.kd-slider-range .kd-sliderambit { - display:block; - position:absolute; - top:0; - left:0; - height:5px; - margin-top:5px; - - background:#c6c6c6; - cursor:pointer; - cursor:move; -} -.kd-slider.kd-slider-range:hover .kd-sliderambit { - background:#535252; -} -.kd-slider.kd-slider-range:active .kd-sliderambit { - background-color:#999; - background-size:6px 6px; - background-position:left -1px; - background-repeat:repeat-x; - background-image:-webkit-linear-gradient(135deg, transparent, transparent 3px, #fff 3px, #fff 4px, transparent 4px, transparent); - /* @alternate */ background-image:-moz-linear-gradient(135deg, transparent, transparent 3px, #fff 3px, #fff 4px, transparent 4px, transparent); - /* @alternate */ background-image:-o-linear-gradient(135deg, transparent, transparent 3px, #fff 3px, #fff 4px, transparent 4px, transparent); - /* @alternate */ background-image:linear-gradient(135deg, transparent, transparent 3px, #fff 3px, #fff 4px, transparent 4px, transparent); -} - -.kd-slider-continuous .kd-sliderhandle { - width:17px; - height:17px; - margin-top:-8px; - margin-left:-8px; - - -webkit-border-radius:8px; - -moz-border-radius:8px; - border-radius:8px; -} -.kd-slider-continuous .kd-sliderhandle-inner { - width:15px; - height:15px; - - -webkit-border-radius:7px; - -moz-border-radius:7px; - border-radius:7px; -} -.kd-slider-continuous.kd-slider-range .kd-sliderhandle { - width:9px; - - -webkit-border-radius:0; - -moz-border-radius:0; - border-radius:0; -} -.kd-slider-continuous.kd-slider-range .kd-sliderhandle-inner { - width:7px; - - -webkit-border-radius:0; - -moz-border-radius:0; - border-radius:0; -} -.kd-slider-continuous.kd-slider-range .kd-sliderhandle-min { - -webkit-border-top-left-radius: 8px; - -webkit-border-bottom-left-radius: 8px; - -moz-border-radius-topleft: 8px; - -moz-border-radius-bottomleft: 8px; - border-top-left-radius: 8px; - border-bottom-left-radius: 8px; -} -.kd-slider-continuous.kd-slider-range .kd-sliderhandle-min .kd-sliderhandle-inner { - -webkit-border-top-left-radius: 6px; - -webkit-border-bottom-left-radius: 6px; - -moz-border-radius-topleft: 6px; - -moz-border-radius-bottomleft: 6px; - border-top-left-radius: 6px; - border-bottom-left-radius: 6px; -} -.kd-slider-continuous.kd-slider-range .kd-sliderhandle-max { - margin-left:0; - -webkit-border-top-right-radius: 8px; - -webkit-border-bottom-right-radius: 8px; - -moz-border-radius-topright: 8px; - -moz-border-radius-bottomright: 8px; - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; -} -.kd-slider-continuous.kd-slider-range .kd-sliderhandle-max .kd-sliderhandle-inner { - -webkit-border-top-right-radius: 6px; - -webkit-border-bottom-right-radius: 6px; - -moz-border-radius-topright: 6px; - -moz-border-radius-bottomright: 6px; - border-top-right-radius: 6px; - border-bottom-right-radius: 6px; -} - -.kd-slider-discrete { - padding-bottom:26px; -} -.kd-slider-discrete .kd-sliderhandle { - width:16px; - height:9px; - margin-top:-18px; - margin-left:-8px; - - -webkit-border-top-left-radius: 3px; - -webkit-border-top-right-radius: 3px; - -moz-border-radius-topleft: 3px; - -moz-border-radius-topright: 3px; - border-top-left-radius: 3px; - border-top-right-radius: 3px; -} -.kd-slider-discrete .kd-sliderhandle:before { - content:""; - display:block; - position:absolute; - top:9px; - border-style:solid; - border-color:#999 transparent; - border-width:8px 8px 0; -} -.kd-slider-discrete .kd-sliderhandle:active:before { - border-color:#535252 transparent; -} -.kd-slider-discrete .kd-sliderhandle-inner { - width:14px; - height:8px; - - -webkit-border-top-left-radius: 2px; - -webkit-border-top-right-radius: 2px; - -moz-border-radius-topleft: 2px; - -moz-border-radius-topright: 2px; - border-top-left-radius: 2px; - border-top-right-radius: 2px; -} -.kd-slider-discrete .kd-sliderhandle-inner:before { - content:""; - display:block; - position:absolute; - top:8px; - border-style:solid; - border-color:#999 transparent; - border-width:7px 7px 0; -} -.kd-slider-discrete:hover .kd-sliderhandle-inner { - background:#fff; -} -.kd-slider-discrete:hover .kd-sliderhandle-inner:before { - border-color:#fff transparent; -} -.kd-slider-discrete .kd-sliderhandle:active .kd-sliderhandle-inner:before { - border-color:#535252 transparent; -} - -.kd-slider-discrete.kd-slider-range .kd-sliderhandle { - width:8px; -} -.kd-slider-discrete.kd-slider-range .kd-sliderhandle-inner { - width:6px; -} -.kd-slider-discrete.kd-slider-range .kd-sliderhandle-min { - margin-left:-7px; - -webkit-border-top-right-radius: 0; - -moz-border-radius-topright: 0; - border-top-right-radius: 0; -} -.kd-slider-discrete.kd-slider-range .kd-sliderhandle-min:before { - border-width:8px 0 0 8px; -} -.kd-slider-discrete.kd-slider-range .kd-sliderhandle-min .kd-sliderhandle-inner { - -webkit-border-top-right-radius: 0; - -moz-border-radius-topright: 0; - border-top-right-radius: 0; -} -.kd-slider-discrete.kd-slider-range .kd-sliderhandle-min .kd-sliderhandle-inner:before { - border-width:6px 0 0 6px; -} -.kd-slider-discrete.kd-slider-range .kd-sliderhandle-max { - margin-left:0; - -webkit-border-top-left-radius: 0; - -moz-border-radius-topleft: 0; - border-top-left-radius: 0; -} -.kd-slider-discrete.kd-slider-range .kd-sliderhandle-max:before { - border-width:8px 8px 0 0; -} -.kd-slider-discrete.kd-slider-range .kd-sliderhandle-max .kd-sliderhandle-inner { - -webkit-border-top-left-radius: 0; - -moz-border-radius-topleft: 0; - border-top-left-radius: 0; -} -.kd-slider-discrete.kd-slider-range .kd-sliderhandle-max .kd-sliderhandle-inner:before { - border-width:6px 6px 0 0; -} - -.kd-slider-discrete .kd-sliderruler { - position:absolute; - top:18px; - left:0; - width:100%; - height:18px; -} -.kd-slider-discrete .kd-sliderstep { - display:block; - position:relative; - float:left; - width:9px; - height:10px; - padding-top:8px; - margin-left:12px; - margin-right:-4px; - - text-align:center; - font-size:12px; - color:#343434; -} -.kd-slider-discrete .kd-sliderstep:first-child { - margin-left:-4px; -} -.kd-slider-discrete .kd-sliderstep:before { - content:""; - display:block; - position:absolute; - top:0; - left:4px; - width:1px; - height:5px; - - background:#d0d0d0; -} -.kd-slider-discrete .kd-sliderstep-minor { - text-indent:-9999px; -} -.kd-slider-discrete .kd-sliderstep-minor:before { - height:2px; -} - -/*------------------------------------------------------------------ -Component: Checkboxes and Radio buttons - -XXX: Modified to remove from defaults. -------------------------------------------------------------------*/ -.kd-input[type=checkbox], -.kd-input[type=radio], -.fakecheckbox, -.fakeradio { - -webkit-appearance: none; - width: 13px; - height: 13px; - border: 1px solid #C6C6C6; - margin:0; - -webkit-border-radius:1px; - -moz-border-radius:1px; - border-radius:1px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - cursor:default; - position:relative; -} -.kd-input[type=checkbox]:active, -.kd-input[type=radio]:active, -.fakecheckbox:active, -.fakeradio:active { - border-color:#666; - background:#ebebeb; -} -.kd-input[type=checkbox]:hover, -.kd-input[type=radio]:hover, -.fakecheckbox:hover, -.fakeradio:hover { - border-color:#666; - -webkit-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 1px rgba(0,0,0,0.1); -} -.kd-input[type=radio], -.fakeradio { - border-radius:50%; - width: 15px; - height: 15px; -} - -.kd-input[type=checkbox].disabled, -.kd-input[type=radio].disabled, -.fakecheckbox.disabled, -.fakeradio.disabled { - border-color:#f1f1f1; - background:#FFF; - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} -.disabledtext{ - color:#B8B8B8; -} - -.kd-input[type=radio]:checked::after, -.fakeradio.checked::after { - content:''; - display:block; - position:relative; - top:3px; - left:3px; - width:7px; - height:7px; - background:#666; - border-radius:50%; -} - -.kd-input[type=checkbox]:checked::after, -.fakecheckbox.checked::after { - content:url('../images/check_no_box.png'); - display:block; - position:absolute; - top:-6px; - left:-5px; -} - -.kd-input[type=checkbox]:focus, -.fakecheckbox.focus { - outline: none; - border-color:#4d90fe; -} -.fakecheckbox, -.fakeradio { - display:inline-block; -} - -/*------------------------------------------------------------------ -Component: Menus -------------------------------------------------------------------*/ -.kd-menulist { - background: #FFF; - /* border:1px solid #CCC;/*THIS SHOULD BE USED IN NON-WEBKIT BROWSERS ONLY - OTHER BROWSERS DO NOT INTERPRET THE OUTLINE STYLE CORRECTLY*/ - outline:1px solid rgba(0,0,0,0.2); - padding:0 0 6px; - white-space: nowrap; - -webkit-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - box-shadow: 0 2px 4px rgba(0,0,0,0.2); -} -.kd-menulist-bubble { - margin-top:11px; - padding-top:6px; -} -.kd-menulist-bubble:after{ - content:""; - outline: none; - display: block; - position: absolute; - top: -11px; - left: 24px; - margin: 0 0 0 -5px; - width: 17px; - height: 11px; - background: url('../images/bubble_point_white.png'); - -} -.kd-menulistitem { - display: block; - padding: 6px 44px 6px 16px; - position: relative; - color: #333; - font-size:13px; - font-weight:normal; - cursor: default; - margin: 0; -} -.kd-menuchecklistitem { - padding-left: 30px; -} - -.kd-shortcutitem{ - padding-right:72px; -} - -.kd-shortcut{ - position:absolute; - right:16px; - text-align:right; - color:#CCC; -} - -.kd-menulistitem.kd-menuchecklistitem.selected { - background-image: url('../images/check_no_box.png'); - background-position: left center; - background-repeat: no-repeat; - background-color: #FFF; -} -.kd-menulistitem.kd-menuchecklistitem.selected:hover { - background-color: #EEE; -} -.kd-menulistitem.disabled, .kd-menulistitem.disabled:hover, .kd-menulistitem.disabled { - color: #ccc; - background-color: #FFF; - cursor: default; -} - -.kd-menulist .kd-flyout { - position: absolute; - left: 100%; - top: 0; - width: 1px; - overflow: hidden; - opacity: 0.0; - -moz-opacity: 0.0; -} - -.kd-menulistitem:hover .kd-flyout { - width: auto; - overflow: visible; - opacity: 1.0; - -moz-opacity: 1.0; -} - -.kd-menulistitem .kd-disclosureindicator { - position: absolute; - right: 10px; - top: 50%; - margin-top: -3px; - opacity: .5; -} - -.kd-menulistitem:hover, .kd-menulistitem.selected { - background-color: #f1f1f1; - color: #222; -} -.kd-menulistitem:hover .kd-disclosureindicator { - border-left-color: #999; - opacity: 1; -} -.kd-menurule { - border-top: 1px solid #ebebeb; - margin-top: 9px; - margin-bottom: 10px; -} - -/*------------------------------------------------------------------ -Component: Menu Button -------------------------------------------------------------------*/ -.kd-menubutton .kd-menulist { - text-align: left; - position: absolute; - z-index: 99; - background: #FFF; - height: 0; - width:auto; - left:-9999px; - /*overflow: hidden;*/ - - opacity: 0.0; - -moz-opacity: 0.0; -} -.kd-menubutton .kd-menulist.shown { - left:0; - height: auto; - opacity: 1.0; - -moz-opacity: 1.0; -} -.kd-menubutton .kd-menulist.scroll.shown { - max-height: 174px; - overflow: auto; -} - -/*------------------------------------------------------------------ -Component: Modal Dialog -------------------------------------------------------------------*/ -#kd-modalshield { - background: #FFF; - position: fixed; - left: 0; - right: 0; - bottom: 0; - z-index: 99; - opacity: 0.0; -} -html.x-mobile #kd-modalshield { - display: none; -} -html.x-mobile #kd-modaldialog { - display: none; -} -body.strawman #kd-modalshield { - top: 44px; -} -body.kd-compact #kd-modalshield { - top: 72px; -} -html.y-expand #kd-modalshield { - top: 80px; -} -#kd-modalshield.visible { - opacity: .75; -} -.kd-modaldialog.visible { - opacity: 1.0; -} -.kd-modaldialog { - -webkit-box-shadow: 0 4px 16px rgba(0,0,0,0.2); - -moz-box-shadow: 0 4px 16px rgba(0,0,0,0.2); - -ms-box-shadow: 0 4px 16px rgba(0,0,0,0.2); - box-shadow: 0 4px 16px rgba(0,0,0,0.2); - background: white; - left: 50%; - outline:1px solid rgba(0,0,0,0.2);/* border:1px solid #CCC;/*THIS IS FOR NON-WEBKIT BROWSERS ONLY - OTHER BROWSERS DO NOT INTERPRET THE OUTLINE STYLE CORRECTLY*/ - padding:30px 42px; - position: fixed; - right: auto; - width: 512px; - height: auto; - overflow: hidden; - z-index: 100; - top: 72px; - margin-left: -256px; - opacity: 0.0; -} -.kd-modaldialog.medium { - padding:28px 32px; - - width: 384px; -} -.kd-modaldialog.small { - padding:16px 20px; - - width: 256px; -} -.kd-modaldialog h1 { - margin-bottom: 1em; -} - -.kd-modaldialog.small h1 { - margin-bottom: 8px; -} -.kd-formbuttons{ - margin-top:16px; -} -.kd-formbuttons .kd-button.primary{ - float:left; - margin-right:16px; -} -.kd-modaldialog .kd-confirmation { - display: inline-block; - padding-top: 7px; -} -.kd-modaldialog input[type=checkbox] { - margin-left: 0; - margin-right: 6px; - margin-bottom: -1px; -} -.kd-closebutton { - width: 44px; - height: 44px; - background: url('../images/icons/x.png') center no-repeat; - position: absolute; - top: 0; - right: 0; - opacity: .7; - -moz-opacity: .7; - cursor:default; -} -.kd-closebutton:hover { - opacity: 1; - -moz-opacity: 1; -} - -/*------------------------------------------------------------------ -Component: Prompt -------------------------------------------------------------------*/ -.kd-prompt label { - display: block; - margin-bottom: 16px; -} -.kd-prompt input[type=text] { - width: 100%; -} - -/*------------------------------------------------------------------ -Component: Settings -------------------------------------------------------------------*/ -.kd-settings { - -webkit-box-shadow: 0 4px 16px rgba(0,0,0,0.2); - -moz-box-shadow: 0 4px 16px rgba(0,0,0,0.2); - -ms-box-shadow: 0 4px 16px rgba(0,0,0,0.2); - box-shadow: 0 4px 16px rgba(0,0,0,0.2); - background: white; - left: 50%; - outline:1px solid rgba(0,0,0,0.2);/* border:1px solid #CCC;/*THIS IS FOR NON-WEBKIT BROWSERS ONLY - OTHER BROWSERS DO NOT INTERPRET THE OUTLINE STYLE CORRECTLY*/ - position: fixed; - right: auto; - width: 800px; - height: auto; - overflow: hidden; - z-index: 100; - top: 72px; - margin-left: -256px; - opacity: 0.0; -} -.kd-settings.visible { - opacity: 1.0; -} -.kd-settings-hd { - background-color: #f1f1f1; - border-bottom: 1px solid #ccc; - height: 71px; -} -.kd-settings-hd h1 { - padding-top: 26px; - padding-left: 42px; -} -.kd-settings-hd .kd-formbuttons { - float: right; - padding-right: 26px; - padding-top: 22px; - margin: 0; -} -.kd-settings-nav { - padding: 36px 20px 36px 42px; - border-right: 1px solid #ebebeb; - width: 108px; - float: left; - overflow: auto; -} -.kd-settings-nav li { - margin-bottom: 13px; -} -.kd-settings-nav li a { - display: block; - color: #333; - cursor: default; -} -.kd-settings-nav li a:hover { - color: #111; -} -.kd-settings-nav li a.selected { - color: #DD4B39; - font-weight: bold; -} -.kd-settings-content { - width: 629px; - margin-left: 171px; - height: auto; - overflow: hidden; - padding-bottom: 20px; -} -.kd-settings-content .kd-settings-pane { - display: none; - padding: 16px 32px; - height: auto; - max-height: 400px; - overflow: auto; -} -.kd-settings-content .kd-settings-pane.selected { - display: block; -} - -.kd-settings-pane-section { - clear: both; - border-bottom: 1px solid #ebebeb; - padding: 20px 0; - height: 100%; - overflow: hidden; -} -.kd-settings-pane-section p { - line-height: 13px; -} -.kd-settings-pane-section .setting-label { - display: block; - width: 185px; - float: left; - font-weight: bold; -} -.kd-settings-pane-section .setting-label .info { - font-size: 11px; - color: #666; - font-weight: normal; -} -.kd-settings-pane-section .setting { - margin-left: 210px; -} -.kd-settings-pane-section .kd-button.kd-select { - float: none; - margin-left: 0; - min-width: 0; - margin-right: 5px; -} - -.kd-settings-pane-section .setting input[type=checkbox] { - margin-right: 5px; - bottom: -1px; -} - -/*------------------------------------------------------------------ -Component: Bubble Panel -------------------------------------------------------------------*/ -.kd-bubble { - position: relative; - background: #FFF; - outline: 1px solid rgba(0,0,0,0.2); - -webkit-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - box-shadow: 0 2px 4px rgba(0,0,0,0.2); - padding: 16px; - width: 146px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.kd-bubble .pointer { - outline: none; - display: block; - position: absolute; - top: -11px; - left: 24px; - margin: 0 0 0 -5px; - width: 17px; - height: 11px; - background: url('../images/bubble_point_white.png'); -} - -.kd-bubble p { - margin-bottom: 0; - color: #666; -} - -.kd-bubble p.links { - margin-top: 10px; -} -.kd-bubble p.links a:hover{ - text-decoration:underline; -} - -.kd-bubble.alert{ - background: #F9EDBE; - outline: 1px solid #f0c36d; -} -.kd-bubble.alert .pointer{ - background: url('../images/bubble_point_yellow.png'); -} - -.kd-profilebox{ - width:336px; -} -.kd-profilebox .kd-disclaimer{ - background:#F9EDBE; - padding:16px; - margin:-16px -16px 0 -16px; - border-bottom:1px solid #ddd8c0; -} -.kd-bubble.kd-profilebox .pointer{ - background: url('../images/bubble_point_yellow_grey.png'); -} -.kd-profilebox .kd-disclaimer p{ - color:#202020; -} -.kd-profile{ - padding:22px 0; - height:100%; - overflow:hidden; -} -.kd-profileimage{ - float:left; - width:160px; -} -.kd-profileimage img{ - border:1px solid #CCC; -} -.kd-profileinfo{ - float:right; - width:160px; -} -.kd-profileinfo .email{ - color:#999; -} -.kd-profileinfo ul{ - margin-top:6px; -} -.kd-profileinfo ul li{ - line-height:24px; -} -.kd-profileinfo .kd-profilename{ - font-size:13px; - line-height:13px; - color:#202020; - font-weight:bold; -} -.kd-accountlist{ - background:#f1f1f1; - padding:3px 16px 0; - margin:0 -16px 0; - border-top:1px solid #CCC; - -webkit-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - -moz-box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); - box-shadow: inset 0px 1px 2px rgba(0,0,0,0.1); -} -.kd-accountlist h3{ - font-size:13px; - font-weight:bold; -} -.kd-accountlist img{ - border:1px solid #CCC; - position:absolute; - left:0; - top:2px; -} -.kd-accountlist ul{ - margin-top:3px; -} -.kd-accountlist ul li{ - height:44px; - position:relative; -} -.kd-accountlist ul li p{ - margin-left:44px; -} -.kd-bubble .bottomlinks{ - margin:0 -16px; - padding:16px 16px 0; - border-top:1px solid #CCC; -} -.kd-bubble .bottomlinks a{ - float:right; -} -.kd-bubble .bottomlinks a:first-child{ - float:left; -} -#stickers .kd-bubble{ - margin-right:44px; - float:left; -} -.kd-bubble.dark{background:#2d2d2d;width:auto;outline: 1px solid rgba(255,255,255,0.5);} -.kd-bubble.dark ul{height:100%; overflow:hidden;} -.kd-bubble.dark li{float:left; margin-left:16px;} -.kd-bubble.dark li img{display:block;} -.kd-bubble.dark li:first-child{margin-left:0;} -.kd-bubble.dark .pointer{ - background:url('../images/bubble_point_dk_grey.png') bottom center no-repeat; -} - -/*------------------------------------------------------------------ -Component: Hovercard -------------------------------------------------------------------*/ -.kd-hovercard { - outline:1px solid rgba(0,0,0,0.2); - width: 160px; - -webkit-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - box-shadow: 0 2px 4px rgba(0,0,0,0.2); -} - -.kd-hovercard .kd-cardprofile { - padding: 16px 16px 0; - border-bottom: 1px solid #ebebeb; -} - -.kd-hovercard .kd-menulist { - outline: 0; - width: auto; - -webkit-box-shadow: 0; - -moz-box-shadow: 0; - box-shadow: 0; -} - -/*------------------------------------------------------------------ -Component: Date Picker -------------------------------------------------------------------*/ -.kd-datepicker{ - padding:16px; - outline: 1px solid rgba(0,0,0,0.2); - opacity:0; - width:144px; - position:absolute; - left:-9999px; - z-index:3; - background:#FFF; - - -webkit-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - box-shadow: 0 2px 4px rgba(0,0,0,0.2); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.kd-minicalendar{ - width:148px; - margin-left:-4px; -} -.kd-datepicker .kd-minicalendar{ - width:144px; - margin:0; - -} -.kd-datepicker.shown{ - opacity:1; -} -.kd-minicalendar h2{ - font-size:13px; - color:#666; - padding-left:4px; -} -.kd-minicalendar h2 .links{ - float:right; - margin-right:2px; -} -.kd-minicalendar h2 .links img{ - cursor:default; -} -.kd-minicalendar td, .kd-minicalendar th{ - width:20px; - height:20px; - line-height:20px; - padding-left:4px; - font-size:11px; - color:#666; - cursor:default; -} -.kd-minicalendar td:hover, .kd-minicalendar td.selected, .kd-minicalendar h2 .links img:hover{ - background:#eee; - color:#333; -} - -.kd-minicalendar td.disabled{ - color:#ccc; -} -.kd-minicalendar td.disabled:hover{ - background:none; - cursor:default; -} - -/*------------------------------------------------------------------ -Component: Color Picker -------------------------------------------------------------------*/ -.kd-colorpicker{ - width:140px; - padding:16px; - outline: 1px solid rgba(0,0,0,0.2); - -webkit-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 2px 4px rgba(0,0,0,0.2); - box-shadow: 0 2px 4px rgba(0,0,0,0.2); - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; -} -.kd-menubutton .kd-colorpicker{ - padding:0; -} -.kd-menubutton.selected .kd-colorpicker{ - padding:16px; -} -.kd-colortable{ - width:140px; -} -.kd-colortable.primaries{ - margin-bottom:8px; -} -.kd-colortable td{ - width:16px; - height:16px; - border:1px solid #FFF; - cursor:default; - position:relative; -} -.kd-colortable td:hover{ - border-color:#333; -} -.kd-colortable td.selected:after{ - content:''; - display:block; - position:absolute; - top:-3px; - right:0; - width:18px; - height:18px; - background:url('../images/icons/svg/Translate/check_with_stroke.svg'); -/* -webkit-mask-image:url('../images/icons/svg/Translate/check_with_stroke.svg');*/ -} - -/*------------------------------------------------------------------ -Component: Activity Indicator -------------------------------------------------------------------*/ -#loader { - position:relative; - width:19px; - height:19px; -} -#loader * { - display:block; - position:absolute; -} -#loader .circle { - width:100%; - height:100%; - -webkit-border-radius:50%; - -moz-border-radius:50%; - border-radius:50%; - opacity:0; - overflow:hidden; -} - -#loader .mask { - height:100%; - width:100%; - opacity:0; - overflow:hidden; -} - -#loader .circle.initial .mask { top:0; height:50%; } - -#loader .circle.red .mask.first { top:0; height:50%; border-bottom:1px solid #555; } -#loader .circle.red .mask.second { bottom:0; height:50%; } - -#loader .circle.yellow .mask.first { right:0; width:50%; border-left:1px solid #888; } -#loader .circle.yellow .mask.second { left:0; width:50%; } - -#loader .circle.green .mask.first { bottom:0; height:50%; border-top:1px solid #555; } -#loader .circle.green .mask.second { top:0; height:50%; } - -#loader .circle.blue .mask.first { left:0; width:50%; border-right:1px solid #888;} -#loader .circle.blue .mask.second { right:0; width:50%; } - -#loader .circle .mask .base { - height:100%; - width:100%; - opacity:0; - -webkit-border-radius:50%; - -moz-border-radius:50%; - border-radius:50%; -} - -#loader .circle .mask .mover { - height:100%; - width:100%; - -webkit-border-radius:50%; - -moz-border-radius:50%; - border-radius:50%; -} - -#loader .circle.red .mask.first .base { top:0; height:200%; background-color:#888; } -#loader .circle.red .mask.second .base { bottom:0; height:200%; background-color:#555; } - -#loader .circle.yellow .mask.first .base { right:0; width:200%; background-color:#555; } -#loader .circle.yellow .mask.second .base { left:0; width:200%; background-color:#888; } - -#loader .circle.green .mask.first .base { bottom:0; height:200%; background-color:#888; } -#loader .circle.green .mask.second .base { top:0; height:200%; background-color:#555; } - -#loader .circle.blue .mask.first .base { left:0; width:200%; background-color:#555; } -#loader .circle.blue .mask.second .base { right:0; width:200%; background-color:#888; } - -#loader .circle.initial .mask .mover { - top:100%; - height:0; - background-color:#363636; -} -#loader .circle.red .mask.first .mover { top:0; height:200%; background-color:#555; } -#loader .circle.red .mask.second .mover { bottom:100%; height:0; background-color:#6a6a6a } - -#loader .circle.yellow .mask.first .mover { right:0; width:200%; background-color:#888; } -#loader .circle.yellow .mask.second .mover { left:100%; width:0; background-color:#363636; } - -#loader .circle.green .mask.first .mover { bottom:0; height:200%; background-color:#555; } -#loader .circle.green .mask.second .mover { top:100%; height:0; background-color:#6a6a6a; } - -#loader .circle.blue .mask.first .mover { left:0; width:200%; background-color:#888; } -#loader .circle.blue .mask.second .mover { right:100%; width:0; background-color:#363636; } - -/* Initial State */ -#loader.initial .circle.initial, -#loader.initial .circle.initial .mask { - opacity:1; -} -#loader.initial .circle.initial .mask .mover { - top:0; - height:200%; - background-color:#555; -} - -/* Moving from Red to Yellow */ -#loader.yellow .circle.yellow, -#loader.yellow .circle.yellow .mask, -#loader.yellow .circle.yellow .mask .base { - opacity:1; -} -#loader.yellow .circle.yellow .mask.first { - border-color:#555; -} -#loader.yellow .circle.yellow .mask.first .mover { - right:100%; - width:0; - background-color:#6a6a6a; -} -#loader.yellow .circle.yellow .mask.second .mover { - left:0; - width:200%; - background-color:#555; -} - -/* Moving from Yellow to Green */ -#loader.green .circle.green, -#loader.green .circle.green .mask, -#loader.green .circle.green .mask .base { - opacity:1; -} -#loader.green .circle.green .mask.first { - border-color:#888; -} -#loader.green .circle.green .mask.first .mover { - bottom:100%; - height:0; - background-color:#363636; -} -#loader.green .circle.green .mask.second .mover { - top:0; - height:200%; - background-color:#888; -} - - -/* Moving from Green to Blue */ -#loader.blue .circle.blue, -#loader.blue .circle.blue .mask, -#loader.blue .circle.blue .mask .base { - opacity:1; -} -#loader.blue .circle.blue .mask.first { - border-color:#555; -} -#loader.blue .circle.blue .mask.first .mover { - left:100%; - width:0; - background-color:#6a6a6a; -} -#loader.blue .circle.blue .mask.second .mover { - right:0; - width:200%; - background-color:#555; -} - -/* Moving from Blue to Red */ -#loader.red .circle.red, -#loader.red .circle.red .mask, -#loader.red .circle.red .mask .base { - opacity:1; -} -#loader.red.firstTime .circle.red .mask.second .base { - opacity:0; -} -#loader.red .circle.red .mask.first { - border-color:#888; -} -#loader.red .circle.red .mask.first .mover { - top:100%; - height:0; - background-color:#363636; -} -#loader.red .circle.red .mask.second .mover { - bottom:0; - height:200%; - background-color:#888; -} -#loader.offline .mask.first .base, -#loader.offline .mask.second .mover, -#loader.readyOn .base, -#loader.readyOn .mover, -#loader.transitionOn .mask.second .base{ - background-color:#999 !important; -} -#loader.offline .mask.first, -#loader.readyOn .mask.first{ - border-color:#999 !important; -} -#loader .bolt{ - background:url('../images/offline_lightning.png') center no-repeat; - position:absolute; - top:50%; - left:50%; - margin-top:-6px; - margin-left:-3px; - opacity:0; - width:8px; - height:14px; -} -#loader.offline .bolt{ - opacity:1; -} -/*#loader.transitionOn .mask.first .mover{ - background-color:#999 !important; -}*/ - -#loader.stopped .mask.first .base, -#loader.finishing .mask.first .base, -#loader.finishing .mask.second .base, -#loader.finishing .mask.first .mover{ - opacity:0 !important; -} - -#loader.finishing .mask.first{ - border-color:transparent !important; -} -#loader.finishing.blue .circle.blue .mask.second .mover{ - width:0; - right:100%; -} -#loader.finishing.green .circle.green .mask.second .mover{ - height:0; - top:100%; -} -#loader.finishing.yellow .circle.yellow .mask.second .mover{ - width:0; - left:100%; -} -#loader.finishing.red .circle.red .mask.second .mover{ - height:0; - bottom:100%; -} - -/*Grey*/ -/*blue and yellow becaome dark grey*/ -/*#loader.grey.red .circle.red .base, -#loader.grey.blue .circle.blue .base, -#loader.grey.yellow .circle.yellow .base, -#loader.grey.green .circle.green .base, -#loader.grey.red .circle.red .mask.second .mover, -#loader.grey.yellow .circle.yellow .mask.second .mover, -#loader.grey.blue .circle.blue .mask.second .mover, -#loader.grey.red .circle.yellow .mask.first .mover, -#loader.grey.yellow .circle.green .mask.first .mover, -#loader.grey.green .circle.blue .mask.first .mover, -#loader.grey.blue .circle.red .mask.first .mover{ - background-color:#777; -}*/ -/*red and green become lighter grey*/ -/*#loader.grey.red .circle.red .mask.first .base, -#loader.grey.red .circle.red .mask.second .mover, -#loader.grey.green .circle.green .mask.first .base, -#loader.grey.green .circle.green .mask.second .mover, -#loader.grey.green .circle.blue .mask.first .mover, -#loader.grey.blue .circle.blue .mask.second .base, -#loader.grey.red .circle.yellow .mask.first .mover, -#loader.grey.yellow .circle.yellow .mask.second .base{ - background-color:#999; -}*/ - -/*#loader.offline.red .circle.red .mask.first .mover, -#loader.grey.yellow .circle.yellow .mask.first .mover, -#loader.grey.green .circle.green .mask.first .mover, -#loader.grey.blue .circle.blue .mask.first .mover, -#loader.grey.red .circle.yellow .mask.second .mover, -#loader.grey.yellow .circle.green .mask.second .mover, -#loader.grey.green .circle.blue .mask.second .mover, -#loader.grey.blue .circle.red .mask.second .mover{ - background-color:#555; -}*/ - -/*#loader.grey .mask.second .base, -#loader.grey .mask.second .mover, -#loader.grey .mask.first .base, -#loader.grey .mask.first .mover{ - background:#999 !important; -} - -#loader.grey .mask.first{ - border-color:#777 !important; -} -#loader.grey.red .mask.first, -#loader.grey.green .mask.first{ - border-color:#999 !important; -}*/ - -/*------------------------------------------------------------------ -Component: Progress Bar -------------------------------------------------------------------*/ -.kd-progressstatus{ - color:#202020; - margin-bottom:0; -} -.kd-progresstext{ - color:#999; -} -.kd-progressbar{ - width:320px; - border:1px solid #999; - padding:1px; -} -.kd-progresstrack { - background-color:#ccc; - width:170px; - height:5px; -} -.kd-progressbar-blue .kd-progresstrack { background-color:#6188f5; } - -.kd-progressbar-tall .kd-progresstrack, -.kd-progressbar-tall .kd-quantitytrack { - height:8px; -} - -.kd-progressbar-animated .kd-progresstrack { - -webkit-box-shadow:inner 0 0 0 1px rgba(0,0,0,0.1); - -moz-box-shadow:inner 0 0 0 1px rgba(0,0,0,0.1); - box-shadow:inner 0 0 0 1px rgba(0,0,0,0.1); - - background-repeat:repeat-x; - background-position:0 0; - background-size:16px 8px; - background-image:-webkit-linear-gradient(315deg, transparent, transparent 33%, rgba(0,0,0,0.12) 33%, rgba(0,0,0,0.12) 66%, transparent 66%, transparent); - /* @alternate */ background-image:-moz-linear-gradient(315deg, transparent, transparent 33%, rgba(0,0,0,0.12) 33%, rgba(0,0,0,0.12) 66%, transparent 66%, transparent); - /* @alternate */ background-image:-o-linear-gradient(315deg, transparent, transparent 33%, rgba(0,0,0,0.12) 33%, rgba(0,0,0,0.12) 66%, transparent 66%, transparent); - /* @alternate */ background-image:linear-gradient(315deg, transparent, transparent 33%, rgba(0,0,0,0.12) 33%, rgba(0,0,0,0.12) 66%, transparent 66%, transparent); -} -.kd-progressbar-animated.kd-progressbar-tall .kd-progresstrack { - background-size:20px 10px; -} - -@-webkit-keyframes bg { - 0% { background-position:0 0; } - 100% { background-position:-16px 0; } -} -@-webkit-keyframes bg-tall { - 0% { background-position:0 0; } - 100% { background-position:-20px 0; } -} - -/*------------------------------------------------------------------ -Component: Quantity Bar -------------------------------------------------------------------*/ -.kd-quantitytrack{ - width:170px; - height:5px; - background-color: #CCC; - background-image: -webkit-linear-gradient(0, transparent 50%, white 50%); - /* @alternate */ background-image: -moz-linear-gradient(0, transparent 50%, white 50%); - /* @alternate */ background-image: linear-gradient(0, transparent 50%, white 50%); - -o-background-size: 5px; - -moz-background-size: 5px; - -webkit-background-size: 5px; - background-size: 5px; -} - -/*------------------------------------------------------------------ -Component: Scrollbars -------------------------------------------------------------------*/ -.scrollBarBox{ - width:144px; - margin-right:44px; - position:relative; - display:inline-block; - -webkit-box-sizing:border-box; -} -.scrollBarInner{ - height:300px; - overflow:auto; - padding-top:20px; - padding-right:16px; -} -.scrollBarInner .shadowTop{ - width:100%; - margin-right:0; - height:6px; - position:absolute; - top:0; - left:0; - background:-webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,.2)), to(rgba(0,0,0,0))); - opacity:0; -} -.scrollBarInner .shadowTop:after { - content:""; - display:block; - position:absolute; - top:0px; - left:0; - width:100%; - height:0; - border-top:1px solid #ebebeb; /*FOR IE*/ - /* @alternate */ border-top:1px solid rgba(0, 0, 0, 0.3); -} - -.scrollBarInner .shadowBottom{ - width:100%; - margin-right:0; - height:4px; - position:absolute; - bottom:0; - left:0; - background:-webkit-gradient(linear, left bottom, left top, from(rgba(0,0,0,.2)), to(rgba(0,0,0,0))); - opacity:1; -} -.scrollBarInner .shadowBottom:after { - content:""; - display:block; - position:absolute; - bottom:0px; - left:0; - width:100%; - height:0; - border-bottom:1px solid #ebebeb; /*FOR IE*/ - /* @alternate */ border-bottom:1px solid rgba(0, 0, 0, 0.3); -} - -::-webkit-scrollbar { - width: 16px; - height: 16px; -} - -::-webkit-scrollbar-button { - height: 0px; - width: 0px; -} - -/*::-webkit-scrollbar-button:horizontal { - background-color: transparent; - width:4px; -}*/ - -::-webkit-scrollbar-button:start:decrement, -::-webkit-scrollbar-button:end:increment { - display: block; -} - -::-webkit-scrollbar-button:vertical:start:increment, -::-webkit-scrollbar-button:vertical:end:decrement { - display: none; -} -::-webkit-scrollbar-track:vertical { - border-right: 0px solid transparent; - border-left: 5px solid transparent; - background-clip:padding-box; - background-color: white; -} -::-webkit-scrollbar-track:horizontal { - border-bottom: 0px solid transparent; - border-top: 5px solid transparent; - background-clip:padding-box; - background-color: white; - -} - -::-webkit-scrollbar-thumb { - min-height: 28px; - padding-top:100px; - background-clip:padding-box; - background-color: rgba(0,0,0,0.2); - -webkit-box-shadow: inset 1px 1px 0px rgba(0,0,0,0.10), - inset 0px -1px 0px rgba(0,0,0,0.07); -} - -::-webkit-scrollbar-thumb:hover { - background-color: rgba(0,0,0,0.4); - -webkit-box-shadow: inset 1px 1px 1px rgba(0,0,0,0.25); -} - -::-webkit-scrollbar-thumb:active { - -webkit-box-shadow: inset 1px 1px 3px rgba(0,0,0,0.35); - background-color: rgba(0,0,0,0.5); -} -::-webkit-scrollbar-thumb:vertical { - border-top: 0px solid transparent; - border-bottom: 0px solid transparent; - border-right: 0px solid transparent; - border-left: 5px solid transparent; -} -::-webkit-scrollbar-thumb:horizontal { - border-top: 5px solid transparent; - border-bottom: 0px solid transparent; - border-right: 0px solid transparent; - border-left: 0px solid transparent; -} - -.inline-scroller .scrollBarInner::-webkit-scrollbar-track:vertical { - border-left: 6px solid transparent; - border-right: 1px solid transparent; -} -.inline-scroller .scrollBarInner::-webkit-scrollbar-track:horizontal { - border-top: 6px solid transparent; - border-bottom: 1px solid transparent; -} - -/*.inline-scroller .scrollBarInner::-webkit-scrollbar-track:hover { - background-color:rgba(0,0,0,0.035); - -webkit-box-shadow: inset 1px 1px 0px rgba(0,0,0,0.14), - inset -1px -1px 0px rgba(0,0,0,0.07); -}*/ - -.inline-scroller .scrollBarInner::-webkit-scrollbar-thumb:vertical { - border-left: 6px solid transparent; - border-right: 1px solid transparent; - border-top: 0px solid transparent; - border-bottom: 0px solid transparent; -} -.inline-scroller .scrollBarInner::-webkit-scrollbar-thumb:horizontal { - border-left: 0px solid transparent; - border-right: 0px solid transparent; - border-top: 6px solid transparent; - border-bottom: 1px solid transparent; -} - -::-webkit-scrollbar-track:hover { - background-color:rgba(0,0,0,0.05); - -webkit-box-shadow: inset 1px 0px 0px rgba(0,0,0,0.10); -} - -::-webkit-scrollbar-track:active { - background-color:rgba(0,0,0,0.05); - -webkit-box-shadow: inset 1px 0px 0px rgba(0,0,0,0.14), - inset -1px -1px 0px rgba(0,0,0,0.07); -} -/*::-webkit-scrollbar-track-piece { background: white; }*/ - -/*------------------------------------------------------------------ -Component: Tooltips -------------------------------------------------------------------*/ -#kd-tooltip { - display: block; - position: absolute; - background: #2d2d2d; - top: -5px; - color: #FFF; - font-weight: bold; - text-align: center; - outline: 1px solid rgba(255,255,255,0.5); - height: 29px; - line-height: 29px; - margin-left: -20px; - padding: 0 10px; - font-size: 11px; - z-index: 2000; - opacity: 0.0; - -webkit-box-shadow: 0px 1px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px 1px 4px rgba(0,0,0,0.2); - box-shadow: 1px 2px 4px rgba(0,0,0,0.2); - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -#kd-tooltip .pointer { - outline: none; - display: block; - position: absolute; - top: -5px; - left: 24px; - margin: 0 0 0 -5px; - width: 0; - height: 0; - line-height: 0px; - font-size: 0px; - /* This sets the tooptip pointer color */ - border-top: transparent; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-bottom: 5px solid #2d2d2d; -} -#kd-tooltip.visible { - opacity: 1.0; -} - -/*------------------------------------------------------------------ -Component: Star/Importance icons -------------------------------------------------------------------*/ -.kd-star { - display: inline-block; - height: 21px; - width: 21px; - background: url('../images/icons/svg/Gmail/starred_ghost.svg') center center no-repeat; - cursor: default; -} -.kd-star:hover { - background-image: url('../images/icons/svg/Gmail/starred_ghost_hover.svg'); -} -.kd-star.selected { - background-image: url('../images/icons/svg/Gmail/starred_fill_yellow.svg'); -} -.kd-star.selected:hover { - background-image: url('../images/icons/svg/Gmail/starred_fill_yellow_hover.svg'); -} -#wrap { - padding-bottom: 400px; - padding-left:200px; -} -.star { - height:19px; - width: 19px; -} -.star_unlit { background: url(../images/star.png); } -.star_unlit:hover { background: url(../images/star_hover.png); } -.star_unlit:active { background: url(../images/star_down.png); } -.star_lit { background: url(../images/star_fill.png); } -.star_lit:hover { background: url(../images/star_fill_hover.png); } -.star_lit:active { background: url(../images/star_fill_down.png); } - -/* importance indicators */ -.importance { - height:19px; - width: 19px; -} -.importance_unlit { - background: url(../images/importance.png); -} - -.importance_unlit:hover { - background: url(../images/importance_hover.png); -} - -.importance_unlit:active { - background: url(../images/importance_down.png); -} - -.importance_lit { - position: relative; - height:19px; - width: 19px; - background: url(../images/importance_fill.png); -} - -.importance_lit:hover { - background: url(../images/importance_fill_hover.png); -} - -.importance_lit:active { - background: url(../images/importance_fill_down.png); -} - -/*------------------------------------------------------------------ -Component: Rating Stars -------------------------------------------------------------------*/ -.kd-ratingstar{ - display:inline-block; - width:12px; - height:21px; - background:url('../images/icons/svg/Maps/review_stars_blank.svg') center no-repeat; - cursor:default; -} -.kd-ratingstar.full{ - background:url('../images/icons/svg/Maps/review_stars_full.svg') center no-repeat; -} -.kd-ratingstar.half{ - background:url('../images/icons/svg/Maps/review_stars_half.svg') center no-repeat; -} - -/*------------------------------------------------------------------ -Component: Sample Form -------------------------------------------------------------------*/ -form ul li{ - margin-bottom:16px; -} -form{ - width:336px; -} -fieldset{ - border:1px solid #ebebeb; - padding:16px; -} -legend{ - padding:0 6px; -} -form label{ - display:block; - line-height:29px; -} -form input[type=text]{ - width:100%; -} -form label input[type=radio], form label input[type=checkbox]{ - bottom:-1px; -} -form label input[type=checkbox]{ - margin-right:5px; -} -form .kd-button.kd-select{ - float:none; - margin-left:0; -} - -/*------------------------------------------------------------------ -Component: Form Errors -------------------------------------------------------------------*/ -#errorDemo{ - width:280px; -} - -.kd-formerror{ - border:1px solid #DD4B39; -} -.kd-errormessage{ - color:#DD4B39; - padding:9px 0 ; -} -.kd-errormessage .qm{ - background:#DD4B39; - color:#FFF; - font-weight:bold; - display:inline-block; - padding: 0 5px ; - -webkit-border-radius:10px; - -moz-border-radius:10px; - border-radius:10px; - - position: relative; - top: -1px; -} -.kd-textlabel{ - color:#666; -} - -/*------------------------------------------------------------------ -Component: List -------------------------------------------------------------------*/ - -.kd-list table, -.kd-list tbody { - display:block; - width:100%; - overflow:visible; -} -.kd-list table tr { - display:block; - position:relative; - height:39px; - margin-top:-1px; - background-color:#f8f8f8; - border:1px solid; - border-color:#ebebea transparent; - z-index:1; -} -.kd-list table tr.highlighted { - background:#fff; -} -.kd-list table tr.checked { - background-color: #f6ebae; - border-color:#ebdb84 transparent; - z-index:2; -} -.kd-list table tr:hover { - z-index:3; - border-color:#ccc; - -webkit-box-shadow: 0 4px 16px rgba(0,0,0,0.2); - -moz-box-shadow: 0 4px 16px rgba(0,0,0,0.2); - -ms-box-shadow: 0 4px 16px rgba(0,0,0,0.2); - box-shadow: 0 4px 16px rgba(0,0,0,0.2); -} -.kd-list table tr.checked:hover { - border-color:#e5d36f; -} -.kd-list table tr:hover input[type=checkbox], -.kd-list table tr:hover .fakecheckbox, -.kd-list table tr.checked input[type=checkbox], -.kd-list table tr.checked .fakecheckbox { - background:#fff; -} -.kd-list table tr td { - display:block; - position:absolute; -} -.kd-list table tr td a { - display:block; - text-overflow:ellipsis; - overflow:hidden; - white-space:nowrap; - line-height:39px; - font-size:13px; - color:#333; -} - -.y-crush .kd-list table tr { - height:29px; -} -.y-crush .kd-list table tr.two-line, -.mobile .kd-list table tr.two-line { - height:51px; -} -.y-crush .kd-list table tr td a, -.mobile .kd-list table .two-line td a { - line-height:29px; -} -.mobile .kd-list table tr td:first-child { - left:16px; - padding-left:0; -} - -/* KNURLING */ -.kd-list table.knurling tr:hover:after { - content:""; - position:absolute; - top:2px; - bottom:2px; - left:2px; - width:7px; - background-image:-webkit-linear-gradient(top, #ddd, #ddd 50%, transparent 50%, transparent); - /* @alternate */ background-image:-moz-linear-gradient(top, #ddd, #ddd 50%, transparent 50%, transparent); - /* @alternate */ background-image:linear-gradient(top, #ddd, #ddd 50%, transparent 50%, transparent); - background-size:1px 2px; - cursor:pointer; - z-index:3; -} -.kd-list table.knurling tr.checked:after { - background-image:-webkit-linear-gradient(top, #dcc961, #dcc961 50%, transparent 50%, transparent); - /* @alternate */ background-image:-moz-linear-gradient(top, #dcc961, #dcc961 50%, transparent 50%, transparent); - /* @alternate */ background-image:linear-gradient(top, #dcc961, #dcc961 50%, transparent 50%, transparent); -} - -/*--- GMAIL EXAMPLE-SPECIFIC CODE --*/ -.kd-list table.gmail tr .icons { - display:block; - width:60px; - padding-left:12px; - overflow:hidden; - white-space:nowrap; - line-height:35px; - font-size:13px; - color:#333; -} -.kd-list table.gmail tr .icons input[type=checkbox] { - vertical-align:middle; -} -.kd-list table.gmail tr .icons .kd-star { - vertical-align:middle; - margin-left:-2px; -} -.kd-list table.gmail tr .icons .kd-important { - display: inline-block; - height: 21px; - width: 21px; - vertical-align:middle; - margin-left:-6px; - background: url('../images/icons/important-unread.png') center center no-repeat; -} -.kd-list table.gmail tr .from { - left:72px; - width:176px; -} -.kd-list table.gmail tr .from a { - width:160px; - padding-left:16px; -} -.kd-list table.gmail tr.highlighted .from .new { - color:#222; - font-weight:bold; -} -.kd-list table.gmail tr .message { - left:248px; - right:88px; -} -.kd-list table.gmail tr .message a { - padding-left:16px; - color:#999; -} -.kd-list table.gmail tr .message .subject { - color:#333; -} -.kd-list table.gmail tr.highlighted .message .subject { - color:#222; - font-weight:bold; -} -.kd-list table.gmail tr .message .snippet:before { - content: " - "; -} -.kd-list table.gmail tr .date { - right:0; - width:88px; - text-align:right; -} -.kd-list table.gmail tr .date a { - width:60px; - padding-right:12px; - padding-left:16px; -} -.y-crush .kd-list table.gmail tr .icons { - line-height:24px; -} -.mobile .kd-list table.gmail .two-line .icons { - line-height:24px; -} -.mobile .kd-list table.gmail tr .message { - left:16px; - right:13px; - top:22px; -} -.mobile .kd-list table.gmail tr .message a { - padding-left:0; -} - -/*--- DOCLIST EXAMPLE-SPECIFIC CODE --*/ -.kd-list table.doclist tr .icons { - display:block; - width:45px; - padding-left:12px; - overflow:hidden; - white-space:nowrap; - line-height:35px; - font-size:13px; - color:#333; -} -.kd-list table.doclist tr .icons input[type=checkbox] { - vertical-align:middle; -} -.kd-list table.doclist tr .icons .kd-star { - vertical-align:middle; - margin-left:-2px; -} -.kd-list table.doclist tr .title { - left:57px; - right:88px; - font-weight:normal; -} -.kd-list table.doclist tr.highlighted .title { - font-weight:bold; -} -.kd-list table.doclist tr .title a { - padding-left:16px; -} -.kd-list table.doclist tr .date { - right:0; - width:88px; - text-align:right; -} -.kd-list table.doclist tr .date a { - width:60px; - padding-right:12px; - padding-left:16px; -} -.mobile .kd-list table.doclist tr .title { - left:57px; - right:7px; -} - -/*------------------------------------------------------------------ -Component: Footers -------------------------------------------------------------------*/ -.pageFooter{ - padding:11px 0px; - border-top:1px solid #ebebeb; - font-size:13px; -} -.pageFooter a:hover{ - text-decoration:underline; -} -.pageFooter, .pageFooter a{color:#999;} -.pageFooter ul.linklist.right{ - float:right; -} -.pageFooter ul.linklist.left{ - float:left; -} -.pageFooter ul.linklist > li, .pageFooter ul.linklist{ -/* display:inline;*/ - float:left; -} -.pageFooter ul.linklist > li{ - margin:0 8px; -} -.pageFooter ul.linklist .kd-menubutton{ - border-left:1px solid; - border-right:1px solid; - border-color:transparent; - margin:-11px 0 0; - padding:11px 7px; -} -.pageFooter ul.linklist .chatbutton{ - padding-top:8px; - padding-bottom:6px; - margin-right:60px; -} -.pageFooter ul.linklist .kd-menubutton.selected a{ - color:#000; -} -.pageFooter ul.linklist .kd-menubutton:hover, .pageFooter ul.linklist .kd-menubutton.selected{ - border-color:#ebebeb; -} -.pageFooter ul.linklist .kd-menubutton:hover a{ - text-decoration:none; -} -.pageFooter .kd-menubutton a{margin:0;} - -.pageFooter .kd-menubutton .kd-disclosureindicator{ - margin:4px 0 0 4px; - opacity:.6; -} -.pageFooter .kd-menubutton img{ - opacity:.6; -} -.pageFooter .kd-menubutton:hover .kd-disclosureindicator, .pageFooter .kd-menubutton:hover img, .pageFooter .kd-menubutton.selected img{ - opacity:.8; -} -.pageFooter .kd-menulist{ - -webkit-box-shadow: 0px -2px 4px rgba(0,0,0,0.2); - -moz-box-shadow: 0px -2px 4px rgba(0,0,0,0.2); - box-shadow: 0 -2px 4px rgba(0,0,0,0.2); - outline:0; - border:1px solid #a7a7a7; - border-bottom:0; -} - -/*------------------------------------------------------------------ -Blue style override -------------------------------------------------------------------*/ - -.componentName, #stickersheet h2.componentName a { color: #dd4b3a; } -.kd-content-sidebar .kd-sidebarlistitem.selected > a { border-left-color:#dd4b3a; } -.kd-appbar .kd-appname, .kd-appbar .kd-appname a { color:#dd4b3a; } - -.kd-button-submit.disabled, .kd-button-submit.disabled:hover, .kd-button-submit.disabled:active { - border-color:#3079ee; - background-color: #4d90ff; -} -.kd-button-action.disabled, .kd-button-action.disabled:hover, .kd-button-action.disabled:active { - border-color: #b0281b; - background-color: #d14837; -} - -.kd-button-submit:focus, .kd-button-submit.focus{ - border-color:#4d90ff -} -.kd-button-action:focus, .kd-button-action.focus{ - border-color:#d14837; -} - -.kd-button-submit { - border-color: #3079ee; - background-color: #4d90ff; - background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90ff),to(#4787ed)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#4d90ff,#4787ed); - /* @alternate */ background-image: -moz-linear-gradient(top,#4d90ff,#4787ed); - /* @alternate */ background-image: -ms-linear-gradient(top,#4d90ff,#4787ed); - /* @alternate */ background-image: -o-linear-gradient(top,#4d90ff,#4787ed); - /* @alternate */ background-image: linear-gradient(top,#4d90ff,#4787ed); - /* filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#4d90ff',EndColorStr='#4787ed'); */ -} -.kd-button-submit:hover { - border-color: #2f5bb8; - background-color: #357ae9; - background-image: -webkit-gradient(linear,left top,left bottom,from(#4d90ff),to(#357ae9)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#4d90ff,#357ae9); - /* @alternate */ background-image: -moz-linear-gradient(top,#4d90ff,#357ae9); - /* @alternate */ background-image: -ms-linear-gradient(top,#4d90ff,#357ae9); - /* @alternate */ background-image: -o-linear-gradient(top,#4d90ff,#357ae9); - /* @alternate */ background-image: linear-gradient(top,#4d90ff,#357ae9); - /* filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#4d90ff',EndColorStr='#357ae9'); */ -} - -.kd-button-action { - margin-bottom: 16px; - border: 1px solid transparent; - color: #fff; - text-transform: uppercase; - letter-spacing: 1; - background-color: #d14837; - background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b3a),to(#d14837)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#dd4b3a,#d14837); - /* @alternate */ background-image: -moz-linear-gradient(top,#dd4b3a,#d14837); - /* @alternate */ background-image: -ms-linear-gradient(top,#dd4b3a,#d14837); - /* @alternate */ background-image: -o-linear-gradient(top,#dd4b3a,#d14837); - /* @alternate */ background-image: linear-gradient(top,#dd4b3a,#d14837); - /* filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#dd4b3a',EndColorStr='#d14837'); */ -} -.kd-button-action:hover { - border-color: #b0281b; - border-bottom-color: #af3020; - background-color: #c53728; - background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b3a),to(#c53728)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#dd4b3a,#c53728); - /* @alternate */ background-image: -moz-linear-gradient(top,#dd4b3a,#c53728); - /* @alternate */ background-image: -ms-linear-gradient(top,#dd4b3a,#c53728); - /* @alternate */ background-image: -o-linear-gradient(top,#dd4b3a,#c53728); - /* @alternate */ background-image: linear-gradient(top,#dd4b3a,#c53728); - /* filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#dd4b3a',EndColorStr='#c53728'); */ -} -.kd-button-action:active, -.kd-button-action:focus:active, -.kd-button-action.focus:active { - border-color: #992a1c; - background-color: #b0281b; - background-image: -webkit-gradient(linear,left top,left bottom,from(#dd4b3a),to(#b0281b)); - /* @alternate */ background-image: -webkit-linear-gradient(top,#dd4b3a,#b0281b); - /* @alternate */ background-image: -moz-linear-gradient(top,#dd4b3a,#b0281b); - /* @alternate */ background-image: -ms-linear-gradient(top,#dd4b3a,#b0281b); - /* @alternate */ background-image: -o-linear-gradient(top,#dd4b3a,#b0281b); - /* @alternate */ background-image: linear-gradient(top,#dd4b3a,#b0281b); -} - -.kd-accordion .expanded .row > a { color:#d14837; } diff --git a/core/src/main/javascript/google/registry/ui/css/registrar_imports_raw.css b/core/src/main/javascript/google/registry/ui/css/registrar_imports_raw.css deleted file mode 100644 index 3b1b547ca..000000000 --- a/core/src/main/javascript/google/registry/ui/css/registrar_imports_raw.css +++ /dev/null @@ -1,11 +0,0 @@ -@import 'admin-settings.css'; -@import 'console.css'; -@import 'contact-settings.css'; -@import 'contact-us.css'; -@import 'dashboard.css'; -@import 'epp.css'; -@import 'forms.css'; -@import 'kd_components.css'; -@import 'registry.css'; -@import 'resources.css'; -@import 'security-settings.css'; diff --git a/core/src/main/javascript/google/registry/ui/css/registry-lock.css b/core/src/main/javascript/google/registry/ui/css/registry-lock.css deleted file mode 100644 index 211d4ace6..000000000 --- a/core/src/main/javascript/google/registry/ui/css/registry-lock.css +++ /dev/null @@ -1,85 +0,0 @@ -/** Registry Lock */ - - .new-registry-lock #lock-domain-input { - width: 50% - } - - .new-registry-lock #lock-domain-submit { - margin-left: 5px; - } - - .registry-locks-table { - width: 1000px; - } - - .registry-locks-table td { - padding: 0.5em 0; - vertical-align: middle; - } - - .lock-confirm-modal { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - background: rgba(0,0,0,0.8); - z-index: 99999; - } - - .lock-confirm-modal > div { - width: 400px; - position: relative; - margin: 10% auto; - padding: 5px 20px 13px 20px; - border-radius: 10px; - background: #fff; - } - - .lock-confirm-modal .buttons-div { - margin-top: 10px; - display: flex; - justify-content: flex-end; - } - - .lock-confirm-modal button { - margin-left: 10px - } - -/** Following section taken from https://loading.io/css, under CC0 licensing. */ -.lds-ring { - display: inline-block; - position: relative; - width: 80px; - height: 80px; -} -.lds-ring div { - box-sizing: border-box; - display: block; - position: absolute; - width: 64px; - height: 64px; - margin: 8px; - border: 8px solid #000000; - border-radius: 50%; - animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; - border-color: #000000 transparent transparent transparent; -} -.lds-ring div:nth-child(1) { - animation-delay: -0.45s; -} -.lds-ring div:nth-child(2) { - animation-delay: -0.3s; -} -.lds-ring div:nth-child(3) { - animation-delay: -0.15s; -} -@keyframes lds-ring { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } -} -/** End of material taken from https://loading.io/css. */ diff --git a/core/src/main/javascript/google/registry/ui/css/registry.css b/core/src/main/javascript/google/registry/ui/css/registry.css deleted file mode 100644 index 8b998c00e..000000000 --- a/core/src/main/javascript/google/registry/ui/css/registry.css +++ /dev/null @@ -1,326 +0,0 @@ -body { - overflow-x: hidden; - overflow-y: hidden !important; - font-family: Arial, sans-serif; - font-size: 13px; - color: #222; -} - -h1 { - width: 100%; - font-size: 1.5em; - /* Bottom padding to get the paragraph text and Billing & resources to - * line up. */ - padding: 0.75em 0.75em 3px 0; -} - -#kd-social a, -#kd-social a:visited, -#reg-content a, -#reg-content a:visited { - color: #15c; -} - -pre { - font-family: "Courier New", Courier, monospace; - white-space: pre-wrap; -} - -table { - table-layout: fixed; -} - -td { - vertical-align: top; -} - -/* Set some explicit form styles so there's no jumping during toggle - * from readonly to editable. */ -input, textarea { - border-style: solid; - border-color: lightgrey; - border-width: 1px; -} - -input[readonly], textarea[readonly] { - resize: none; - border-color: white; -} - -textarea { - margin-bottom: 1em; - font-family: "Courier New", Courier, monospace; - font-size: 13px; - border: solid 1px #ddd; -} - -textarea[readonly] { - background-color: #eaeaea; -} - -hr { - border: none; - border-top: solid 1px #ebebeb; -} - -.hidden { - display: none; -} - -#kd-googlebar { - position: fixed; - width: 100%; - min-width: 985px; - padding: 1em 2em; - white-space: nowrap; - height: 37px; -} - -#kd-googlebar a.logo, -#kd-searchfield, -#kd-searchbutton { - position: static; - display: inline-block; -} - -#kd-search { - width: 470px; - margin-top: 2px; - padding-top: 0px; - padding-left: 3em; - white-space: nowrap; -} - -#kd-search form { - width: auto; -} - -input#kd-searchfield, -#kd-searchbutton { - height: 29px; - border: none; -} - -input#kd-searchfield { - width: 400px; - font-size: 12pt; -} - -#kd-searchbutton { - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} - -#kd-social { - position: fixed; - top: 1.25em; - right: 0; -} - -#kd-social .kd-name { - float: none; - color: #555; -} - -.kd-name a:before { - content: ' | '; - color: #999; -} - -/* Logo */ -a.logo { - vertical-align: middle; - font-size: 30px; - font-weight: 300; - font-family: "open sans", sans-serif; - color: #63666a; -} - -a.logo * { - vertical-align: middle; -} - -/* Reg prefix. */ - -.reg-user-id { - display: block; - height: 1.5em; - padding: 0; - margin-top: -10px; -} - -/* Misc. */ - -#loady { - position: absolute; - top: 5px; - right: -30px; -} - -.eppResponse { - color: #333; - margin-top: 1em; -} - -.kd-appbar { - padding: 1em 0; - position: fixed; - width: 100%; -} - -li.kd-menulistitem { - text-transform: none; -} - -#reg-nav.shown { - display: inherit; -} - -/* Begin fixed headers and nav selectors */ -#reg-app { - float: left; - margin-top: 64px; - width: 100%; -} - -.kd-butterbar { - position: absolute; - display: block; - margin-left: inherit; -} - -.kd-butterbar.shown { - -webkit-transform: translateX(-50%); - -ms-transform: translateX(-50%); - transform: translateX(-50%); -} - -.kd-appbar { - /* same as in reg-content below. lines the left edge of the - appbuttons and content area with the 'r' in registry. */ - padding-left: 173px; - padding-top: .75em; -} - -.kd-content-sidebar { - margin-left: 15px; - padding-left: 0; - border-left: 0; -} - -#reg-nav { - position: fixed; - left: 0; - top: 136px; - width: 155px; - margin: 0 25px 0 0; - z-index: 3; -} - -#reg-navlist li { - margin-left: 0; - padding-left: 0; -} - -#reg-navlist li ul { - margin-left: 0em; - padding-left: 2em; -} - -.reg-navlist-sub { - padding-left: 3px; -} - -#reg-navlist a { - margin-left: 0; - padding-left: 2em; - border-left: solid 3px white; -} - -#reg-navlist li ul, -#reg-navlist a { - line-height: 24px; -} - -#reg-navlist li ul li { - margin-left: -2em; -} - -#reg-navlist li ul li a { - padding-left: 3em; -} - -#reg-navlist a.domain-active-nav { - border-left: solid 3px red; - font-weight: bold; - color: #bf624B; -} - -#reg-content-and-footer { - position: absolute; - top: 136px; - left: 173px; - bottom: 0; - width: calc(100% - 173px); - margin: 0; - padding: 25px 0 1em 0; - overflow-y: scroll !important; - overflow-x: hidden; -} - -#reg-content { - margin-bottom: 100px; -} - -#reg-content, -.pageFooter { - width: 75%; -} - -#debug { - position: absolute; - top: 127px; - right: 0; - width: 15%; - border-left: solid 1px grey; - padding-left: 1em; -} - -/* End fixed headers and nav selectors */ - -#reg-content, -#reg-login { - min-height: 400px; -} - -.reg-select { - margin-left: 23px; -} - -div#reg-deprecation-warning { - position: fixed; - top: 64px; - width: 100%; - left: 0; - text-align: center; - background-color: #ba2a1a; - font-size: 0.6svw; -} - -div#reg-deprecation-warning h1 { - color: #ffffff; -} - -div#reg-deprecation-warning a { - color: #add8e6; -} - -div#reg-accessing-as-role { - margin-top: 40px; -} - -@media screen and (max-width: 1600px) { - div#reg-deprecation-warning { - font-size: 0.85vw; - } -} diff --git a/core/src/main/javascript/google/registry/ui/css/resources.css b/core/src/main/javascript/google/registry/ui/css/resources.css deleted file mode 100644 index 2f197433d..000000000 --- a/core/src/main/javascript/google/registry/ui/css/resources.css +++ /dev/null @@ -1,28 +0,0 @@ -#domain-registrar-resources h2 { - border-top: solid 1px #eee; - padding-top: 1em; - margin-top: 1em; -} - -#domain-registrar-resources h2 img { - vertical-align: middle; - margin-right: 10px; -} - -#domain-registrar-resources h2 + p, -#domain-registrar-resources button, -#domain-registrar-resources em { - margin-left: 34px; /* Folder icon + ^^ 10px more */ -} - -#domain-registrar-resources h2 + p { - padding-top: 1em; -} - -#domain-registrar-resources a { - color: white !important; -} - -#domain-registrar-resources em { - color: red; -} diff --git a/core/src/main/javascript/google/registry/ui/css/security-settings.css b/core/src/main/javascript/google/registry/ui/css/security-settings.css deleted file mode 100644 index 4eee5d4fc..000000000 --- a/core/src/main/javascript/google/registry/ui/css/security-settings.css +++ /dev/null @@ -1,67 +0,0 @@ -/** Security Settings */ -#domain-registrar-phone-passcode, -#domain-registrar-phone-passcode input { - color: #3D9200; -} - -div#ips div.ip { - width: 209px; -} - -#newIp { - width: 187px; - margin-left: 0.5em; -} - -div#ips.editing div.ip input, -div#ips.editing div.ip button[type=button] { - display: inline-block; - height: 27px; - line-height: 27px; - background: #ebebeb; - vertical-align: top; - border: none; - border-bottom: solid 3px white; -} - -div#ips.editing div.ip input { - width: 169px; - margin: 0; - padding: 0; - color: #555; - padding-left: 5px ! important; -} - -div#ips.editing div.ip input[readonly] { - margin-left: 0.5em; -} - -div#ips.editing div.ip button[type=button] { - float: right; - margin-left: -2px; - width: 30px; - min-width: 30px; - height: 30px; - color: grey; - font-size: 1.1em; -} - -div#ips.editing div.ip button[type=button]:hover { - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; -} - -div#ips.editing div.ip button[type=button] i { - font-style: normal; -} - -div#ips.editing .kd-errormessage { - margin-left: 0.5em; -} - -.item td.certificate h4 { - margin-top: 1em; - text-transform: lowercase; - border: solid 1px red; -} diff --git a/core/src/main/javascript/google/registry/ui/externs/json.js b/core/src/main/javascript/google/registry/ui/externs/json.js deleted file mode 100644 index 83f0f789d..000000000 --- a/core/src/main/javascript/google/registry/ui/externs/json.js +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -/** - * @fileoverview External JSON definitions. The purpose of this file is to give - * type information to the JavaScript compiler so it won't rename these - * properties. - * @externs - */ - -/** - * @suppress {duplicate} - */ -var registry = {}; - - -/** - * @suppress {duplicate} - */ -registry.json = {}; - -registry.json.locks = {}; - -/** - * @typedef {{ - * domainName: string, - * lockedTime: string, - * lockedBy: string, - * userCanUnlock: boolean, - * isLockPending: boolean, - * isUnlockPending: boolean - * }} - */ -registry.json.locks.ExistingLock; - -/** - * @typedef {{ - * clientId: string, - * email: string, - * details: !Array., - * lockEnabledForContact: boolean - * }} - */ -registry.json.locks.ExistingLocksResult; - -/** - * @typedef {{ - * status: string, - * message: string, - * results: !Array. - * }} - */ -registry.json.locks.ExistingLocksResponse; - -registry.json.ote = {}; - -/** - * @typedef {{ - * description: string, - * requirement: number, - * timesPerformed: number, - * completed: boolean - * }} - */ -registry.json.ote.OteStatusDetail; - - -/** - * @typedef {{ - * clientId: string, - * completed: boolean, - * details: !Array. - * }} - */ -registry.json.ote.OteStatusResult; - - -/** - * @typedef {{ - * status: string, - * message: string, - * results: !Array. - * }} - */ -registry.json.ote.OteStatusResponse; - - -/** - * @constructor - * @template T - */ -registry.json.Response = function() {}; - - -/** - * Request state which can be `SUCCESS` or `ERROR`. - * @type {string} - */ -registry.json.Response.prototype.status; - - -/** - * @type {string} - */ -registry.json.Response.prototype.message; - - -/** - * @type {string|undefined} - */ -registry.json.Response.prototype.field; - - -/** - * @type {!Array.} - */ -registry.json.Response.prototype.results; - - -// XXX: Might not need undefineds here. -/** - * @typedef {{ - * allowedTlds: !Array, - * registrarId: string, - * clientCertificate: string?, - * clientCertificateHash: string?, - * failoverClientCertificate: string?, - * failoverClientCertificateHash: string?, - * driveFolderId: string?, - * ianaIdentifier: (number?|undefined), - * icannReferralEmail: string, - * ipAddressAllowList: !Array, - * emailAddress: (string?|undefined), - * lastUpdateTime: string, - * url: (string?|undefined), - * phonePasscode: (string?|undefined), - * phoneNumber: (string?|undefined), - * faxNumber: (string?|undefined), - * localizedAddress: registry.json.RegistrarAddress, - * whoisServer: (string?|undefined), - * referralUrl: (string?|undefined), - * contacts: !Array., - * registryLockAllowed: boolean - * }} - */ -registry.json.Registrar; - - -/** - * @typedef {{ - * street: !Array., - * city: string, - * state: (string?|undefined), - * zip: (string?|undefined), - * countryCode: string - * }} - */ -registry.json.RegistrarAddress; - - -/** - * @typedef {{ - * name: (string?|undefined), - * emailAddress: string, - * visibleInWhoisAsAdmin: boolean, - * visibleInWhoisAsTech: boolean, - * visibleInDomainWhoisAsAbuse: boolean, - * phoneNumber: (string?|undefined), - * faxNumber: (string?|undefined), - * types: (string?|undefined), - * allowedToSetRegistryLockPassword: boolean, - * registryLockAllowed: boolean, - * registryLockEmailAddress: (string?|undefined) - * }} - */ -registry.json.RegistrarContact; diff --git a/core/src/main/javascript/google/registry/ui/js/component.js b/core/src/main/javascript/google/registry/ui/js/component.js deleted file mode 100644 index 696130710..000000000 --- a/core/src/main/javascript/google/registry/ui/js/component.js +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.Component'); - -goog.forwardDeclare('registry.Console'); -goog.require('goog.events.EventHandler'); -goog.require('registry.util'); - - - -/** - * Base component for UI. - * - *
- * ui/js/component.js - Base UI class.
- *       ^
- *       |
- *       edit_item.js - Common controls for editable items.
- *       ^
- *        \
- *         |-ui/js/resource_component.js - JSON resources
- *                 ^
- *                  \
- *                   |- ui/js/registrar/settings.js
- * 
- * - * @param {!registry.Console} cons the console singleton. - * @constructor - * @extends {goog.events.EventHandler} - */ -registry.Component = function(cons) { - registry.Component.base(this, 'constructor'); - - /** @type {!registry.Console} */ - this.console = cons; - - /** - * The hashPath this component is mapped by. This is set by the - * console after construction. - * @type {string} - */ - this.basePath = ''; - - /** - * Bean counter that's used by `addRemBtnHandlers`, - * e.g. `typeCounts['host']++` when user adds or removes. - * @type {!Object.} - * @protected - */ - this.typeCounts = {}; - - /** - * Stateful UI/server session model. - * @type {?Object.} - */ - this.model = null; -}; -goog.inherits(registry.Component, goog.events.EventHandler); - - -/** - * Subclasses should override this to implement panel display. - * @param {string} id The target resource id. - */ -registry.Component.prototype.bindToDom = function(id) { - registry.util.unbutter(); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/console.js b/core/src/main/javascript/google/registry/ui/js/console.js deleted file mode 100644 index 309576b76..000000000 --- a/core/src/main/javascript/google/registry/ui/js/console.js +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.Console'); - -goog.require('goog.Disposable'); -goog.require('goog.History'); -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.events.KeyCodes'); -goog.require('goog.history.EventType'); -goog.require('registry.util'); - -goog.forwardDeclare('goog.events.KeyEvent'); - - - -/** - * Abstract console for both admin and registrar console UIs. - * @constructor - * @extends {goog.Disposable} - */ -registry.Console = function() { - registry.Console.base(this, 'constructor'); - - /** - * @type {!goog.History} - * @protected - */ - this.history = new goog.History(); -}; -goog.inherits(registry.Console, goog.Disposable); - -/** - * Registers the console's events and sets everything up. - * - * Should be called after the constructor. - * - * The reason this isn't done in the constructor is that this is a base class - * designed to be extended. We have to wait for the actual implementation to - * finish constructing before using it. - */ -registry.Console.prototype.setUp = function() { - goog.events.listen( - this.history, - goog.history.EventType.NAVIGATE, - goog.bind(this.handleHashChange, this)); - - this.bindToDom(); - - // goog.History always starts off as "not enabled", meaning it doesn't trigger - // the listeners on change. - // - // When it's set to be enabled, it will start triggering the listeners on - // every change, but it also triggers the listeners immediately with the - // current history entry. - // - // This means the handleHashChange listener registered above will be called - // now. - this.history.setEnabled(true); -}; - - -/** - * Helper to setup permanent page elements. - */ -registry.Console.prototype.bindToDom = function() { - registry.util.unbutter(); - goog.events.listen(goog.dom.getRequiredElement('kd-searchbutton'), - goog.events.EventType.CLICK, - goog.bind(this.onSearch_, this)); - goog.events.listen(goog.dom.getRequiredElement('kd-searchfield'), - goog.events.EventType.KEYUP, - goog.bind(this.onSearchFieldKeyUp_, this)); - goog.events.listen( - goog.dom.getElementByClass(goog.getCssName('kd-butterbar-dismiss')), - goog.events.EventType.CLICK, - registry.util.unbutter); -}; - - -/** - * Subclasses should override to visit the hash token given by - * `goog.History.getToken()`. - */ -registry.Console.prototype.handleHashChange = goog.abstractMethod; - - -/** - * @param {string} resourcePath Resource description path. - */ -registry.Console.prototype.view = function(resourcePath) { - // Setting the new history token will also trigger the handleHashChange - // listener registered in the setUp() function. - this.history.setToken(resourcePath); -}; - - -/** - * Handler for search bar. - * @private - */ -registry.Console.prototype.onSearch_ = function() { - var qElt = goog.dom.getRequiredElement('kd-searchfield'); - if (qElt.getAttribute('disabled')) { - return; - } - var query = qElt.value; - if (query == '') { - return; - } - // Filtering this value change event. - qElt.setAttribute('disabled', true); - qElt.value = ''; - this.view(query); - qElt.removeAttribute('disabled'); -}; - - -/** - * Handler for key press in the search input field. - * @param {!goog.events.KeyEvent} e Key event to handle. - * @return {boolean} Whether the event should be continued or cancelled. - * @private - */ -registry.Console.prototype.onSearchFieldKeyUp_ = function(e) { - if (e.keyCode == goog.events.KeyCodes.ENTER) { - this.onSearch_(); - return false; - } - return true; -}; diff --git a/core/src/main/javascript/google/registry/ui/js/edit_item.js b/core/src/main/javascript/google/registry/ui/js/edit_item.js deleted file mode 100644 index d0e8428b7..000000000 --- a/core/src/main/javascript/google/registry/ui/js/edit_item.js +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.EditItem'); - -goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.soy'); -goog.require('registry.Component'); -goog.require('registry.soy.console'); -goog.require('registry.util'); - -goog.forwardDeclare('registry.Console'); - - - -/** - * An editable item, with Edit and Save/Cancel buttons in the appbar. - * @param {!registry.Console} cons - * @param {function()} itemTmpl - * @param {boolean} isEditable - * @constructor - * @extends {registry.Component} - */ -registry.EditItem = function(cons, itemTmpl, isEditable) { - registry.EditItem.base(this, 'constructor', cons); - - /** - * @type {!Function} - */ - this.itemTmpl = itemTmpl; - - /** - * Optional current target resource id. - * @type {?string} - */ - this.id = null; - - /** - * Should the "edit" button be enabled? - * @type {boolean} - */ - this.isEditable = isEditable; - - /** - * Transitional id for next resource during create. - * @type {?string} - */ - this.nextId = null; -}; -goog.inherits(registry.EditItem, registry.Component); - - -/** @override */ -registry.EditItem.prototype.bindToDom = function(id) { - registry.EditItem.base(this, 'bindToDom', id); - this.id = id; - this.nextId = null; - this.setupAppbar(); -}; - - -/** Setup appbar save/edit buttons. */ -registry.EditItem.prototype.setupAppbar = function() { - goog.soy.renderElement(goog.dom.getRequiredElement('reg-app-buttons'), - registry.soy.console.appbarButtons); - goog.events.listen(goog.dom.getRequiredElement('reg-app-btn-add'), - goog.events.EventType.CLICK, - goog.bind(this.add, this)); - goog.events.listen(goog.dom.getRequiredElement('reg-app-btn-edit'), - goog.events.EventType.CLICK, - goog.bind(this.edit, this)); - goog.events.listen(goog.dom.getRequiredElement('reg-app-btn-save'), - goog.events.EventType.CLICK, - goog.bind(this.save, this)); - goog.events.listen(goog.dom.getRequiredElement('reg-app-btn-cancel'), - goog.events.EventType.CLICK, - goog.bind(this.cancel, this)); - goog.events.listen(goog.dom.getRequiredElement('reg-app-btn-back'), - goog.events.EventType.CLICK, - goog.bind(this.back, this)); - // Show the add/edit buttons only if isEditable. - // "edit" is shown if we have an item's ID - // "add" is shown if we don't have an item's ID - registry.util.setVisible('reg-app-btns-edit', this.isEditable && !!this.id); - registry.util.setVisible('reg-app-btn-add', this.isEditable && !this.id); -}; - - -/** - * Retrieve item from server. Overrides should callback to - * `#handleFetchItem(string, !Object)`. - * @param {string} id item id. - */ -registry.EditItem.prototype.fetchItem = goog.abstractMethod; - - -/** - * Handle result decoding and display. - * @param {string} id The requested ID/name, for error message. - * @param {!Object} rsp The requested object. - */ -registry.EditItem.prototype.handleFetchItem = goog.abstractMethod; - - -/** Subclasses should override to continue processing after fetch. */ -registry.EditItem.prototype.processItem = function() {}; - - -/** - * Show the item. - * @param {!Object} objArgs - */ -registry.EditItem.prototype.renderItem = function(objArgs) { - goog.soy.renderElement(goog.dom.getRequiredElement('reg-content'), - this.itemTmpl, - objArgs); - this.runAfterRender(objArgs); -}; - - -/** - * @return {boolean} if the component is currently being edited. - */ -registry.EditItem.prototype.isEditing = function() { - return goog.dom.classlist.contains( - goog.dom.getElement('reg-app'), goog.getCssName('editing')); -}; - - -/** - * Toggles the editing state of a component. This will first hide the - * elements of the `shown` class, then adds the `editing` - * style to the component, then shows the elements that had the `hidden` - * class. - */ -registry.EditItem.prototype.toggleEdit = function() { - // Toggle appbar buttons. - var addBtn = goog.dom.getRequiredElement('reg-app-btn-add'); - var editBtns = goog.dom.getRequiredElement('reg-app-btns-edit'); - var saveBtns = goog.dom.getRequiredElement('reg-app-btns-save'); - var editing = goog.dom.classlist.contains(saveBtns, - registry.util.cssShown); - if (editing) { - registry.util.setVisible(saveBtns, false); - if (this.id) { - registry.util.setVisible(editBtns, true); - } else { - registry.util.setVisible(addBtn, true); - } - } else { - if (this.id) { - registry.util.setVisible(editBtns, false); - } else { - registry.util.setVisible(addBtn, false); - } - registry.util.setVisible(saveBtns, true); - } - // Then page contents. - var parentElt = goog.dom.getElement('reg-content'); - var shownCssName = goog.getCssName('shown'); - var hiddenCssName = goog.getCssName('hidden'); - var shown = goog.dom.getElementsByClass(shownCssName, parentElt); - var hidden = goog.dom.getElementsByClass(hiddenCssName, parentElt); - - for (var i = 0; i < shown.length; i++) { - goog.dom.classlist.addRemove(shown[i], shownCssName, hiddenCssName); - } - - // Then add editing styles. - var editingCssName = goog.getCssName('editing'); - var startingEdit = !goog.dom.classlist.contains(parentElt, editingCssName); - if (startingEdit) { - goog.dom.classlist.remove(parentElt, editingCssName); - } else { - goog.dom.classlist.add(parentElt, editingCssName); - } - - // The show hiddens. - for (var i = 0; i < hidden.length; i++) { - goog.dom.classlist.addRemove(hidden[i], hiddenCssName, shownCssName); - } -}; - - -/** - * Subclasses should override to enhance the default model. - * @return {!Object.} - */ -registry.EditItem.prototype.newModel = function() { - return {item: {}}; -}; - - -// N.B. setting these as abstract precludes their correct binding in -// setupAppbar. -/** Show add item panel. */ -registry.EditItem.prototype.add = function() {}; - - -/** Go back from item to collection view. */ -registry.EditItem.prototype.back = function() {}; - - -/** Sets up initial edit model state and then called edit(objArgs). */ -registry.EditItem.prototype.edit = function() { - var objArgs = this.model; - if (objArgs == null) { - objArgs = this.newModel(); - } - // XXX: This is vestigial. In the new msg format, this pollutes the - // server-model state. Should be carried elsewhere. - objArgs.readonly = false; - this.renderItem(objArgs); - this.setupEditor(objArgs); - this.toggleEdit(); -}; - - -/** - * Save the current item. Calls either create if creating a new - * object or update otherwise. - */ -registry.EditItem.prototype.save = function() { - if (this.model == null) { - this.sendCreate(); - } else { - this.sendUpdate(); - } -}; - - -/** - * Resets to non-editing, readonly state, or visits home screen if the - * page was in on a create panel. - */ -registry.EditItem.prototype.cancel = function() { - this.toggleEdit(); - // XXX: The presence of a model is sufficient for non-collection pages, but an - // empty id also means go to the collection in collection pages. Should - // be simplified. - if (this.model && this.id != '') { - this.model.readonly = true; - this.renderItem(this.model); - } else { - this.bindToDom(''); - } -}; - - -/** - * Called after this.renderItem(), to allow for further setup of - * editing. - * - * TODO(b/122661518): merge this with runAfterRender so we don't have two - * similar methods - * @param {!Object} objArgs - */ -registry.EditItem.prototype.setupEditor = function(objArgs) {}; - -/** - * Called at the end of this.renderItem() to allow for registration - * of listeners and other tasks that depend on the existence of the items in the - * DOM - * @param {!Object} objArgs - */ -registry.EditItem.prototype.runAfterRender = function(objArgs) {}; - - -// XXX: These should really take @param {object} which is the form. Alas the -// only override which doesn't work this way, ResourceComponent.sendCreate -// breaks this opportunity. Hmmm... -/** Subclasses should extract form values and send them to the server. */ -registry.EditItem.prototype.sendCreate = goog.abstractMethod; - - -/** Subclasses should extract form values and send them to the server. */ -registry.EditItem.prototype.sendUpdate = goog.abstractMethod; - - -/** Subclasses should extract form values and send them to the server. */ -registry.EditItem.prototype.sendDelete = goog.abstractMethod; - - -/** - * Subclasses should override to populate update queryParams with form - * fields as needed. `queryParams.nextId` MUST be set to the - * new object's ID. - * @param {!Object} queryParams - */ -registry.EditItem.prototype.prepareUpdate = goog.abstractMethod; - - -/** - * Subclasses should provide a function to parse JSON response from server and - * return a result object as described below. - * @param {!Object} rsp Decoded JSON response from the server. - * @return {!Object} a result object describing next steps. On - * success, if next is defined, visit(ret.next) is called, otherwise - * if err is set, the butterbar message is set to it. - */ -registry.EditItem.prototype.handleUpdateResponse = goog.abstractMethod; diff --git a/core/src/main/javascript/google/registry/ui/js/forms.js b/core/src/main/javascript/google/registry/ui/js/forms.js deleted file mode 100644 index bf770ff7a..000000000 --- a/core/src/main/javascript/google/registry/ui/js/forms.js +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.forms'); - -goog.require('goog.array'); -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); -goog.require('goog.dom.classlist'); -goog.require('goog.dom.forms'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.events.KeyCodes'); -goog.require('registry.util'); - -goog.forwardDeclare('goog.events.KeyEvent'); - - -/** - * Sets the focus on a form field (if it exists). - * @param {Element|string} field Form field (or ID) to focus. - */ -registry.forms.focus = function(field) { - field = goog.dom.getElement(field); - if (field !== null && goog.dom.isFocusable(field)) { - goog.dom.forms.focusAndSelect(field); - } -}; - - -/** - * Displays a form field error, or butters if no field is specified. - * @param {string} message Human-readable explanation of why this field is evil. - * @param {string=} opt_field Erroneous field name. - */ -registry.forms.displayError = function(message, opt_field) { - if (opt_field === undefined) { - registry.util.butter(message); - return; - } - var input = goog.dom.getElement(opt_field) || - goog.dom.getElement(opt_field + '[0]'); - // XXX: Transitioning to use of form.eltId instead of DOM id. If DOM id - // lookup fails, then search forms for the named field. - if (opt_field != null && input === null) { - for (var fNdx in document.forms) { - var form = document.forms[fNdx]; - if (form[opt_field]) { - input = form[opt_field]; - break; - } - } - } - if (input !== null) { - goog.dom.classlist.add(input, goog.getCssName('kd-formerror')); - goog.dom.insertSiblingAfter( - goog.dom.createDom(goog.dom.TagName.DIV, - goog.getCssName('kd-errormessage'), - message), - input); - registry.forms.focus(input); - } else { - registry.util.butter(opt_field + ': ' + message); - } -}; - - -/** Removes error markup from whois settings form. */ -registry.forms.resetErrors = function() { - registry.util.unbutter(); - goog.array.forEach( - goog.dom.getElementsByClass(goog.getCssName('kd-formerror')), - function(field) { - goog.dom.classlist.remove(field, goog.getCssName('kd-formerror')); - }); - goog.array.forEach( - goog.dom.getElementsByClass(goog.getCssName('kd-errormessage')), - goog.dom.removeNode); -}; - - -/** - * Adds enter key listeners to all form fields. - * @param {!Element} container Parent element containing INPUT fields. - * @param {function()} callback Called when enter is pressed in a field. - */ -registry.forms.listenFieldsOnEnter = function(container, callback) { - var handler = goog.partial(registry.forms.onFieldKeyUp_, callback); - goog.array.forEach( - goog.dom.getElementsByTagNameAndClass( - goog.dom.TagName.INPUT, undefined, container), - function(field) { - goog.events.listen(field, goog.events.EventType.KEYUP, handler); - }); -}; - - -/** - * Event handler that saves form when enter is pressed in a form field. - * @param {function()} callback Called when key pressed is ENTER. - * @param {!goog.events.KeyEvent} e Key event to handle. - * @return {boolean} Whether the event should be continued or cancelled. - * @private - */ -registry.forms.onFieldKeyUp_ = function(callback, e) { - if (e.keyCode == goog.events.KeyCodes.ENTER) { - callback(); - return false; - } - return true; -}; - - -/** - * Toggles disabled state of a button or form element. - * @param {!Element} element Form element to disable. - * @param {boolean} enabled Enables element if true, or else disables it. - */ -registry.forms.setEnabled = function(element, enabled) { - if (enabled) { - goog.dom.classlist.remove(element, goog.getCssName('disabled')); - } else { - goog.dom.classlist.add(element, goog.getCssName('disabled')); - element.blur(); - } -}; diff --git a/core/src/main/javascript/google/registry/ui/js/menu_button.js b/core/src/main/javascript/google/registry/ui/js/menu_button.js deleted file mode 100644 index 1d238ee62..000000000 --- a/core/src/main/javascript/google/registry/ui/js/menu_button.js +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.MenuButton'); - -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.events'); -goog.require('goog.events.EventHandler'); -goog.require('goog.events.EventType'); - -goog.forwardDeclare('goog.events.BrowserEvent'); - - - -/** - * Kennedy style menu button. - * @param {!Element} button Menu button element. - * @constructor - * @extends {goog.events.EventHandler} - * @final - */ -registry.MenuButton = function(button) { - registry.MenuButton.base(this, 'constructor'); - - /** - * Outer menu button element. - * @private {!Element} - * @const - */ - this.button_ = button; - this.listen(button, goog.events.EventType.CLICK, this.onButtonClick_); - - /** - * Label that displays currently selected item. - * @private {!Element} - * @const - */ - this.label_ = - goog.dom.getRequiredElementByClass(goog.getCssName('label'), button); - - /** - * List of selectable items. - * @private {!Element} - * @const - */ - this.menu_ = - goog.dom.getRequiredElementByClass(goog.getCssName('kd-menulist'), - button); - - goog.array.forEach( - goog.dom.getElementsByClass(goog.getCssName('kd-menulistitem'), button), - function(item) { - this.listen(item, goog.events.EventType.CLICK, this.onItemClick_); - }, - this); -}; -goog.inherits(registry.MenuButton, goog.events.EventHandler); - - -/** - * Returns selected value in menu. - * @return {string} - */ -registry.MenuButton.prototype.getValue = function() { - return goog.dom.getTextContent( - goog.dom.getRequiredElementByClass( - goog.getCssName('selected'), - this.button_)); -}; - - -/** - * Main menu button handler. - * @param {!goog.events.BrowserEvent} e - * @private - */ -registry.MenuButton.prototype.onButtonClick_ = function(e) { - if (goog.dom.classlist.contains(this.button_, goog.getCssName('selected'))) { - return; - } - e.stopPropagation(); - goog.dom.classlist.add(this.button_, goog.getCssName('selected')); - goog.dom.classlist.add(this.menu_, goog.getCssName('shown')); - this.listenOnce(goog.dom.getDocument().body, goog.events.EventType.CLICK, - this.hideMenu_); -}; - - -/** - * Menu item selection handler. - * @param {!goog.events.BrowserEvent} e - * @private - */ -registry.MenuButton.prototype.onItemClick_ = function(e) { - e.stopPropagation(); - if (goog.dom.classlist.contains(this.button_, goog.getCssName('disabled'))) { - return; - } - goog.array.forEach( - goog.dom.getElementsByClass(goog.getCssName('kd-menulistitem'), - this.button_), - function(item) { - goog.dom.classlist.remove(item, goog.getCssName('selected')); - }, - this); - goog.asserts.assert(e.target instanceof Element); - goog.dom.classlist.add(e.target, goog.getCssName('selected')); - var text = goog.dom.getTextContent(e.target); - goog.dom.setTextContent(this.label_, text); - goog.events.fireListeners(this.button_, goog.events.EventType.CHANGE, - false, {newValue: text}); - this.hideMenu_(); -}; - - -/** - * Hide the menu. - * @private - */ -registry.MenuButton.prototype.hideMenu_ = function() { - goog.dom.classlist.remove(this.menu_, goog.getCssName('shown')); - goog.dom.classlist.remove(this.button_, goog.getCssName('selected')); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/admin_settings.js b/core/src/main/javascript/google/registry/ui/js/registrar/admin_settings.js deleted file mode 100644 index 089a861f7..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/admin_settings.js +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.registrar.AdminSettings'); - -goog.forwardDeclare('registry.registrar.Console'); -goog.require('goog.array'); -goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.json'); -goog.require('goog.net.XhrIo'); -goog.require('goog.soy'); -goog.require('registry.Resource'); -goog.require('registry.ResourceComponent'); -goog.require('registry.soy.registrar.admin'); - - - -/** - * Admin Settings page, such as allowed TLDs for this registrar. - * @param {!registry.registrar.Console} console - * @param {!registry.Resource} resource the RESTful resource for the registrar. - * @constructor - * @extends {registry.ResourceComponent} - * @final - */ -registry.registrar.AdminSettings = function(console, resource) { - registry.registrar.AdminSettings.base( - this, 'constructor', console, resource, - registry.soy.registrar.admin.settings, console.params.isAdmin, null); -}; -goog.inherits(registry.registrar.AdminSettings, registry.ResourceComponent); - - -/** @override */ -registry.registrar.AdminSettings.prototype.bindToDom = function(id) { - registry.registrar.AdminSettings.base(this, 'bindToDom', 'fake'); - goog.dom.removeNode(goog.dom.getRequiredElement('reg-app-btn-back')); -}; - -/** @override */ -registry.registrar.AdminSettings.prototype.runAfterRender = function(objArgs) { - const oteButton = goog.dom.getElement('btn-ote-status'); - if (oteButton) { - goog.events.listen( - oteButton, - goog.events.EventType.CLICK, - goog.bind( - this.oteStatusCheck_, this, objArgs.xsrfToken, objArgs.clientId), - false, this); - } -}; - -/** @override */ -registry.registrar.AdminSettings.prototype.setupEditor = function(objArgs) { - goog.dom.classlist.add( - goog.dom.getRequiredElement('tlds'), goog.getCssName('editing')); - var tlds = goog.dom.getElementsByClass( - goog.getCssName('tld'), goog.dom.getRequiredElement('tlds')); - goog.array.forEach(tlds, function(tld) { - var remBtn = goog.dom.getChildren(tld)[0]; - goog.events.listen( - remBtn, goog.events.EventType.CLICK, - goog.bind(this.onTldRemove_, this, remBtn)); - }, this); - this.typeCounts['reg-tlds'] = - objArgs.allowedTlds ? objArgs.allowedTlds.length : 0; - - goog.events.listen( - goog.dom.getRequiredElement('btn-add-tld'), goog.events.EventType.CLICK, - this.onTldAdd_, false, this); -}; - -/** - * Click handler for OT&E status checking button. - * @param {string} xsrfToken - * @param {string} clientId - * @private - */ -registry.registrar.AdminSettings.prototype.oteStatusCheck_ = function( - xsrfToken, clientId) { - goog.net.XhrIo.send('/registrar-ote-status', function(e) { - var response = - /** @type {!registry.json.ote.OteStatusResponse} */ - (e.target.getResponseJson(registry.Resource.PARSER_BREAKER_)); - var oteResultParent = goog.dom.getRequiredElement('ote-status-area-parent'); - if (response.status === 'SUCCESS') { - var results = response.results[0]; - goog.soy.renderElement( - oteResultParent, registry.soy.registrar.admin.oteResultsTable, - {completed: results.completed, detailsList: results.details}); - } else { - goog.soy.renderElement( - oteResultParent, registry.soy.registrar.admin.oteErrorArea, - {message: response.message}); - } - }, 'POST', goog.json.serialize({'clientId': clientId}), { - 'X-CSRF-Token': xsrfToken, - 'Content-Type': 'application/json; charset=UTF-8' - }); -}; - -/** - * Click handler for TLD add button. - * @private - */ -registry.registrar.AdminSettings.prototype.onTldAdd_ = function() { - const tldInputElt = goog.dom.getRequiredElement('newTld'); - const tldElt = goog.soy.renderAsFragment(registry.soy.registrar.admin.tld, { - name: 'allowedTlds[' + this.typeCounts['reg-tlds'] + ']', - tld: tldInputElt.value, - }); - goog.dom.appendChild(goog.dom.getRequiredElement('tlds'), tldElt); - var remBtn = goog.dom.getFirstElementChild(tldElt); - goog.dom.classlist.remove(remBtn, goog.getCssName('hidden')); - goog.events.listen( - remBtn, goog.events.EventType.CLICK, - goog.bind(this.onTldRemove_, this, remBtn)); - this.typeCounts['reg-tlds']++; - tldInputElt.value = ''; -}; - - -/** - * Click handler for TLD remove button. - * @param {!Element} remBtn The remove button. - * @private - */ -registry.registrar.AdminSettings.prototype.onTldRemove_ = function(remBtn) { - goog.dom.removeNode(goog.dom.getParentElement(remBtn)); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/console.js b/core/src/main/javascript/google/registry/ui/js/registrar/console.js deleted file mode 100644 index 70c878e66..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/console.js +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.registrar.Console'); - -goog.require('goog.Uri'); -goog.require('goog.dispose'); -goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.net.XhrIo'); -goog.require('registry.Console'); -goog.require('registry.Resource'); -goog.require('registry.registrar.AdminSettings'); -goog.require('registry.registrar.ContactSettings'); -goog.require('registry.registrar.ContactUs'); -goog.require('registry.registrar.Dashboard'); -goog.require('registry.registrar.RegistryLock'); -goog.require('registry.registrar.Resources'); -goog.require('registry.registrar.SecuritySettings'); -goog.require('registry.registrar.WhoisSettings'); -goog.require('registry.util'); - -goog.forwardDeclare('registry.Component'); - - - -/** - * The Registrar Console. - * @param {!Object} params Parameters to be passed into templates. These are - * a combination of configurable parameters (e.g. phone number) and - * user/session/registrar specific parameters. See - * registrar/Console.soy#.main for expected contents. - * @constructor - * @extends {registry.Console} - * @final - */ -registry.registrar.Console = function(params) { - registry.registrar.Console.base(this, 'constructor'); - - /** - * @type {!Object} - */ - this.params = params; - - /** - * Component that's currently embedded in the page. - * @type {?registry.Component} - * @private - */ - this.component_ = null; - - /** - * Last active nav element. - * @type {?Element} - */ - this.lastActiveNavElt; - - /** - * A map from the URL fragment to the component to show. - * - * @type {!Object.} - */ - this.pageMap = {}; - // Homepage. Displayed when there's no fragment, or when the fragment doesn't - // correspond to any view - this.pageMap[''] = registry.registrar.Dashboard; - // Updating the Registrar settings - this.pageMap['security-settings'] = registry.registrar.SecuritySettings; - this.pageMap['contact-settings'] = registry.registrar.ContactSettings; - this.pageMap['whois-settings'] = registry.registrar.WhoisSettings; - this.pageMap['contact-us'] = registry.registrar.ContactUs; - this.pageMap['resources'] = registry.registrar.Resources; - // Registry lock is enabled or not per registrar, but since we don't have the registrar object - // accessible here yet, show the link no matter what (the page will show an error message if - // registry lock isn't enabled for this registrar) - this.pageMap['registry-lock'] = registry.registrar.RegistryLock; - // For admin use. The relevant tab is only shown in Console.soy for admins, - // but we also need to remove it here, otherwise it'd still be accessible if - // the user manually puts '#admin-settings' in the URL. - // - // Both the Console.soy and here, the "hiding the admin console for non - // admins" is purely for "aesthetic / design" reasons and have NO security - // implications. - // - // The security implications are only in the backend where we make sure all - // changes are made by users with the correct access (in other words - we - // don't trust the client-side to secure our application anyway) - if (this.params.isAdmin) { - this.pageMap['admin-settings'] = registry.registrar.AdminSettings; - } -}; -goog.inherits(registry.registrar.Console, registry.Console); - - -/** - * Changes the content area depending on hash path. - * - *

Hash path is expected to be of the form: - * - *

- *   #type/id
- * 
- * - *

The `id` part may be appended by `()` to specify that the target - * should be a resource create page. - * - * @override - */ -registry.registrar.Console.prototype.handleHashChange = function() { - var hashToken = this.history.getToken(); - - var parts = hashToken.split('/'); - var type = ''; - var id = ''; - if (parts.length >= 1) { - type = parts[0]; - } - if (parts.length == 2) { - id = parts[1]; - } - - goog.net.XhrIo.cleanup(); - - var componentCtor = this.pageMap[type]; - if (componentCtor == undefined) { - componentCtor = this.pageMap['']; - } - var oldComponent = this.component_; - const resource = new registry.Resource( - new goog.Uri('/registrar-settings'), this.params.clientId, - this.params.xsrfToken); - this.component_ = new componentCtor(this, resource); - this.registerDisposable(this.component_); - this.component_.basePath = type; - this.component_.bindToDom(id); - - this.changeNavStyle(); - - goog.dispose(oldComponent); -}; - - -/** Change nav style. */ -registry.registrar.Console.prototype.changeNavStyle = function() { - var hashToken = this.history.getToken(); - // Path except id - var slashNdx = hashToken.lastIndexOf('/'); - slashNdx = slashNdx == -1 ? hashToken.length : slashNdx; - var regNavlist = goog.dom.getRequiredElement('reg-navlist'); - var path = hashToken.substring(0, slashNdx); - var active = regNavlist.querySelector('a[href="#' + path + '"]'); - if (active === null) { - registry.util.log('Unknown path or path form in changeNavStyle.'); - return; - } - if (this.lastActiveNavElt) { - goog.dom.classlist.remove( - this.lastActiveNavElt, goog.getCssName('domain-active-nav')); - } - goog.dom.classlist.add(active, goog.getCssName('domain-active-nav')); - this.lastActiveNavElt = active; -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/contact_settings.js b/core/src/main/javascript/google/registry/ui/js/registrar/contact_settings.js deleted file mode 100644 index d3311cd4e..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/contact_settings.js +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.registrar.ContactSettings'); - -goog.require('goog.array'); -goog.require('goog.dom'); -goog.require('goog.dom.TagName'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.json'); -goog.require('goog.soy'); -goog.require('registry.Resource'); -goog.require('registry.ResourceComponent'); -goog.require('registry.soy.registrar.contacts'); -goog.require('registry.util'); - -goog.forwardDeclare('registry.registrar.Console'); - - - -/** - * Contact Settings page. Registrar Contacts are not really a proper - * REST resource as they're still passed from the server as a member - * field of Registrar, so this class behaves like an item page, - * updating only that field of the Registrar object and not - * implementing the create action from edit_item. - * @param {!registry.registrar.Console} console - * @param {!registry.Resource} resource the RESTful resource for the registrar. - * @constructor - * @extends {registry.ResourceComponent} - * @final - */ -registry.registrar.ContactSettings = function(console, resource) { - registry.registrar.ContactSettings.base( - this, 'constructor', console, resource, - registry.soy.registrar.contacts.contact, console.params.isOwner, null); -}; -goog.inherits(registry.registrar.ContactSettings, registry.ResourceComponent); - - -/** @override */ -registry.registrar.ContactSettings.prototype.setupAppbar = function() { - registry.registrar.ContactSettings.base(this, 'setupAppbar'); - // Setup delete only on existing items, not on creates. - if (this.model != null) { - var deleteBtn = goog.dom.createDom( - goog.dom.TagName.BUTTON, { - type: 'button', - id: 'reg-app-btn-delete', - className: goog.getCssName('kd-button') - }, - 'Delete'); - goog.events.listen(deleteBtn, goog.events.EventType.CLICK, - goog.bind(this.sendDelete, this)); - goog.dom.insertSiblingBefore(deleteBtn, - goog.dom.getRequiredElement('reg-app-btn-cancel')); - } -}; - - -/** @override */ -registry.registrar.ContactSettings.prototype.renderItem = function(rspObj) { - var contentElt = goog.dom.getRequiredElement('reg-content'); - /** @type {!registry.json.RegistrarContact} */ - var contacts = rspObj.contacts; - if (this.id) { - var targetContactNdx; - var targetContact; - for (var c in contacts) { - var ct = contacts[c]; - if (ct.emailAddress == this.id) { - targetContactNdx = c; - targetContact = ct; - break; - } - } - if (!targetContact) { - registry.util.butter('No contact with the given email.'); - return; - } - var typesList = targetContact.types.toLowerCase().split(','); - var actualTypesLookup = {}; - for (var t in typesList) { - actualTypesLookup[typesList[t]] = true; - } - goog.soy.renderElement( - contentElt, - registry.soy.registrar.contacts.contact, - { - item: targetContact, - namePrefix: 'contacts[' + targetContactNdx + '].', - actualTypesLookup: actualTypesLookup, - readonly: (rspObj.readonly || false), - registryLockAllowedForRegistrar: rspObj.registryLockAllowed - }); - this.setupAppbar(); - this.setupPasswordElemIfNecessary_(targetContactNdx); - } else { - var contactsByType = {}; - for (var c in contacts) { - var contact = contacts[c]; - var types = contact.types; - if (!types) { - // If the contact has no types, synthesize an "OTHER" type so that it - // still will be displayed in the console. - types = 'OTHER'; - } - types = types.split(','); - for (var t in types) { - var type = types[t].toLowerCase(); - var contactsList = contactsByType[type]; - if (!contactsList) { - contactsByType[type] = contactsList = []; - } - contactsList.push(contact); - } - } - goog.soy.renderElement( - contentElt, - registry.soy.registrar.contacts.set, - {contactsByType: contactsByType }); - } -}; - - -/** @override */ -registry.registrar.ContactSettings.prototype.add = function() { - var newContactNdx = this.model.contacts.length; - goog.soy.renderElement(goog.dom.getRequiredElement('reg-content'), - registry.soy.registrar.contacts.contact, - { - item: {}, - namePrefix: 'contacts[' + newContactNdx + '].', - actualTypesLookup: {}, - readonly: false - }); - this.toggleEdit(); -}; - - -/** @override */ -registry.registrar.ContactSettings.prototype.sendDelete = function() { - var ndxToDel = null; - for (var i = 0; i < this.model.contacts.length; i++) { - var contact = this.model.contacts[i]; - if (contact.emailAddress == this.id) { - ndxToDel = i; - } - } - if (ndxToDel === null) { - throw new Error('Email to delete does not match model.'); - } - var modelCopy = /** @type {!Object} - */ (JSON.parse(goog.json.serialize(this.model))); - goog.array.removeAt(modelCopy.contacts, ndxToDel); - this.resource.update(modelCopy, goog.bind(this.handleDeleteResponse, this)); -}; - - -/** @override */ -registry.registrar.ContactSettings.prototype.prepareUpdate = - function(modelCopy) { - var form = registry.util.parseForm('item'); - var contact; - // Handle update/create. - if (this.id) { - // Update contact, so overwrite it in the model before sending - // back to server. - var once = false; - for (var c in form.contacts) { - if (once) { - throw new Error('More than one contact parsed from form: ' + c); - } - contact = form.contacts[c]; - modelCopy.contacts[c] = contact; - once = true; - } - } else { - // Add contact. - contact = form.contacts.pop(); - modelCopy.contacts.push(contact); - } - contact.visibleInWhoisAsAdmin = contact.visibleInWhoisAsAdmin == 'true'; - contact.visibleInWhoisAsTech = contact.visibleInWhoisAsTech == 'true'; - contact.visibleInDomainWhoisAsAbuse = - contact.visibleInDomainWhoisAsAbuse == 'true'; - contact.types = ''; - for (var tNdx in contact.type) { - if (contact.type[tNdx]) { - if (contact.types.length > 0) { - contact.types += ','; - } - contact.types += ('' + tNdx).toUpperCase(); - } - } - delete contact['type']; - // Override previous domain WHOIS abuse contact. - if (contact.visibleInDomainWhoisAsAbuse) { - for (var c in modelCopy.contacts) { - if (modelCopy.contacts[c].emailAddress != contact.emailAddress) { - modelCopy.contacts[c].visibleInDomainWhoisAsAbuse = false; - } - } - } - this.nextId = contact.emailAddress; -}; - - -// XXX: Should be hoisted up. -/** - * Handler for contact save that navigates to that item on success. - * Does nothing on failure as UI will be left with error messages for - * the user to resolve. - * @param {!Object} rsp Decoded JSON response from the server. - * @override - */ -registry.registrar.ContactSettings.prototype.handleCreateResponse = - function(rsp) { - this.handleUpdateResponse(rsp); - if (rsp.status == 'SUCCESS') { - this.console.view('contact-settings/' + this.nextId); - } - return rsp; -}; - - -/** - * Handler for contact delete that navigates back to the collection on success. - * Does nothing on failure as UI will be left with error messages for - * the user to resolve. - * @param {!Object} rsp Decoded JSON response from the server. - * @override - */ -registry.registrar.ContactSettings.prototype.handleDeleteResponse = - function(rsp) { - this.handleUpdateResponse(rsp); - if (rsp.status == 'SUCCESS') { - this.id = null; - this.console.view('contact-settings'); - } - return rsp; -}; - -// Show or hide the password based on what the user chooses -registry.registrar.ContactSettings.prototype.setupPasswordElemIfNecessary_ = - function(contactIndex) { - var showOrHidePasswordButton = goog.dom.getElement('showOrHideRegistryLockPassword') - var showOrHidePassword = function() { - var inputElement = goog.dom.getRequiredElement( - 'contacts[' + contactIndex + '].registryLockPassword') - var type = inputElement.getAttribute('type') - if (type === 'password') { - showOrHidePasswordButton.text = 'Hide password'; - inputElement.setAttribute('type', 'text'); - } else { - showOrHidePasswordButton.text = 'Show password'; - inputElement.setAttribute('type', 'password'); - } - }; - - if (showOrHidePasswordButton != null) { - goog.events.listen(showOrHidePasswordButton, - goog.events.EventType.CLICK, showOrHidePassword, false, this); - } -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/contact_us.js b/core/src/main/javascript/google/registry/ui/js/registrar/contact_us.js deleted file mode 100644 index 73b1f97eb..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/contact_us.js +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.registrar.ContactUs'); - -goog.require('goog.dom'); -goog.require('registry.Resource'); -goog.require('registry.ResourceComponent'); -goog.require('registry.soy.registrar.console'); - -goog.forwardDeclare('registry.registrar.Console'); - - - -/** - * Contact Us page. - * @param {!registry.registrar.Console} console - * @param {!registry.Resource} resource the RESTful resource for the registrar. - * @constructor - * @extends {registry.ResourceComponent} - * @final - */ -registry.registrar.ContactUs = function(console, resource) { - registry.registrar.ContactUs.base( - this, 'constructor', console, resource, - registry.soy.registrar.console.contactUs, console.params.isOwner, null); -}; -goog.inherits(registry.registrar.ContactUs, registry.ResourceComponent); - - -/** @override */ -registry.registrar.ContactUs.prototype.bindToDom = function(id) { - registry.registrar.ContactUs.base(this, 'bindToDom', ''); - goog.dom.removeChildren(goog.dom.getRequiredElement('reg-app-buttons')); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/dashboard.js b/core/src/main/javascript/google/registry/ui/js/registrar/dashboard.js deleted file mode 100644 index 660a87c3a..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/dashboard.js +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.registrar.Dashboard'); - -goog.require('goog.Timer'); -goog.require('goog.dom'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.soy'); -goog.require('goog.style'); -goog.require('registry.Component'); -goog.require('registry.soy.registrar.console'); - -goog.forwardDeclare('registry.registrar.Console'); - - - -/** - * Dashboard for Registrar Console. - * @param {!registry.registrar.Console} console - * @constructor - * @extends {registry.Component} - * @final - */ -registry.registrar.Dashboard = function(console) { - registry.registrar.Dashboard.base(this, 'constructor', console); - - /** @private {number} */ - this.x_ = 0; - - /** @private {?Element} */ - this.gear_ = null; - - /** @private {?goog.Timer} */ - this.timer_ = null; -}; -goog.inherits(registry.registrar.Dashboard, registry.Component); - - -/** @override */ -registry.registrar.Dashboard.prototype.bindToDom = function(id) { - registry.registrar.Dashboard.base(this, 'bindToDom', ''); - goog.dom.removeChildren(goog.dom.getRequiredElement('reg-app-buttons')); - goog.soy.renderElement(goog.dom.getElement('reg-content'), - registry.soy.registrar.console.dashboard, - this.console.params); - goog.events.listen(goog.dom.getElement('rotate'), - goog.events.EventType.CLICK, - goog.bind(this.rotate_, this)); - this.gear_ = goog.dom.getRequiredElement('gear'); -}; - - -/** - * Let's do the twist. - * @private - */ -registry.registrar.Dashboard.prototype.rotate_ = function() { - this.timer_ = new goog.Timer(10); - this.registerDisposable(this.timer_); - goog.events.listen(this.timer_, goog.Timer.TICK, - goog.bind(this.rotateCall_, this)); - this.timer_.start(); -}; - - -/** - * No really this time! - * @private - */ -registry.registrar.Dashboard.prototype.rotateCall_ = function() { - this.x_++; - goog.style.setStyle(this.gear_, 'transform', 'rotate(' + this.x_ + 'deg)'); - if (this.x_ == 360) { - this.timer_.stop(); - } -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/main.js b/core/src/main/javascript/google/registry/ui/js/registrar/main.js deleted file mode 100644 index 189f38d5b..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/main.js +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -/** - * @fileoverview Entry point for the registrar console. - */ - -goog.provide('registry.registrar.main'); - -goog.require('registry.registrar.Console'); - - -/** - * Instantiates a registry object, which syncs with the server. - * Sub-templates are invoked based on location/pathname, to choose - * either Registry or Registrar pages. - * - * @param {string} xsrfToken populated by server-side soy template. - * @param {string} clientId The registrar clientId. - * @param {boolean} isAdmin - * @param {boolean} isOwner - * @param {string} productName the product name displayed by the UI. - * @param {string} integrationEmail - * @param {string} supportEmail - * @param {string} announcementsEmail - * @param {string} supportPhoneNumber - * @param {string} technicalDocsUrl - * @param {string} environment - * @export - */ -registry.registrar.main = function( - xsrfToken, clientId, isAdmin, isOwner, productName, integrationEmail, - supportEmail, announcementsEmail, supportPhoneNumber, technicalDocsUrl, - environment) { - const console = new registry.registrar.Console({ - xsrfToken: xsrfToken, - clientId: clientId, - isAdmin: isAdmin, - isOwner: isOwner, - productName: productName, - integrationEmail: integrationEmail, - supportEmail: supportEmail, - announcementsEmail: announcementsEmail, - supportPhoneNumber: supportPhoneNumber, - technicalDocsUrl: technicalDocsUrl, - environment: environment, - }); - - console.setUp(); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/registry_lock.js b/core/src/main/javascript/google/registry/ui/js/registrar/registry_lock.js deleted file mode 100644 index fd4bfd5be..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/registry_lock.js +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2020 The Nomulus Authors. 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. - -goog.provide('registry.registrar.RegistryLock'); - -goog.forwardDeclare('registry.registrar.Console'); -goog.require('goog.array'); -goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.events'); -goog.require('goog.events.KeyCodes'); -goog.require('goog.events.EventType'); -goog.require('goog.json'); -goog.require('goog.net.XhrIo'); -goog.require('goog.soy'); -goog.require('registry.Resource'); -goog.require('registry.ResourceComponent'); -goog.require('registry.soy.registrar.registrylock'); - - -/** - * Registry Lock page, allowing the user to lock / unlock domains. - * @param {!registry.registrar.Console} console - * @param {!registry.Resource} resource the RESTful resource for the registrar. - * @constructor - * @extends {registry.ResourceComponent} - * @final - */ -registry.registrar.RegistryLock = function(console, resource) { - registry.registrar.RegistryLock.base( - this, 'constructor', console, resource, - registry.soy.registrar.registrylock.settings, false, null); -}; -goog.inherits(registry.registrar.RegistryLock, registry.ResourceComponent); - -registry.registrar.RegistryLock.prototype.runAfterRender = function(objArgs) { - this.isAdmin = objArgs.isAdmin; - this.clientId = objArgs.clientId; - this.xsrfToken = objArgs.xsrfToken; - - if (objArgs.registryLockAllowed) { - // Load the existing locks and display them in the table - goog.net.XhrIo.send( - '/registry-lock-get?clientId=' + objArgs.clientId, e => this.fillLocksPage_(e)); - } else { - goog.soy.renderElement( - goog.dom.getRequiredElement('locks-content'), - registry.soy.registrar.registrylock.lockNotAllowedOnRegistrar, - {supportEmail: objArgs.supportEmail}); - } -}; - -/** - * Removes the lock/unlock-confirmation modal if it exists - * @private - */ -const removeModalIfExists_ = function() { - var modalElement = goog.dom.getElement('lock-confirm-modal'); - if (modalElement != null) { - modalElement.parentElement.removeChild(modalElement); - } -} - -/** - * Clears the modal and displays the locks content (lock a new domain, existing locks) that was - * retrieved from the server. - * @private - */ -registry.registrar.RegistryLock.prototype.fillLocksPage_ = function(e) { - var response = - /** @type {!registry.json.locks.ExistingLocksResponse} */ - (e.target.getResponseJson(registry.Resource.PARSER_BREAKER_)); - if (response.status === 'SUCCESS') { - removeModalIfExists_(); - var locksDetails = response.results[0] - var locksContentDiv = goog.dom.getRequiredElement('locks-content'); - goog.soy.renderElement( - locksContentDiv, - registry.soy.registrar.registrylock.locksContent, - {locks: locksDetails.locks, - email: locksDetails.email, - lockEnabledForContact: locksDetails.lockEnabledForContact}); - - if (locksDetails.lockEnabledForContact) { - this.registryLockEmailAddress = locksDetails.email; - // Listen to the lock-domain 'submit' button click - var lockButton = goog.dom.getRequiredElement('button-lock-domain'); - goog.events.listen(lockButton, goog.events.EventType.CLICK, this.onLockDomain_, false, this); - // For all unlock buttons, listen and perform the unlock action if they're clicked - var unlockButtons = goog.dom.getElementsByClass('domain-unlock-button', locksContentDiv); - unlockButtons.forEach(button => - goog.events.listen(button, goog.events.EventType.CLICK, this.onUnlockDomain_, false, this)); - } - } else { - var errorDiv = goog.dom.getRequiredElement('modal-error-message'); - errorDiv.textContent = response.message; - errorDiv.removeAttribute('hidden'); - } -} - -/** - * Shows the lock/unlock confirmation modal - * @private - */ -registry.registrar.RegistryLock.prototype.showModal_ = function(targetElement, domain, isLock) { - var parentElement = targetElement.parentElement; - // attach the modal to the parent element so focus remains correct if the user closes the modal - var modalElement = goog.soy.renderAsElement( - registry.soy.registrar.registrylock.confirmModal, - {domain: domain, - isLock: isLock, - isAdmin: this.isAdmin, - emailAddress: this.registryLockEmailAddress}); - parentElement.prepend(modalElement); - if (domain == null) { - goog.dom.getRequiredElement('domain-lock-input-value').focus(); - } else { - var passwordElem = goog.dom.getElement('domain-lock-password'); - if (passwordElem != null) { - passwordElem.focus(); - } - } - // delete the modal when the user clicks the cancel button - goog.events.listen( - goog.dom.getRequiredElement('domain-lock-cancel'), - goog.events.EventType.CLICK, - removeModalIfExists_, - false, - this); - - // Listen to the "submit" click and also the user hitting enter - goog.events.listen( - goog.dom.getRequiredElement('domain-lock-submit'), - goog.events.EventType.CLICK, - e => this.lockOrUnlockDomain_(isLock, e), - false, - this); - - [goog.dom.getElement('domain-lock-password'), - goog.dom.getElement('domain-lock-input-value')].forEach(elem => { - if (elem != null) { - goog.events.listen( - elem, - goog.events.EventType.KEYPRESS, - e => { - if (e.keyCode === goog.events.KeyCodes.ENTER) { - this.lockOrUnlockDomain_(isLock, e); - } - }, - false, - this); - } - }); -} - -/** - * Locks or unlocks the specified domain - * @private - */ -registry.registrar.RegistryLock.prototype.lockOrUnlockDomain_ = function(isLock, e) { - var domain = goog.dom.getRequiredElement('domain-lock-input-value').value; - var passwordElem = goog.dom.getElement('domain-lock-password'); - var password = passwordElem == null ? null : passwordElem.value; - var relockDuration = this.getRelockDurationFromModal_() - goog.net.XhrIo.send('/registry-lock-post', - e => this.fillLocksPage_(e), - 'POST', - goog.json.serialize({ - 'registrarId': this.clientId, - 'domainName': domain, - 'isLock': isLock, - 'password': password, - 'relockDurationMillis': relockDuration - }), { - 'X-CSRF-Token': this.xsrfToken, - 'Content-Type': 'application/json; charset=UTF-8' - }); -} - -/** - * Returns the duration after which we will re-lock a locked domain. Will return null if we - * are locking a domain, or if the user selects the "Never" option - * @private - */ -registry.registrar.RegistryLock.prototype.getRelockDurationFromModal_ = function() { - var inputElements = goog.dom.getElementsByTagNameAndClass("input", "relock-duration-input"); - for (var i = 0; i < inputElements.length; i++) { - var elem = inputElements[i]; - if (elem.checked && elem.value !== "0") { - return elem.value; - } - } - return null; -} - -/** - * Click handler for unlocking domains (button click). - * @private - */ -registry.registrar.RegistryLock.prototype.onUnlockDomain_ = function(e) { - // the domain is stored in the button ID if it's the right type of button - var idRegex = /button-unlock-(.*)/ - var targetId = e.target.id; - var match = targetId.match(idRegex); - if (match) { - var domain = match[1]; - this.showModal_(e.target, domain, false); - } -} - -/** - * Click handler for lock-domain button. - * @private - */ -registry.registrar.RegistryLock.prototype.onLockDomain_ = function(e) { - this.showModal_(e.target, null, true); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/resources.js b/core/src/main/javascript/google/registry/ui/js/registrar/resources.js deleted file mode 100644 index e6116813e..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/resources.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.registrar.Resources'); - -goog.require('goog.dom'); -goog.require('registry.Resource'); -goog.require('registry.ResourceComponent'); -goog.require('registry.soy.registrar.console'); - -goog.forwardDeclare('registry.registrar.Console'); - - - -/** - * Resources and billing page. - * @param {!registry.registrar.Console} console - * @param {!registry.Resource} resource the RESTful resource for the registrar. - * @constructor - * @extends {registry.ResourceComponent} - * @final - */ -registry.registrar.Resources = function(console, resource) { - registry.registrar.Resources.base( - this, 'constructor', console, resource, - registry.soy.registrar.console.resources, console.params.isOwner, null); -}; -goog.inherits(registry.registrar.Resources, - registry.ResourceComponent); - - -/** @override */ -registry.registrar.Resources.prototype.bindToDom = function(id) { - registry.registrar.Resources.base(this, 'bindToDom', 'fake'); - goog.dom.removeNode(goog.dom.getRequiredElement('reg-app-btn-back')); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/security_settings.js b/core/src/main/javascript/google/registry/ui/js/registrar/security_settings.js deleted file mode 100644 index f699131c0..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/security_settings.js +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.registrar.SecuritySettings'); - -goog.require('goog.array'); -goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.events'); -goog.require('goog.events.EventType'); -goog.require('goog.soy'); -goog.require('registry.Resource'); -goog.require('registry.ResourceComponent'); -goog.require('registry.soy.registrar.security'); - -goog.forwardDeclare('registry.registrar.Console'); - - - -/** - * Security Settings page. - * @param {!registry.registrar.Console} console - * @param {!registry.Resource} resource the RESTful resource for the registrar. - * @constructor - * @extends {registry.ResourceComponent} - * @final - */ -registry.registrar.SecuritySettings = function(console, resource) { - registry.registrar.SecuritySettings.base( - this, 'constructor', console, resource, - registry.soy.registrar.security.settings, console.params.isOwner, null); -}; -goog.inherits(registry.registrar.SecuritySettings, registry.ResourceComponent); - - -/** @override */ -registry.registrar.SecuritySettings.prototype.bindToDom = function(id) { - registry.registrar.SecuritySettings.base(this, 'bindToDom', 'fake'); - goog.dom.removeNode(goog.dom.getRequiredElement('reg-app-btn-back')); -}; - - -/** @override */ -registry.registrar.SecuritySettings.prototype.setupEditor = - function(objArgs) { - goog.dom.classlist.add(goog.dom.getRequiredElement('ips'), - goog.getCssName('editing')); - var ips = goog.dom.getElementsByClass(goog.getCssName('ip'), - goog.dom.getRequiredElement('ips')); - goog.array.forEach(ips, function(ip) { - var remBtn = goog.dom.getChildren(ip)[0]; - goog.events.listen(remBtn, - goog.events.EventType.CLICK, - goog.bind(this.onIpRemove_, this, remBtn)); - }, this); - this.typeCounts['reg-ips'] = objArgs.ipAddressAllowList ? - objArgs.ipAddressAllowList.length : 0; - - goog.events.listen(goog.dom.getRequiredElement('btn-add-ip'), - goog.events.EventType.CLICK, - this.onIpAdd_, - false, - this); -}; - - -/** - * Click handler for IP add button. - * @private - */ -registry.registrar.SecuritySettings.prototype.onIpAdd_ = function() { - var ipInputElt = goog.dom.getRequiredElement('newIp'); - var ipElt = goog.soy.renderAsFragment(registry.soy.registrar.security.ip, { - name: 'ipAddressAllowList[' + this.typeCounts['reg-ips'] + ']', - ip: ipInputElt.value - }); - goog.dom.appendChild(goog.dom.getRequiredElement('ips'), ipElt); - var remBtn = goog.dom.getFirstElementChild(ipElt); - goog.dom.classlist.remove(remBtn, goog.getCssName('hidden')); - goog.events.listen(remBtn, goog.events.EventType.CLICK, - goog.bind(this.onIpRemove_, this, remBtn)); - this.typeCounts['reg-ips']++; - ipInputElt.value = ''; -}; - - -/** - * Click handler for IP remove button. - * @param {!Element} remBtn The remove button. - * @private - */ -registry.registrar.SecuritySettings.prototype.onIpRemove_ = - function(remBtn) { - goog.dom.removeNode(goog.dom.getParentElement(remBtn)); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/registrar/whois_settings.js b/core/src/main/javascript/google/registry/ui/js/registrar/whois_settings.js deleted file mode 100644 index a87d0dca6..000000000 --- a/core/src/main/javascript/google/registry/ui/js/registrar/whois_settings.js +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.registrar.WhoisSettings'); - -goog.require('goog.dom'); -goog.require('registry.Resource'); -goog.require('registry.ResourceComponent'); -goog.require('registry.soy.registrar.whois'); - -goog.forwardDeclare('registry.registrar.Console'); - - - -/** - * WHOIS Settings page. - * @param {!registry.registrar.Console} console - * @param {!registry.Resource} resource the RESTful resource for the registrar. - * @constructor - * @extends {registry.ResourceComponent} - * @final - */ -registry.registrar.WhoisSettings = function(console, resource) { - registry.registrar.WhoisSettings.base( - this, 'constructor', console, resource, - registry.soy.registrar.whois.settings, console.params.isOwner, null); -}; -goog.inherits(registry.registrar.WhoisSettings, registry.ResourceComponent); - - -/** @override */ -registry.registrar.WhoisSettings.prototype.bindToDom = function(id) { - registry.registrar.WhoisSettings.base(this, 'bindToDom', 'fake'); - goog.dom.removeNode(goog.dom.getRequiredElement('reg-app-btn-back')); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/resource.js b/core/src/main/javascript/google/registry/ui/js/resource.js deleted file mode 100644 index 7003a9b85..000000000 --- a/core/src/main/javascript/google/registry/ui/js/resource.js +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.Resource'); - -goog.require('goog.json'); -goog.require('registry.Session'); - -goog.forwardDeclare('goog.Uri'); - - - -/** - * Provide a CRUD view of a server resource. - * - * @param {!goog.Uri} baseUri Target RESTful resource. - * @param {string} id the ID of the target resource - * @param {string} xsrfToken Security token to pass back to the server. - * @extends {registry.Session} - * @constructor - */ -registry.Resource = function(baseUri, id, xsrfToken) { - registry.Resource.base(this, 'constructor', baseUri, xsrfToken); - /** @const @private {string} the ID of the target resource. */ - this.id_ = id; -}; -goog.inherits(registry.Resource, registry.Session); - - -/** - * Get the resource from the server. - * - * @param {!Object} args Params for server. - * @param {!Function} callback for retrieved resource. - */ -registry.Resource.prototype.read = function(args, callback) { - this.send_('read', args, callback); -}; - - -/** - * Update the resource on the server. - * - * @param {!Object} args params for server. - * @param {!Function} callback on success. - * @throws {!Exception} if the 'op' field is set on args. - */ -registry.Resource.prototype.update = function(args, callback) { - this.send_('update', args, callback); -}; - - -/** - * RESTful access to resources on the server. - * - * @param {string} opCode One of (create|read|update) - * @param {!Object} argsObj arguments for the operation. - * @param {!Function} callback For XhrIo result throws. - * @private - */ -registry.Resource.prototype.send_ = - function(opCode, argsObj, callback) { - // NB: must be declared this way in order to avoid compiler renaming - var req = {}; - req['op'] = opCode; - req['args'] = argsObj; - req['id'] = this.id_; - this.sendXhrIo(goog.json.serialize(req), callback); -}; - -/** - * JSON response prefix which prevents evaluation. - * @const - */ -registry.Resource.PARSER_BREAKER_ = ')]}\'\n'; diff --git a/core/src/main/javascript/google/registry/ui/js/resource_component.js b/core/src/main/javascript/google/registry/ui/js/resource_component.js deleted file mode 100644 index 469260978..000000000 --- a/core/src/main/javascript/google/registry/ui/js/resource_component.js +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.ResourceComponent'); - -goog.require('goog.dom'); -goog.require('goog.json'); -goog.require('goog.object'); -goog.require('registry.EditItem'); -goog.require('registry.forms'); -goog.require('registry.util'); - -goog.forwardDeclare('registry.Console'); -goog.forwardDeclare('registry.Resource'); - - - -/** - * The ResourceComponent class respresents server state for a named - * resource and binds UI CRUD operations on it, or its constituent - * collection. - * @param {!registry.Console} console console singleton. - * @param {!registry.Resource} resource the RESTful resource. - * @param {!Function} itemTmpl - * @param {boolean} isEditable if true, the "edit" button will be enabled - * @param {Function} renderSetCb may be null if this resource is only - * ever an item. - * @constructor - * @extends {registry.EditItem} - */ -registry.ResourceComponent = function( - console, - resource, - itemTmpl, - isEditable, - renderSetCb) { - registry.ResourceComponent.base( - this, 'constructor', console, itemTmpl, isEditable); - - /** @type {!registry.Resource} */ - this.resource = resource; - - /** @type {Function} */ - this.renderSetCb = renderSetCb; -}; -goog.inherits(registry.ResourceComponent, registry.EditItem); - - -/** @override */ -registry.ResourceComponent.prototype.renderItem = function(rspObj) { - // Augment the console parameters with the response object, we'll need both. - var params = goog.object.clone(this.console.params); - goog.object.extend(params, rspObj); - registry.ResourceComponent.base(this, 'renderItem', params); -}; - - -/** @override */ -registry.ResourceComponent.prototype.bindToDom = function(id) { - registry.ResourceComponent.base(this, 'bindToDom', id); - this.fetchItem(id); -}; - - -/** @override */ -registry.ResourceComponent.prototype.back = function() { - this.console.view(this.basePath); -}; - - -/** @override */ -registry.ResourceComponent.prototype.fetchItem = function(id) { - this.resource.read({}, goog.bind(this.handleFetchItem, this, id)); -}; - - -/** @override */ -registry.ResourceComponent.prototype.handleFetchItem = function(id, rsp) { - // XXX: Two different protocols are supported here. The new style used in the - // registrar console is first, followed by the item/set style used by - // the admin console. - if ('status' in rsp) { - // New style. - if (rsp.status == 'SUCCESS') { - this.model = rsp.results[0]; - this.model.readonly = true; - this.processItem(); - this.renderItem(this.model); - } else { - // XXX: Happens if the server restarts while the client has an - // open-session. This should retry. - registry.forms.resetErrors(); - registry.forms.displayError(rsp['message'], rsp['field']); - } - } else if ('item' in rsp) { - this.model = rsp.item; - this.model.readonly = true; - this.processItem(); - this.renderItem(this.model); - } else if ('set' in rsp && this.renderSetCb != null) { - // XXX: This conditional logic should be hoisted to edit_item when - // collection support is improved. - goog.dom.removeChildren(goog.dom.getRequiredElement('reg-app-buttons')); - this.renderSetCb(goog.dom.getRequiredElement('reg-content'), rsp); - } else { - registry.util.log('unknown message type in handleFetchItem'); - } -}; - - -/** @override */ -registry.ResourceComponent.prototype.sendUpdate = function() { - var modelCopy = /** @type {!Object} - */ (JSON.parse(goog.json.serialize(this.model))); - this.prepareUpdate(modelCopy); - if (this.id) { - this.resource.update(modelCopy, goog.bind(this.handleUpdateResponse, this)); - } else { - this.resource.update(modelCopy, goog.bind(this.handleCreateResponse, this)); - } -}; - - -/** @override */ -registry.ResourceComponent.prototype.prepareUpdate = function(modelCopy) { - var form = registry.util.parseForm('item'); - for (var ndx in form) { - modelCopy[ndx] = form[ndx]; - } -}; - - -/** @override */ -registry.ResourceComponent.prototype.handleUpdateResponse = function(rsp) { - if (rsp.status) { - if (rsp.status != 'SUCCESS') { - registry.forms.resetErrors(); - registry.forms.displayError(rsp['message'], rsp['field']); - return rsp; - } - // XXX: Vestigial state from admin console. Shouldn't be possible to be - // null. - if (this.id) { - this.fetchItem(this.id || ''); - this.toggleEdit(); - } - return rsp; - } - // XXX: Should be removed when admin console uses new response format. - if (rsp instanceof Object && 'results' in rsp) { - registry.util.butter(rsp['results']); - this.bindToDom(this.nextId || ''); - this.nextId = null; - } else { - registry.util.butter(rsp.toString()); - } - return rsp; -}; - - -/** - * Handle resource create response. - * @param {!Object} rsp Decoded JSON response from the server. - * @return {!Object} a result object describing next steps. On - * success, if next is defined, visit(ret.next) is called, otherwise - * if err is set, the butterbar message is set to it. - */ -registry.ResourceComponent.prototype.handleCreateResponse = - goog.abstractMethod; - - -/** - * Handle resource delete response. - * @param {!Object} rsp Decoded JSON response from the server. - * @return {!Object} a result object describing next steps. On - * success, if next is defined, visit(ret.next) is called, otherwise - * if err is set, the butterbar message is set to it. - */ -registry.ResourceComponent.prototype.handleDeleteResponse = - goog.abstractMethod; diff --git a/core/src/main/javascript/google/registry/ui/js/session.js b/core/src/main/javascript/google/registry/ui/js/session.js deleted file mode 100644 index 2fee38028..000000000 --- a/core/src/main/javascript/google/registry/ui/js/session.js +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.Session'); - -goog.require('goog.json'); -goog.require('goog.net.XhrIo'); -goog.require('registry.util'); - -goog.forwardDeclare('goog.Uri'); - - - -/** - * XHR launcher for JSON requests. - * @param {!goog.Uri} defaultUri URI to which requests are POSTed. - * @param {string} xsrfToken Cross-site request forgery protection token. - * @constructor - * @template REQUEST, RESPONSE - */ -registry.Session = function(defaultUri, xsrfToken) { - - /** - * URI to which requests are posted. - * @protected {!goog.Uri} - * @const - */ - this.uri = defaultUri; - - /** - * XHR request headers. - * @private {!Object} - * @const - */ - this.headers_ = { - 'Content-Type': 'application/json; charset=utf-8', - 'X-CSRF-Token': xsrfToken, - 'X-Requested-With': 'XMLHttpRequest' - }; -}; - - -/** - * Abstract method to send a request to the server. - * @param {REQUEST} body HTTP request body as a string or JSON object. - * @param {function(RESPONSE)} onSuccess XHR success callback. - * @param {function(string)=} opt_onError XHR error callback. The default action - * is to show a bloody butterbar. - * @final - */ -registry.Session.prototype.sendXhrIo = - function(body, onSuccess, opt_onError) { - goog.net.XhrIo.send( - this.uri.toString(), - goog.bind(this.onXhrComplete_, this, onSuccess, - opt_onError || goog.bind(this.displayError_, this)), - 'POST', - goog.isObject(body) ? goog.json.serialize(body) : body, - this.headers_); -}; - - -/** - * Handler invoked when an asynchronous request is complete. - * @param {function(RESPONSE)} onSuccess Success callback. - * @param {function(string)} onError Success callback. - * @param {{target: !goog.net.XhrIo}} e XHR event. - * @private - */ -registry.Session.prototype.onXhrComplete_ = function(onSuccess, onError, e) { - if (e.target.isSuccess()) { - onSuccess(/** @type {!RESPONSE} */ ( - e.target.getResponseJson(registry.Session.PARSER_BREAKER_))); - } else { - onError(e.target.getLastError()); - } -}; - - -/** - * JSON response prefix which prevents evaluation. - * @private {string} - * @const - */ -registry.Session.PARSER_BREAKER_ = ')]}\'\n'; - - -/** - * Displays `message` to user in bloody butterbar. - * @param {string} message - * @private - */ -registry.Session.prototype.displayError_ = function(message) { - registry.util.butter( - this.uri.toString() + ': ' + message + '. Please reload.', true); -}; diff --git a/core/src/main/javascript/google/registry/ui/js/util.js b/core/src/main/javascript/google/registry/ui/js/util.js deleted file mode 100644 index 99838b1c5..000000000 --- a/core/src/main/javascript/google/registry/ui/js/util.js +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2017 The Nomulus Authors. 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. - -goog.provide('registry.util'); - -goog.require('goog.dom'); -goog.require('goog.dom.classlist'); -goog.require('goog.soy'); - - -/** - * Logging function that delegates to `console.log()`. - * @param {...*} var_args - */ -registry.util.log = function(var_args) { - if (goog.DEBUG) { - if (goog.global.console !== undefined && goog.global.console['log'] !== undefined) { - goog.global.console.log.apply(goog.global.console, arguments); - } - } -}; - - -/** - * CSS class for hiding an element whose visibility can be toggled. - * @type {string} - * @const - */ -registry.util.cssHidden = goog.getCssName('hidden'); - - -/** - * CSS class for showing an element whose visibility can be toggled. - * @type {string} - * @const - */ -registry.util.cssShown = goog.getCssName('shown'); - - -/** - * Changes element visibility by toggling CSS `shown` to `hidden`. - * @param {!Element|string} element Element or id attribute of element. - * @param {boolean} visible Shows `element` if true, or else hides it. - */ -registry.util.setVisible = function(element, visible) { - goog.dom.classlist.addRemove( - goog.dom.getElement(element), - visible ? registry.util.cssHidden : registry.util.cssShown, - visible ? registry.util.cssShown : registry.util.cssHidden); -}; - - -/** - * Show a buttebar with the given message. A dismiss link will be added. - * @param {string} message the message to show the user. - * @param {boolean=} opt_isFatal indicates butterbar should be blood red. This - * should only be used when an RPC returns a non-200 status. - */ -registry.util.butter = function(message, opt_isFatal) { - goog.dom.setTextContent( - goog.dom.getElementByClass(goog.getCssName('kd-butterbar-text')), - message); - var butterbar = - goog.dom.getRequiredElementByClass(goog.getCssName('kd-butterbar')); - registry.util.setVisible(butterbar, true); - if (opt_isFatal) { - goog.dom.classlist.add(butterbar, goog.getCssName('fatal')); - } else { - goog.dom.classlist.remove(butterbar, goog.getCssName('fatal')); - } -}; - - -/** - * Hides the butterbar. - */ -registry.util.unbutter = function() { - registry.util.setVisible( - goog.dom.getRequiredElementByClass(goog.getCssName('kd-butterbar')), - false); -}; - - -/** - * Renders the tmpl at and then moves it before the given elt. - * @param {Element|string} id dom id of the refElt to render before. - * @param {function()} tmpl template to render. - * @param {!Object} tmplParams params to pass to the template. - * @return {!Element} the rendered row. - */ -registry.util.renderBeforeRow = function(id, tmpl, tmplParams) { - var refElt = goog.dom.getElement(id); - goog.soy.renderElement(refElt, tmpl, tmplParams); - var prevSib = goog.dom.getPreviousElementSibling(refElt); - goog.dom.removeNode(refElt); - refElt.removeAttribute('id'); - goog.dom.insertSiblingAfter(refElt, prevSib); - var newAnchorRefElt = goog.dom.createDom(refElt.tagName, {'id': id}); - goog.dom.insertSiblingAfter(newAnchorRefElt, refElt); - return refElt; -}; - - -/** - * Turns an HTML form's named elements into a JSON data structure with - * Pablo's black magick. - * @param {string} formName the name of the form to be parsed. - * @throws {Error} if `formName` couldn't be found. - * @return {!Object} the parsed form values as an object. - */ -registry.util.parseForm = function(formName) { - var form = /** @type {HTMLFormElement} - */ (document.querySelector('form[name=' + formName + ']')); - if (form == null) { - throw new Error('No such form named ' + formName); - } - var obj = {}; - // Find names first, since e.g. radio buttons have two elts with the - // same name. - var eltNames = {}; - for (var i = 0; i < form.elements.length; i++) { - var elt = form.elements[i]; - if (elt.name == '') { - continue; - } - eltNames[elt.name] = null; - } - for (var eltName in eltNames) { - var elt = form.elements[eltName]; - var val; - if (elt.type == 'checkbox') { - val = elt.checked; - } else { - val = elt.value; - } - registry.util.expandObject_(obj, eltName, val); - } - return obj; -}; - - -/** - * Give the object a value at the given path. Paths are split on dot - * and array elements are recognized. - * - *

    - *
  • a = 1 - *
  • foo:a = 1.5 - *
  • b.c = 2 - *
  • b.d = 3 - *
  • c[0] = 4 - *
  • c[1] = 5 - *
  • d[0].a = 6 - *
  • d[1].foo:b = 7 - *
  • d[1].@b = 8 - *
- * - * Yields the following object: - *
- * {
- *   a: '1',
- *   'foo:a': '1.5',
- *   b: {
- *     c: '2',
- *     d: '3'
- *   },
- *   c: ['4','5'],
- *   d: [{a:'6'},{'foo:b':'7'},{'@b':'8'}]
- * }
- * 
- * - * @param {!Object} obj - * @param {string} pathSpec - * @param {string|Array.|null} val - * @private - */ -registry.util.expandObject_ = function(obj, pathSpec, val) { - var path = pathSpec.split('.'); - for (var p = 0; p < path.length; p++) { - var fieldName = path[p]; - var arrElt = fieldName.match(/^([\w:]+)\[(\d+)\]$/); - if (arrElt) { - var arrName = arrElt[1]; - var arrNdx = arrElt[2]; - if (!obj[arrName]) { - obj[arrName] = []; - } - obj = obj[arrName]; - fieldName = arrNdx; - if (!obj[arrNdx]) { - obj[arrNdx] = {}; - } - } else { - if (!obj[fieldName]) { - obj[fieldName] = {}; - } - } - if (p == path.length - 1) { - obj[fieldName] = val; - } else { - obj = obj[fieldName]; - } - } -}; diff --git a/core/src/main/javascript/soyutils_usegoog.js b/core/src/main/javascript/soyutils_usegoog.js deleted file mode 100644 index 600d05099..000000000 --- a/core/src/main/javascript/soyutils_usegoog.js +++ /dev/null @@ -1,2869 +0,0 @@ -/* - * Copyright 2008 Google Inc. - * - * 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. - */ - -/** - * @fileoverview - * - * NOTE (gbrodman) this file is taken from the open source version located at - * https://github.com/google/closure-templates/blob/6c8cf1c7916abd0ab5d7e9d259985873f8af4fd2/javascript/soyutils_usegoog.js - * and slightly modified so that it compiles. - * - * Utility functions and classes for Soy gencode - * - *

- * This file contains utilities that should only be called by Soy-generated - * JS code. Please do not use these functions directly from - * your hand-written code. Their names all start with '$$', or exist within the - * soydata.VERY_UNSAFE namespace. - * - *

TODO(lukes): ensure that the above pattern is actually followed - * consistently. - * - */ -goog.provide('soy'); -goog.provide('soy.asserts'); -goog.provide('soy.esc'); -goog.provide('soydata'); -goog.provide('soydata.SanitizedHtml'); -goog.provide('soydata.VERY_UNSAFE'); - -goog.require('goog.array'); -goog.require('goog.asserts'); -goog.require('goog.debug'); -goog.require('goog.format'); -goog.require('goog.html.SafeHtml'); -goog.require('goog.html.SafeScript'); -goog.require('goog.html.SafeStyle'); -goog.require('goog.html.SafeStyleSheet'); -goog.require('goog.html.SafeUrl'); -goog.require('goog.html.TrustedResourceUrl'); -goog.require('goog.html.uncheckedconversions'); -goog.require('goog.i18n.BidiFormatter'); -goog.require('goog.i18n.bidi'); -goog.require('goog.object'); -goog.require('goog.soy.data.SanitizedContent'); -goog.require('goog.soy.data.SanitizedContentKind'); -goog.require('goog.soy.data.SanitizedCss'); -goog.require('goog.soy.data.SanitizedHtml'); -goog.require('goog.soy.data.SanitizedHtmlAttribute'); -goog.require('goog.soy.data.SanitizedJs'); -goog.require('goog.soy.data.SanitizedTrustedResourceUri'); -goog.require('goog.soy.data.SanitizedUri'); -goog.require('goog.string'); -goog.require('goog.string.Const'); -goog.require('soy.checks'); -goog.requireType('goog.soy'); - - -// ----------------------------------------------------------------------------- -// soydata: Defines typed strings, e.g. an HTML string `"ac"` is -// semantically distinct from the plain text string `"ac"` and smart -// templates can take that distinction into account. - - -/** @typedef {!goog.soy.data.SanitizedContent|{isInvokableFn: boolean}} */ -soydata.IdomFunction; - -/** - * Checks whether a given value is of a given content kind. - * - * @param {?} value The value to be examined. - * @param {!goog.soy.data.SanitizedContentKind} contentKind The desired content - * kind. - * @return {boolean} Whether the given value is of the given kind. - * @private - */ -soydata.isContentKind_ = function(value, contentKind) { - // TODO(user): This function should really include the assert on - // value.constructor that is currently sprinkled at most of the call sites. - // Unfortunately, that would require a (debug-mode-only) switch statement. - // TODO(user): Perhaps we should get rid of the contentKind property - // altogether and only at the constructor. - return value != null && value.contentKind === contentKind; -}; - -/** - * Returns a given value's contentDir property, constrained to a - * goog.i18n.bidi.Dir value or null. Returns null if the value is null, - * undefined, a primitive or does not have a contentDir property, or the - * property's value is not 1 (for LTR), -1 (for RTL), or 0 (for neutral). - * - * @param {?} value The value whose contentDir property, if any, is to - * be returned. - * @return {?goog.i18n.bidi.Dir} The contentDir property. - */ -soydata.getContentDir = function(value) { - if (value != null) { - switch (value.contentDir) { - case goog.i18n.bidi.Dir.LTR: - return goog.i18n.bidi.Dir.LTR; - case goog.i18n.bidi.Dir.RTL: - return goog.i18n.bidi.Dir.RTL; - case goog.i18n.bidi.Dir.NEUTRAL: - return goog.i18n.bidi.Dir.NEUTRAL; - } - } - return null; -}; - -/** - * This class is only a holder for `soydata.SanitizedHtml.from`. Do not - * instantiate or extend it. Use `goog.soy.data.SanitizedHtml` instead. - * - * @constructor - * @extends {goog.soy.data.SanitizedHtml} - * @abstract - */ -soydata.SanitizedHtml = function() { - soydata.SanitizedHtml.base(this, 'constructor'); // Throws an exception. -}; -goog.inherits(soydata.SanitizedHtml, goog.soy.data.SanitizedHtml); - -/** - * Returns a SanitizedHtml object for a particular value. The content direction - * is preserved. - * - * This HTML-escapes the value unless it is already SanitizedHtml or SafeHtml. - * - * @param {?} value The value to convert. If it is already a SanitizedHtml - * object, it is left alone. - * @return {!goog.soy.data.SanitizedHtml} A SanitizedHtml object derived from - * the stringified value. It is escaped unless the input is SanitizedHtml or - * SafeHtml. - */ -soydata.SanitizedHtml.from = function(value) { - // The check is soydata.isContentKind_() inlined for performance. - if (soy.checks.isHtml(value)) { - return /** @type {!goog.soy.data.SanitizedHtml} */ (value); - } - if (value instanceof goog.html.SafeHtml) { - return soydata.VERY_UNSAFE.ordainSanitizedHtml( - goog.html.SafeHtml.unwrap(value), value.getDirection()); - } - return soydata.VERY_UNSAFE.ordainSanitizedHtml( - soy.esc.$$escapeHtmlHelper(String(value)), soydata.getContentDir(value)); -}; - - -/** - * Empty string, used as a type in Soy templates. - * @enum {string} - * @private - */ -soydata.$$EMPTY_STRING_ = { - VALUE: '', -}; - - -/** - * Creates a factory for SanitizedContent types. - * - * This is a hack so that the soydata.VERY_UNSAFE.ordainSanitized* can - * instantiate Sanitized* classes, without making the Sanitized* constructors - * publicly usable. Requiring all construction to use the VERY_UNSAFE names - * helps callers and their reviewers easily tell that creating SanitizedContent - * is not always safe and calls for careful review. - * - * @param {function(new: T)} ctor A constructor. - * @return {function(*, ?goog.i18n.bidi.Dir=): T} A factory that takes - * content and an optional content direction and returns a new instance. If - * the content direction is undefined, ctor.prototype.contentDir is used. - * @template T - * @private - */ -soydata.$$makeSanitizedContentFactory_ = function(ctor) { - /** - * @param {string} content - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ - function InstantiableCtor(content) { - /** @override */ - this.content = content; - } - InstantiableCtor.prototype = ctor.prototype; - /** - * Creates a ctor-type SanitizedContent instance. - * - * @param {?} content The content to put in the instance. - * @param {?goog.i18n.bidi.Dir=} opt_contentDir The content direction. If - * undefined, ctor.prototype.contentDir is used. - * @return {!goog.soy.data.SanitizedContent} The new instance. It is actually - * of type T above (ctor's type, a descendant of SanitizedContent), but - * there is no way to express that here. - */ - function sanitizedContentFactory(content, opt_contentDir) { - var result = new InstantiableCtor(String(content)); - if (opt_contentDir !== undefined) { - result.contentDir = opt_contentDir; - } - return result; - } - return sanitizedContentFactory; -}; - - -/** - * Creates a factory for SanitizedContent types that should always have their - * default directionality. - * - * This is a hack so that the soydata.VERY_UNSAFE.ordainSanitized* can - * instantiate Sanitized* classes, without making the Sanitized* constructors - * publicly usable. Requiring all construction to use the VERY_UNSAFE names - * helps callers and their reviewers easily tell that creating SanitizedContent - * is not always safe and calls for careful review. - * - * @param {function(new: T, string)} ctor A constructor. - * @return {function(*): T} A factory that takes content and returns a new - * instance (with default directionality, i.e. ctor.prototype.contentDir). - * @template T - * @private - */ -soydata.$$makeSanitizedContentFactoryWithDefaultDirOnly_ = function(ctor) { - /** - * @param {string} content - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ - function InstantiableCtor(content) { - /** @override */ - this.content = content; - } - InstantiableCtor.prototype = ctor.prototype; - /** - * Creates a ctor-type SanitizedContent instance. - * - * @param {?} content The content to put in the instance. - * @return {!goog.soy.data.SanitizedContent} The new instance. It is actually - * of type T above (ctor's type, a descendant of SanitizedContent), but - * there is no way to express that here. - */ - function sanitizedContentFactory(content) { - var result = new InstantiableCtor(String(content)); - return result; - } - return sanitizedContentFactory; -}; - - -// ----------------------------------------------------------------------------- -// Sanitized content ordainers. Please use these with extreme caution. A good -// recommendation is to limit usage of these to just a handful of files in your -// source tree where usages can be carefully audited. - - -/** - * Takes a leap of faith that the provided content is "safe" HTML. - * - * @param {?} content A string of HTML that can safely be embedded in - * a PCDATA context in your app. If you would be surprised to find that an - * HTML sanitizer produced `s` (e.g. it runs code or fetches bad URLs) - * and you wouldn't write a template that produces `s` on security or - * privacy grounds, then don't pass `s` here. - * @param {?goog.i18n.bidi.Dir=} opt_contentDir The content direction; null if - * unknown and thus to be estimated when necessary. Default: null. - * @return {!goog.soy.data.SanitizedHtml} Sanitized content wrapper that - * indicates to Soy not to escape when printed as HTML. - */ -soydata.VERY_UNSAFE.ordainSanitizedHtml = - soydata.$$makeSanitizedContentFactory_(goog.soy.data.SanitizedHtml); - - -/** - * Takes a leap of faith that the provided content is "safe" (non-attacker- - * controlled, XSS-free) Javascript. - * - * @param {?} content Javascript source that when evaluated does not - * execute any attacker-controlled scripts. - * @return {!goog.soy.data.SanitizedJs} Sanitized content wrapper that indicates - * to Soy not to escape when printed as Javascript source. - */ -soydata.VERY_UNSAFE.ordainSanitizedJs = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnly_( - goog.soy.data.SanitizedJs); - - -/** - * Takes a leap of faith that the provided content is "safe" to use as a URI - * in a Soy template. - * - * This creates a Soy SanitizedContent object which indicates to Soy there is - * no need to escape it when printed as a URI (e.g. in an href or src - * attribute), such as if it's already been encoded or if it's a Javascript: - * URI. - * - * @param {?} content A chunk of URI that the caller knows is safe to - * emit in a template. - * @return {!goog.soy.data.SanitizedUri} Sanitized content wrapper that - * indicates to Soy not to escape or filter when printed in URI context. - */ -soydata.VERY_UNSAFE.ordainSanitizedUri = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnly_( - goog.soy.data.SanitizedUri); - - -/** - * Takes a leap of faith that the provided content is "safe" to use as a - * TrustedResourceUri in a Soy template. - * - * This creates a Soy SanitizedContent object which indicates to Soy there is - * no need to filter it when printed as a TrustedResourceUri. - * - * @param {?} content A chunk of TrustedResourceUri such as that the caller - * knows is safe to emit in a template. - * @return {!goog.soy.data.SanitizedTrustedResourceUri} Sanitized content - * wrapper that indicates to Soy not to escape or filter when printed in - * TrustedResourceUri context. - */ -soydata.VERY_UNSAFE.ordainSanitizedTrustedResourceUri = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnly_( - goog.soy.data.SanitizedTrustedResourceUri); - - -/** - * Takes a leap of faith that the provided content is "safe" to use as an - * HTML attribute. - * - * @param {?} content An attribute name and value, such as - * `dir="ltr"`. - * @return {!goog.soy.data.SanitizedHtmlAttribute} Sanitized content wrapper - * that indicates to Soy not to escape when printed as an HTML attribute. - */ -soydata.VERY_UNSAFE.ordainSanitizedHtmlAttribute = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnly_( - goog.soy.data.SanitizedHtmlAttribute); - - -/** - * Takes a leap of faith that the provided content is "safe" to use as CSS - * in a style block. - * - * @param {?} content CSS, such as `color:#c3d9ff`. - * @return {!goog.soy.data.SanitizedCss} Sanitized CSS wrapper that indicates to - * Soy there is no need to escape or filter when printed in CSS context. - */ -soydata.VERY_UNSAFE.ordainSanitizedCss = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnly_( - goog.soy.data.SanitizedCss); - -// Utilities related to defining and stubbing soy templates - - -/** - * A map that allows us to dynamically replace templates. - * - * The key is the fully qualified template name and the value is a replacement - * to call instead. - * - * @type {?Object} - * @const - * @public - */ -soy.$$stubsMap = goog.DEBUG ? {} : null; - - -// ----------------------------------------------------------------------------- -// Soy-generated utilities in the soy namespace. Contains implementations for -// common soyfunctions (e.g. keys()) and escaping/print directives. - - -/** - * Provides a compact serialization format for the key structure. - * @param {?} item - * @return {string} - */ -soy.$$serializeKey = function(item) { - const stringified = String(item); - let delimiter; - if (item == null) { - delimiter = '_'; - } else if (typeof item === 'number') { - delimiter = '#'; - } else { - delimiter = ':'; - } - return `${stringified.length}${delimiter}${stringified}`; -}; - - - -/** - * Whether the locale is right-to-left. - * - * @type {boolean} - */ -soy.$$IS_LOCALE_RTL = goog.i18n.bidi.IS_RTL; - - - -/** - * Copies extra properties into an object if they do not already exist. The - * destination object is mutated in the process. - * - * @param {?} obj The destination object to update. - * @param {?} defaults An object with default properties to apply. - * @return {?} The destination object for convenience. - */ -soy.$$assignDefaults = function(obj, defaults) { - for (var key in defaults) { - if (!(key in obj)) { - obj[key] = defaults[key]; - } - } - - return obj; -}; - - -/** - * Gets the keys in a map as an array. There are no guarantees on the order. - * @param {!Object} map The map to get the keys of. - * @return {!Array} The array of keys in the given map. - */ -soy.$$getMapKeys = function(map) { - var mapKeys = []; - for (var key in map) { - mapKeys.push(key); - } - return mapKeys; -}; - - -/** - * Returns the argument if it is not null. - * - * @param {T} val The value to check - * @return {T} val if is isn't null - * @template T - */ -soy.$$checkNotNull = function(val) { - if (val == null) { - throw Error('unexpected null value'); - } - return val; -}; - - -/** - * Parses the given string into a base 10 integer. Returns null if parse is - * unsuccessful. - * @param {?string} str The string to parse - * @return {?number} The string parsed as a base 10 integer, or null if - * unsuccessful - */ -soy.$$parseInt = function(str) { - var parsed = parseInt(String(str), 10); - return isNaN(parsed) ? null : parsed; -}; - -/** - * When equals comparison cannot be expressed using JS runtime semantics for ==, - * bail out to a runtime function. In practice, this only means comparisons - * of boolean, string and number are valid for equals, and everything else needs - * this function. Some sanitized content may be functions or objects that need - * to be coerced to a string. - * @param {?} valueOne - * @param {?} valueTwo - * @return {boolean} - */ -soy.$$equals = function(valueOne, valueTwo) { - // Incremental DOM functions have to be coerced to a string. At runtime - // they are tagged with a type for ATTR or HTML. They both need to be - // the same to be considered structurally equal. Beware, as this is a - // very expensive function. - if ((valueOne && valueTwo) && - (valueOne.isInvokableFn && valueTwo.isInvokableFn)) { - if ((/** @type {?} */ (valueOne)).contentKind !== - (/** @type {?} */ (valueTwo)).contentKind) { - return false; - } else { - return valueOne.toString() === valueTwo.toString(); - } - } - - // Likewise for sanitized content. - if (valueOne instanceof goog.soy.data.SanitizedContent && - valueTwo instanceof goog.soy.data.SanitizedContent) { - if (valueOne.contentKind != valueTwo.contentKind) { - return false; - } else { - return valueOne.toString() == valueTwo.toString(); - } - } - - // Rely on javascript semantics for comparing two objects. - return valueOne == valueTwo; -}; - - -/** - * @param {?} value - * @return {boolean} - */ -soy.$$isFunction = function(value) { - return typeof value === 'function'; -}; - -/** - * Parses the given string into a float. Returns null if parse is unsuccessful. - * @param {?string} str The string to parse - * @return {?number} The string parsed as a float, or null if unsuccessful. - */ -soy.$$parseFloat = function(str) { - var parsed = parseFloat(str); - return isNaN(parsed) ? null : parsed; -}; - -/** - * Returns a random integer. - * @return {number} a random integer between 0 and num - */ -soy.$$randomInt = function(/** number */ num) { - return Math.floor(Math.random() * num); -}; - -/** - * Rounds the given value to the closest decimal point left (negative numbers) - * or right (positive numbers) of the decimal point - * - * TODO(b/112835292): This is probably not something that anyone should use, - * instead they should use an i18n friendly number formatting routine. - * - * @return {number} the rounded value - */ -soy.$$round = function(/** number */ num, /** number */ numDigitsAfterPt) { - const shift = Math.pow(10, numDigitsAfterPt); - return Math.round(num * shift) / shift; -}; - -/** @return {boolean} returns whether the needle was found in the haystack */ -soy.$$strContains = function(/** string */ haystack, /** string */ needle) { - return haystack.indexOf(needle) != -1; -}; - -/** - * Coerce the given value into a bool. - * - * For objects of type `SanitizedContent`, the contents are used to determine - * the boolean value; this is because the outer `SanitizedContent` object - * instance is always truthy (unless it's null). - * - * @param {*} arg The argument to coerce. - * @return {boolean} - */ -soy.$$coerceToBoolean = function(arg) { - if (arg instanceof goog.soy.data.SanitizedContent) { - return !!arg.getContent(); - } - return !!arg; -}; - - -/** - * Gets a consistent unique id for the given delegate template name. Two calls - * to this function will return the same id if and only if the input names are - * the same. - * - *

Important: This function must always be called with a string constant. - * - *

If Closure Compiler is not being used, then this is just this identity - * function. If Closure Compiler is being used, then each call to this function - * will be replaced with a short string constant, which will be consistent per - * input name. - * - * @param {string} delTemplateName The delegate template name for which to get a - * consistent unique id. - * @return {string} A unique id that is consistent per input name. - * - * @idGenerator {consistent} - */ -soy.$$getDelTemplateId = function(delTemplateName) { - return delTemplateName; -}; - - -/** - * Map from registered delegate template key to the priority of the - * implementation. - * @const {!Object} - * @private - */ -soy.$$DELEGATE_REGISTRY_PRIORITIES_ = {}; - -/** - * Map from registered delegate template key to the implementation function. - * @const {!Object} - * @private - */ -soy.$$DELEGATE_REGISTRY_FUNCTIONS_ = {}; - - -/** - * Registers a delegate implementation. If the same delegate template key (id - * and variant) has been registered previously, then priority values are - * compared and only the higher priority implementation is stored (if - * priorities are equal, an error is thrown). - * - * @param {string} delTemplateId The delegate template id. - * @param {string} delTemplateVariant The delegate template variant (can be - * empty string). - * @param {number} delPriority The implementation's priority value. - * @param {!Function} delFn The implementation function. - */ -soy.$$registerDelegateFn = function( - delTemplateId, delTemplateVariant, delPriority, delFn) { - - var mapKey = 'key_' + delTemplateId + ':' + delTemplateVariant; - var currPriority = soy.$$DELEGATE_REGISTRY_PRIORITIES_[mapKey]; - if (currPriority === undefined || delPriority > currPriority) { - // Registering new or higher-priority function: replace registry entry. - soy.$$DELEGATE_REGISTRY_PRIORITIES_[mapKey] = delPriority; - soy.$$DELEGATE_REGISTRY_FUNCTIONS_[mapKey] = delFn; - } else if (delPriority == currPriority) { - // Registering same-priority function: error. - throw Error( - 'Encountered two active delegates with the same priority ("' + - delTemplateId + ':' + delTemplateVariant + '").'); - } else { - // Registering lower-priority function: do nothing. - } -}; - - -/** - * Retrieves the (highest-priority) implementation that has been registered for - * a given delegate template key (id and variant). If no implementation has - * been registered for the key, then the fallback is the same id with empty - * variant. If the fallback is also not registered, and allowsEmptyDefault is - * true, then returns an implementation that is equivalent to an empty template - * (i.e. rendered output would be empty string). - * - * @param {string} delTemplateId The delegate template id. - * @param {string} delTemplateVariant The delegate template variant (can be - * empty string). - * @param {boolean} allowsEmptyDefault Whether to default to the empty template - * function if there's no active implementation. - * @return {!Function} The retrieved implementation function. - */ -soy.$$getDelegateFn = function( - delTemplateId, delTemplateVariant, allowsEmptyDefault) { - - var delFn = soy.$$DELEGATE_REGISTRY_FUNCTIONS_[ - 'key_' + delTemplateId + ':' + delTemplateVariant]; - if (! delFn && delTemplateVariant != '') { - // Fallback to empty variant. - delFn = soy.$$DELEGATE_REGISTRY_FUNCTIONS_['key_' + delTemplateId + ':']; - } - - if (delFn) { - return delFn; - } else if (allowsEmptyDefault) { - return soy.$$EMPTY_TEMPLATE_FN_; - } else { - throw Error( - 'Found no active impl for delegate call to "' + delTemplateId + - (delTemplateVariant ? ':' + delTemplateVariant : '') + - '" (and delcall does not set allowemptydefault="true").'); - } -}; - - -/** - * Private helper soy.$$getDelegateFn(). This is the empty template function - * that is returned whenever there's no delegate implementation found. - * - * Note: This is also used for idom. - * - * @return {string} - * @private - */ -soy.$$EMPTY_TEMPLATE_FN_ = function() { - return ''; -}; - - -// ----------------------------------------------------------------------------- -// Internal sanitized content wrappers. - - -/** - * Creates a SanitizedContent factory for SanitizedContent types for internal - * Soy let and param blocks. - * - * This is a hack within Soy so that SanitizedContent objects created via let - * and param blocks will truth-test as false if they are empty string. - * Tricking the Javascript runtime to treat empty SanitizedContent as falsey is - * not possible, and changing the Soy compiler to wrap every boolean statement - * for just this purpose is impractical. Instead, we just avoid wrapping empty - * string as SanitizedContent, since it's a no-op for empty strings anyways. - * - * @param {function(new: T)} ctor A constructor. - * @return {function(*, ?goog.i18n.bidi.Dir=): (T|!soydata.$$EMPTY_STRING_)} - * A factory that takes content and an optional content direction and - * returns a new instance, or an empty string. If the content direction is - * undefined, ctor.prototype.contentDir is used. - * @template T - * @private - */ -soydata.$$makeSanitizedContentFactoryForInternalBlocks_ = function(ctor) { - /** - * @param {string} content - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ - function InstantiableCtor(content) { - /** @override */ - this.content = content; - } - InstantiableCtor.prototype = ctor.prototype; - /** - * Creates a ctor-type SanitizedContent instance. - * - * @param {?} content The content to put in the instance. - * @param {?goog.i18n.bidi.Dir=} opt_contentDir The content direction. If - * undefined, ctor.prototype.contentDir is used. - * @return {!goog.soy.data.SanitizedContent|!soydata.$$EMPTY_STRING_} The new - * instance, or an empty string. A new instance is actually of type T - * above (ctor's type, a descendant of SanitizedContent), but there's no - * way to express that here. - */ - function sanitizedContentFactory(content, opt_contentDir) { - var contentString = String(content); - if (!contentString) { - return soydata.$$EMPTY_STRING_.VALUE; - } - var result = new InstantiableCtor(contentString); - if (opt_contentDir !== undefined) { - result.contentDir = opt_contentDir; - } - return result; - } - return sanitizedContentFactory; -}; - - -/** - * Creates a SanitizedContent factory for SanitizedContent types that should - * always have their default directionality for internal Soy let and param - * blocks. - * - * This is a hack within Soy so that SanitizedContent objects created via let - * and param blocks will truth-test as false if they are empty string. - * Tricking the Javascript runtime to treat empty SanitizedContent as falsey is - * not possible, and changing the Soy compiler to wrap every boolean statement - * for just this purpose is impractical. Instead, we just avoid wrapping empty - * string as SanitizedContent, since it's a no-op for empty strings anyways. - * - * @param {function(new: T)} ctor A constructor. - * @return {function(*): (T|!soydata.$$EMPTY_STRING_)} A - * factory that takes content and returns a - * new instance (with default directionality, i.e. - * ctor.prototype.contentDir), or an empty string. - * @template T - * @private - */ -soydata.$$makeSanitizedContentFactoryWithDefaultDirOnlyForInternalBlocks_ = - function(ctor) { - /** - * @param {string} content - * @constructor - * @extends {goog.soy.data.SanitizedContent} - */ - function InstantiableCtor(content) { - /** @override */ - this.content = content; - } - InstantiableCtor.prototype = ctor.prototype; - /** - * Creates a ctor-type SanitizedContent instance. - * - * @param {?} content The content to put in the instance. - * @return {!goog.soy.data.SanitizedContent|!soydata.$$EMPTY_STRING_} The new - * instance, or an empty string. A new instance is actually of type T - * above (ctor's type, a descendant of SanitizedContent), but there's no - * way to express that here. - */ - function sanitizedContentFactory(content) { - var contentString = String(content); - if (!contentString) { - return soydata.$$EMPTY_STRING_.VALUE; - } - var result = new InstantiableCtor(contentString); - return result; - } - return sanitizedContentFactory; -}; - - -/** - * Creates kind="html" block contents (internal use only). - * - * @param {?} content Text. - * @param {?goog.i18n.bidi.Dir=} opt_contentDir The content direction; null if - * unknown and thus to be estimated when necessary. Default: null. - * @return {!goog.soy.data.SanitizedHtml|!soydata.$$EMPTY_STRING_} Wrapped - * result. - */ -soydata.VERY_UNSAFE.$$ordainSanitizedHtmlForInternalBlocks = - soydata.$$makeSanitizedContentFactoryForInternalBlocks_( - goog.soy.data.SanitizedHtml); - - -/** - * Creates kind="js" block contents (internal use only). - * - * @param {?} content Text. - * @return {!goog.soy.data.SanitizedJs|!soydata.$$EMPTY_STRING_} Wrapped result. - */ -soydata.VERY_UNSAFE.$$ordainSanitizedJsForInternalBlocks = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnlyForInternalBlocks_( - goog.soy.data.SanitizedJs); - - -/** - * Creates kind="trustedResourceUri" block contents (internal use only). - * - * @param {?} content Text. - * @return {!goog.soy.data.SanitizedTrustedResourceUri|!soydata.$$EMPTY_STRING_} - * Wrapped result. - */ -soydata.VERY_UNSAFE.$$ordainSanitizedTrustedResourceUriForInternalBlocks = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnlyForInternalBlocks_( - goog.soy.data.SanitizedTrustedResourceUri); - - -/** - * Creates kind="uri" block contents (internal use only). - * - * @param {?} content Text. - * @return {!goog.soy.data.SanitizedUri|!soydata.$$EMPTY_STRING_} Wrapped - * result. - */ -soydata.VERY_UNSAFE.$$ordainSanitizedUriForInternalBlocks = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnlyForInternalBlocks_( - goog.soy.data.SanitizedUri); - - -/** - * Creates kind="attributes" block contents (internal use only). - * - * @param {?} content Text. - * @return {!goog.soy.data.SanitizedHtmlAttribute|!soydata.$$EMPTY_STRING_} - * Wrapped result. - */ -soydata.VERY_UNSAFE.$$ordainSanitizedAttributesForInternalBlocks = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnlyForInternalBlocks_( - goog.soy.data.SanitizedHtmlAttribute); - - -/** - * Creates kind="css" block contents (internal use only). - * - * @param {?} content Text. - * @return {!goog.soy.data.SanitizedCss|!soydata.$$EMPTY_STRING_} Wrapped - * result. - */ -soydata.VERY_UNSAFE.$$ordainSanitizedCssForInternalBlocks = - soydata.$$makeSanitizedContentFactoryWithDefaultDirOnlyForInternalBlocks_( - goog.soy.data.SanitizedCss); - - -// ----------------------------------------------------------------------------- -// Escape/filter/normalize. - - -/** - * Returns a SanitizedHtml object for a particular value. The content direction - * is preserved. - * - * This HTML-escapes the value unless it is already SanitizedHtml. Escapes - * double quote '"' in addition to '&', '<', and '>' so that a string can be - * included in an HTML tag attribute value within double quotes. - * - * @param {?} value The value to convert. If it is already a SanitizedHtml - * object, it is left alone. - * @return {!goog.soy.data.SanitizedHtml} An escaped version of value. - */ -soy.$$escapeHtml = function(value) { - return soydata.SanitizedHtml.from(value); -}; - - -/** - * Strips unsafe tags to convert a string of untrusted HTML into HTML that - * is safe to embed. The content direction is preserved. - * - * @param {?} value The string-like value to be escaped. May not be a string, - * but the value will be coerced to a string. - * @param {?Array=} opt_safeTags Additional tag names to whitelist. - * @return {!goog.soy.data.SanitizedHtml} A sanitized and normalized version of - * value. - */ -soy.$$cleanHtml = function(value, opt_safeTags) { - if (soy.checks.isHtml(value)) { - return /** @type {!goog.soy.data.SanitizedHtml} */ (value); - } - var tagWhitelist; - if (opt_safeTags) { - tagWhitelist = goog.object.createSet(opt_safeTags); - goog.object.extend(tagWhitelist, soy.esc.$$SAFE_TAG_WHITELIST_); - } else { - tagWhitelist = soy.esc.$$SAFE_TAG_WHITELIST_; - } - return soydata.VERY_UNSAFE.ordainSanitizedHtml( - soy.$$stripHtmlTags(value, tagWhitelist), soydata.getContentDir(value)); -}; - - -/** - * Converts HTML to plain text by removing tags, normalizing spaces and - * converting entities. - * - * The last two parameters are idom functions. - * @param {string|?goog.soy.data.SanitizedHtml|?goog.html.SafeHtml| - * ?soydata.IdomFunction|?Function|undefined} value - * @return {string} - */ -soy.$$htmlToText = function(value) { - if (value == null) { - return ''; - } - var html; - if (value instanceof goog.html.SafeHtml) { - html = goog.html.SafeHtml.unwrap(value); - } else if (soydata.isContentKind_( - value, goog.soy.data.SanitizedContentKind.HTML)) { - html = value.toString(); - } else { - return goog.asserts.assertString(value); - } - var text = ''; - var start = 0; - // Tag name to stop removing contents, e.g. '/script'. - var removingUntil = ''; - // Tag name to stop preserving whitespace, e.g. '/pre'. - var wsPreservingUntil = ''; - var tagRe = - /<(?:!--.*?--|(?:!|(\/?[a-z][\w:-]*))(?:[^>'"]|"[^"]*"|'[^']*')*)>|$/gi; - for (var match; match = tagRe.exec(html);) { - var tag = match[1]; - var offset = match.index; - if (!removingUntil) { - var chunk = html.substring(start, offset); - chunk = goog.string.unescapeEntities(chunk); - if (!wsPreservingUntil) { - // We are not inside

, normalize spaces.
-        chunk = chunk.replace(/\s+/g, ' ');
-        if (!/\S$/.test(text)) {
-          // Strip leading space unless after non-whitespace.
-          chunk = chunk.replace(/^ /, '');
-        }
-      }
-      text += chunk;
-      if (/^(script|style|textarea|title)$/i.test(tag)) {
-        removingUntil = '/' + tag.toLowerCase();
-      } else if (/^br$/i.test(tag)) {
-        // 
adds newline even after newline. - text += '\n'; - } else if (soy.BLOCK_TAGS_RE_.test(tag)) { - if (/[^\n]$/.test(text)) { - // Block tags don't add more consecutive newlines. - text += '\n'; - } - if (/^pre$/i.test(tag)) { - wsPreservingUntil = '/' + tag.toLowerCase(); - } else if (tag.toLowerCase() == wsPreservingUntil) { - wsPreservingUntil = ''; - } - } else if (/^(td|th)$/i.test(tag)) { - // We add \t even after newline to support more leading . - text += '\t'; - } - } else if (removingUntil == tag.toLowerCase()) { - removingUntil = ''; - } - if (!match[0]) { - break; - } - start = offset + match[0].length; - } - return text; -}; - - -/** @private @const */ -soy.BLOCK_TAGS_RE_ = - /^\/?(address|blockquote|dd|div|dl|dt|h[1-6]|hr|li|ol|p|pre|table|tr|ul)$/i; - -/** - * Escapes HTML, except preserves entities. - * - * Used mainly internally for escaping message strings in attribute and rcdata - * context, where we explicitly want to preserve any existing entities. - * - * @param {?} value Value to normalize. - * @return {string} A value safe to insert in HTML without any quotes or angle - * brackets. - */ -soy.$$normalizeHtml = function(value) { - return soy.esc.$$normalizeHtmlHelper(value); -}; - - -/** - * Escapes HTML special characters in a string so that it can be embedded in - * RCDATA. - *

- * Escapes HTML special characters so that the value will not prematurely end - * the body of a tag like ``. - *

- * Will normalize known safe HTML to make sure that sanitized HTML (which could - * contain an innocuous `` don't prematurely end an RCDATA - * element. - * - * @param {?} value The string-like value to be escaped. May not be a string, - * but the value will be coerced to a string. - * @return {string} An escaped version of value. - */ -soy.$$escapeHtmlRcdata = function(value) { - if (soy.checks.isHtml(value)) { - return soy.esc.$$normalizeHtmlHelper(value.getContent()); - } - return soy.esc.$$escapeHtmlHelper(value); -}; - - -/** - * Matches any/only HTML5 void elements' start tags. - * See http://www.w3.org/TR/html-markup/syntax.html#syntax-elements - * @const {!RegExp} - * @private - */ -soy.$$HTML5_VOID_ELEMENTS_ = new RegExp( - '^<(?:area|base|br|col|command|embed|hr|img|input' + - '|keygen|link|meta|param|source|track|wbr)\\b'); - - -/** - * Removes HTML tags from a string of known safe HTML. - * If opt_tagWhitelist is not specified or is empty, then - * the result can be used as an attribute value. - * - * @param {?} value The HTML to be escaped. May not be a string, but the - * value will be coerced to a string. - * @param {?Object=} opt_tagWhitelist Has an own property whose - * name is a lower-case tag name and whose value is `1` for - * each element that is allowed in the output. - * @return {string} A representation of value without disallowed tags, - * HTML comments, or other non-text content. - */ -soy.$$stripHtmlTags = function(value, opt_tagWhitelist) { - if (!opt_tagWhitelist) { - // If we have no white-list, then use a fast track which elides all tags. - return String(value).replace(soy.esc.$$HTML_TAG_REGEX_, '') - // This is just paranoia since callers should normalize the result - // anyway, but if they didn't, it would be necessary to ensure that - // after the first replace non-tag uses of < do not recombine into - // tags as in "<script>alert(1337)script>". - .replace(soy.esc.$$LT_REGEX_, '<'); - } - - // Escapes '[' so that we can use [123] below to mark places where tags - // have been removed. - var html = String(value).replace(/\[/g, '['); - - // Consider all uses of '<' and replace whitelisted tags with markers like - // [1] which are indices into a list of approved tag names. - // Replace all other uses of < and > with entities. - var tags = []; - var attrs = []; - html = html.replace( - soy.esc.$$HTML_TAG_REGEX_, - function(tok, tagName) { - if (tagName) { - tagName = tagName.toLowerCase(); - if (opt_tagWhitelist.hasOwnProperty(tagName) && - opt_tagWhitelist[tagName]) { - var isClose = tok.charAt(1) == '/'; - var index = tags.length; - var start = ''; - attrs[index] = attributes; - return '[' + index + ']'; - } - } - return ''; - }); - - // Escape HTML special characters. Now there are no '<' in html that could - // start a tag. - html = soy.esc.$$normalizeHtmlHelper(html); - - var finalCloseTags = soy.$$balanceTags_(tags); - - // Now html contains no tags or less-than characters that could become - // part of a tag via a replacement operation and tags only contains - // approved tags. - // Reinsert the white-listed tags. - html = html.replace(/\[(\d+)\]/g, function(_, index) { - if (attrs[index] && tags[index]) { - return tags[index].substr(0, tags[index].length - 1) + attrs[index] + '>'; - } - return tags[index]; - }); - - // Close any still open tags. - // This prevents unclosed formatting elements like

    and from - // breaking the layout of containing HTML. - return html + finalCloseTags; -}; - - -/** - * Make sure that tag boundaries are not broken by Safe CSS when embedded in a - * `