Page MenuHomestyx hydra

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/.arcconfig b/.arcconfig
index 1e949e42ce..2d7555dc10 100644
--- a/.arcconfig
+++ b/.arcconfig
@@ -1,10 +1,11 @@
{
"project_id" : "phabricator",
"conduit_uri" : "https://secure.phabricator.com/api/",
"lint.engine" : "PhabricatorLintEngine",
"unit.engine" : "PhutilUnitTestEngine",
"phutil_libraries" : {
"phabricator" : "src/"
},
- "lint.xhpast.naminghook" : "PhabricatorSymbolNameLinter"
+ "lint.xhpast.naminghook" : "PhabricatorSymbolNameLinter",
+ "lint.jshint.config" : "support/jshint/jshintconfig"
}
diff --git a/externals/JsShrink/jsShrink.php b/externals/JsShrink/jsShrink.php
new file mode 100644
index 0000000000..36f1c39335
--- /dev/null
+++ b/externals/JsShrink/jsShrink.php
@@ -0,0 +1,45 @@
+<?php
+/** Remove spaces and comments from JavaScript code
+* @param string code with commands terminated by semicolon
+* @return string shrinked code
+* @link http://vrana.github.com/JsShrink/
+* @author Jakub Vrana, http://www.vrana.cz/
+* @copyright 2007 Jakub Vrana
+* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
+*/
+function jsShrink($input) {
+ return preg_replace_callback('(
+ (?:
+ (^|[-+\([{}=,:;!%^&*|?~]|/(?![/*])|return|throw) # context before regexp
+ (?:\s|//[^\n]*+\n|/\*(?:[^*]|\*(?!/))*+\*/)* # optional space
+ (/(?![/*])(?:\\\\[^\n]|[^[\n/\\\\]|\[(?:\\\\[^\n]|[^]])++)+/) # regexp
+ |(^
+ |\'(?:\\\\.|[^\n\'\\\\])*\'
+ |"(?:\\\\.|[^\n"\\\\])*"
+ |([0-9A-Za-z_$]+)
+ |([-+]+)
+ |.
+ )
+ )(?:\s|//[^\n]*+\n|/\*(?:[^*]|\*(?!/))*+\*/)* # optional space
+ )sx', 'jsShrinkCallback', "$input\n");
+}
+
+function jsShrinkCallback($match) {
+ static $last = '';
+ $match += array_fill(1, 5, null); // avoid E_NOTICE
+ list(, $context, $regexp, $result, $word, $operator) = $match;
+ if ($word != '') {
+ $result = ($last == 'word' ? "\n" : ($last == 'return' ? " " : "")) . $result;
+ $last = ($word == 'return' || $word == 'throw' || $word == 'break' ? 'return' : 'word');
+ } elseif ($operator) {
+ $result = ($last == $operator[0] ? "\n" : "") . $result;
+ $last = $operator[0];
+ } else {
+ if ($regexp) {
+ $result = $context . ($context == '/' ? "\n" : "") . $regexp;
+ }
+ $last = '';
+ }
+ return $result;
+}
diff --git a/externals/JsShrink/readme.txt b/externals/JsShrink/readme.txt
new file mode 100644
index 0000000000..8b59308c72
--- /dev/null
+++ b/externals/JsShrink/readme.txt
@@ -0,0 +1,23 @@
+JsShrink - Remove spaces and comments from JavaScript code
+Available in PHP and JavaScript
+Requires statements ending by semicolon, use JSHint or JSLint to verify.
+
+http://vrana.github.com/JsShrink/
+
+Usage PHP:
+<?php
+include "jsShrink.php";
+echo jsShrink($code);
+?>
+
+Usage JavaScript:
+<script type="text/javascript" src="jsShrink.js"></script>
+<script type="text/javascript">
+textarea.value = jsShrink(code);
+</script>
+
+Note:
+Google Closure Compiler is much more powerful and efficient tool.
+JsShrink was created for those looking for PHP or JavaScript only solution.
+Most other JS minifiers are not able to process valid JavaScript code:
+http://php.vrana.cz/minifikace-javascriptu.php#srovnani
diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php
index 4cfe033d0d..929b412f44 100644
--- a/src/__celerity_resource_map__.php
+++ b/src/__celerity_resource_map__.php
@@ -1,4400 +1,4378 @@
<?php
/**
* This file is automatically generated. Use 'celerity_mapper.php' to rebuild
* it.
* @generated
*/
celerity_register_resource_map(array(
'/rsrc/image/actions/edit.png' =>
array(
'hash' => 'ae90914d120ac3838ddc633b480343f3',
'uri' => '/res/ae90914d/rsrc/image/actions/edit.png',
'disk' => '/rsrc/image/actions/edit.png',
'type' => 'png',
),
'/rsrc/image/apple-touch-icon.png' =>
array(
'hash' => '3380adf2dd4a5efa0885618bc5943640',
'uri' => '/res/3380adf2/rsrc/image/apple-touch-icon.png',
'disk' => '/rsrc/image/apple-touch-icon.png',
'type' => 'png',
),
'/rsrc/image/avatar.png' =>
array(
'hash' => '1c5f255071537f05406adee86717ff27',
'uri' => '/res/1c5f2550/rsrc/image/avatar.png',
'disk' => '/rsrc/image/avatar.png',
'type' => 'png',
),
'/rsrc/image/checker_dark.png' =>
array(
'hash' => '640f795343df76ebe5409aae6187e57f',
'uri' => '/res/640f7953/rsrc/image/checker_dark.png',
'disk' => '/rsrc/image/checker_dark.png',
'type' => 'png',
),
'/rsrc/image/checker_light.png' =>
array(
'hash' => '7f8f3ef8beb0f2cc4cc69efb9e1c3308',
'uri' => '/res/7f8f3ef8/rsrc/image/checker_light.png',
'disk' => '/rsrc/image/checker_light.png',
'type' => 'png',
),
'/rsrc/image/credit_cards.png' =>
array(
'hash' => '681448de424ea159b6ea68af04c046ae',
'uri' => '/res/681448de/rsrc/image/credit_cards.png',
'disk' => '/rsrc/image/credit_cards.png',
'type' => 'png',
),
'/rsrc/image/darkload.gif' =>
array(
'hash' => '3a52cb7145d6e70f461fed21273117f2',
'uri' => '/res/3a52cb71/rsrc/image/darkload.gif',
'disk' => '/rsrc/image/darkload.gif',
'type' => 'gif',
),
'/rsrc/image/divot.png' =>
array(
'hash' => '3be267bd11ea375bf68e808893718e0e',
'uri' => '/res/3be267bd/rsrc/image/divot.png',
'disk' => '/rsrc/image/divot.png',
'type' => 'png',
),
'/rsrc/image/grippy_texture.png' =>
array(
'hash' => 'a8945e12ceeaddd5b491a8d81cfa19c1',
'uri' => '/res/a8945e12/rsrc/image/grippy_texture.png',
'disk' => '/rsrc/image/grippy_texture.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/arrow_branch.png' =>
array(
'hash' => 'f27b67520766e3d971722bcff703f3a8',
'uri' => '/res/f27b6752/rsrc/image/icon/fatcow/arrow_branch.png',
'disk' => '/rsrc/image/icon/fatcow/arrow_branch.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/arrow_merge.png' =>
array(
'hash' => 'c4bd97f3b1257439e2123ef69d2194d0',
'uri' => '/res/c4bd97f3/rsrc/image/icon/fatcow/arrow_merge.png',
'disk' => '/rsrc/image/icon/fatcow/arrow_merge.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/bullet_black.png' =>
array(
'hash' => '718f9c560a13766796f1be7dfaadeeab',
'uri' => '/res/718f9c56/rsrc/image/icon/fatcow/bullet_black.png',
'disk' => '/rsrc/image/icon/fatcow/bullet_black.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/bullet_orange.png' =>
array(
'hash' => 'c3bf91b65baacb27f2af143ab9180119',
'uri' => '/res/c3bf91b6/rsrc/image/icon/fatcow/bullet_orange.png',
'disk' => '/rsrc/image/icon/fatcow/bullet_orange.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/bullet_red.png' =>
array(
'hash' => '00273e4aa6ea3de630295610d6c9560c',
'uri' => '/res/00273e4a/rsrc/image/icon/fatcow/bullet_red.png',
'disk' => '/rsrc/image/icon/fatcow/bullet_red.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/calendar_edit.png' =>
array(
'hash' => 'de249c0f4f37bf5b2c69ff39ec5573fb',
'uri' => '/res/de249c0f/rsrc/image/icon/fatcow/calendar_edit.png',
'disk' => '/rsrc/image/icon/fatcow/calendar_edit.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/document_black.png' =>
array(
'hash' => '44d65a7f05a9c921719deedc160d68f7',
'uri' => '/res/44d65a7f/rsrc/image/icon/fatcow/document_black.png',
'disk' => '/rsrc/image/icon/fatcow/document_black.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_blue.png' =>
array(
'hash' => '75a080492f900fbe489e4b27e403962b',
'uri' => '/res/75a08049/rsrc/image/icon/fatcow/flag_blue.png',
'disk' => '/rsrc/image/icon/fatcow/flag_blue.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_finish.png' =>
array(
'hash' => '4af11fc7fab8e4610cbc3c88a02d4f78',
'uri' => '/res/4af11fc7/rsrc/image/icon/fatcow/flag_finish.png',
'disk' => '/rsrc/image/icon/fatcow/flag_finish.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_ghost.png' =>
array(
'hash' => '14c9f30a37b43f276f27a27a924bf02d',
'uri' => '/res/14c9f30a/rsrc/image/icon/fatcow/flag_ghost.png',
'disk' => '/rsrc/image/icon/fatcow/flag_ghost.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_green.png' =>
array(
'hash' => 'fed01374cd396cb774872762dcc447e1',
'uri' => '/res/fed01374/rsrc/image/icon/fatcow/flag_green.png',
'disk' => '/rsrc/image/icon/fatcow/flag_green.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_orange.png' =>
array(
'hash' => '88008cb8bb99761a37e5a743e2455aeb',
'uri' => '/res/88008cb8/rsrc/image/icon/fatcow/flag_orange.png',
'disk' => '/rsrc/image/icon/fatcow/flag_orange.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_pink.png' =>
array(
'hash' => '2f199f06ffc3dfc81b7561a057e0bc33',
'uri' => '/res/2f199f06/rsrc/image/icon/fatcow/flag_pink.png',
'disk' => '/rsrc/image/icon/fatcow/flag_pink.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_purple.png' =>
array(
'hash' => '16358629dc86c39550b575586eb5df80',
'uri' => '/res/16358629/rsrc/image/icon/fatcow/flag_purple.png',
'disk' => '/rsrc/image/icon/fatcow/flag_purple.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_red.png' =>
array(
'hash' => '210c28b4d93c439a499f5814f5e05772',
'uri' => '/res/210c28b4/rsrc/image/icon/fatcow/flag_red.png',
'disk' => '/rsrc/image/icon/fatcow/flag_red.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/flag_yellow.png' =>
array(
'hash' => 'bdfd73744a80bb80329ae50bc8a5f962',
'uri' => '/res/bdfd7374/rsrc/image/icon/fatcow/flag_yellow.png',
'disk' => '/rsrc/image/icon/fatcow/flag_yellow.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/folder.png' =>
array(
'hash' => '25e46cf9d210dde2242332296f79938c',
'uri' => '/res/25e46cf9/rsrc/image/icon/fatcow/folder.png',
'disk' => '/rsrc/image/icon/fatcow/folder.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/folder_go.png' =>
array(
'hash' => 'ba922ff7959309f51a14cb7ed5124d8b',
'uri' => '/res/ba922ff7/rsrc/image/icon/fatcow/folder_go.png',
'disk' => '/rsrc/image/icon/fatcow/folder_go.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/key_question.png' =>
array(
'hash' => '530a6448a4b91edec091a9292ccfd3d9',
'uri' => '/res/530a6448/rsrc/image/icon/fatcow/key_question.png',
'disk' => '/rsrc/image/icon/fatcow/key_question.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/link.png' =>
array(
'hash' => 'be1bea49b216548433014f3324902928',
'uri' => '/res/be1bea49/rsrc/image/icon/fatcow/link.png',
'disk' => '/rsrc/image/icon/fatcow/link.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/page_white_edit.png' =>
array(
'hash' => 'e7b7e7f2d9730bc80bc5c9eac1f3e36d',
'uri' => '/res/e7b7e7f2/rsrc/image/icon/fatcow/page_white_edit.png',
'disk' => '/rsrc/image/icon/fatcow/page_white_edit.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/page_white_link.png' =>
array(
'hash' => '1cfbad14412bda6c6f132dcc7c8725fd',
'uri' => '/res/1cfbad14/rsrc/image/icon/fatcow/page_white_link.png',
'disk' => '/rsrc/image/icon/fatcow/page_white_link.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/page_white_put.png' =>
array(
'hash' => 'bb7308aa5ac40137a8262da395a267fd',
'uri' => '/res/bb7308aa/rsrc/image/icon/fatcow/page_white_put.png',
'disk' => '/rsrc/image/icon/fatcow/page_white_put.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/page_white_text.png' =>
array(
'hash' => 'e47d590b626f617fb7d1d44e96e8fd11',
'uri' => '/res/e47d590b/rsrc/image/icon/fatcow/page_white_text.png',
'disk' => '/rsrc/image/icon/fatcow/page_white_text.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/conduit.png' =>
array(
'hash' => '1cae0656580aa3cd0b54b9d98306b1b9',
'uri' => '/res/1cae0656/rsrc/image/icon/fatcow/source/conduit.png',
'disk' => '/rsrc/image/icon/fatcow/source/conduit.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/email.png' =>
array(
'hash' => '93bdb3e168da1ed68f50c42125729d4e',
'uri' => '/res/93bdb3e1/rsrc/image/icon/fatcow/source/email.png',
'disk' => '/rsrc/image/icon/fatcow/source/email.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/fax.png' =>
array(
'hash' => 'd7dedf229841f2d041b347afd881596f',
'uri' => '/res/d7dedf22/rsrc/image/icon/fatcow/source/fax.png',
'disk' => '/rsrc/image/icon/fatcow/source/fax.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/mobile.png' =>
array(
'hash' => '786e7146d1e7d7318baf76c9d2baad97',
'uri' => '/res/786e7146/rsrc/image/icon/fatcow/source/mobile.png',
'disk' => '/rsrc/image/icon/fatcow/source/mobile.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/tablet.png' =>
array(
'hash' => '374cd40e4965be6b2fbdef4059d0ca05',
'uri' => '/res/374cd40e/rsrc/image/icon/fatcow/source/tablet.png',
'disk' => '/rsrc/image/icon/fatcow/source/tablet.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/source/web.png' =>
array(
'hash' => 'f4882a8f5619ba505ca033f72a340635',
'uri' => '/res/f4882a8f/rsrc/image/icon/fatcow/source/web.png',
'disk' => '/rsrc/image/icon/fatcow/source/web.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/default160x120.png' =>
array(
'hash' => '1b52ebd1fe0eee3ed0abfc382991b265',
'uri' => '/res/1b52ebd1/rsrc/image/icon/fatcow/thumbnails/default160x120.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/default160x120.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/default60x45.png' =>
array(
'hash' => '048d851d8d1daad4754e891e734c1899',
'uri' => '/res/048d851d/rsrc/image/icon/fatcow/thumbnails/default60x45.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/default60x45.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/image160x120.png' =>
array(
'hash' => '434acbd8dbbc2da9f09f6205a396eba1',
'uri' => '/res/434acbd8/rsrc/image/icon/fatcow/thumbnails/image160x120.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/image160x120.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/image60x45.png' =>
array(
'hash' => '29f7872dc53588fe0b8f0b330c7ee23a',
'uri' => '/res/29f7872d/rsrc/image/icon/fatcow/thumbnails/image60x45.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/image60x45.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/pdf160x120.png' =>
array(
'hash' => '39d2e22541658a3472ba41ae2fa548e5',
'uri' => '/res/39d2e225/rsrc/image/icon/fatcow/thumbnails/pdf160x120.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/pdf160x120.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/pdf60x45.png' =>
array(
'hash' => 'b3572e9317cbed5184d12bdfabed2727',
'uri' => '/res/b3572e93/rsrc/image/icon/fatcow/thumbnails/pdf60x45.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/pdf60x45.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/zip160x120.png' =>
array(
'hash' => 'e505108688a903b5cfb674707a289bcc',
'uri' => '/res/e5051086/rsrc/image/icon/fatcow/thumbnails/zip160x120.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/zip160x120.png',
'type' => 'png',
),
'/rsrc/image/icon/fatcow/thumbnails/zip60x45.png' =>
array(
'hash' => 'f00716f4e8f7a95e70d43504f06be0a6',
'uri' => '/res/f00716f4/rsrc/image/icon/fatcow/thumbnails/zip60x45.png',
'disk' => '/rsrc/image/icon/fatcow/thumbnails/zip60x45.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/close-2.png' =>
array(
'hash' => '72ff3ddcc1ed5d19a715ed6242114b53',
'uri' => '/res/72ff3ddc/rsrc/image/icon/lightbox/close-2.png',
'disk' => '/rsrc/image/icon/lightbox/close-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/close-hover-2.png' =>
array(
'hash' => '6ad4bd4a7820547a1d9041752546ba16',
'uri' => '/res/6ad4bd4a/rsrc/image/icon/lightbox/close-hover-2.png',
'disk' => '/rsrc/image/icon/lightbox/close-hover-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/left-arrow-2.png' =>
array(
'hash' => 'd84cbb0d42739f87b8f25b2f1d2f1153',
'uri' => '/res/d84cbb0d/rsrc/image/icon/lightbox/left-arrow-2.png',
'disk' => '/rsrc/image/icon/lightbox/left-arrow-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/left-arrow-hover-2.png' =>
array(
'hash' => 'cdf05f98fff3f390cd8df0c89894a3e1',
'uri' => '/res/cdf05f98/rsrc/image/icon/lightbox/left-arrow-hover-2.png',
'disk' => '/rsrc/image/icon/lightbox/left-arrow-hover-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/right-arrow-2.png' =>
array(
'hash' => '52021038cb6995c71f62a804bc2d420d',
'uri' => '/res/52021038/rsrc/image/icon/lightbox/right-arrow-2.png',
'disk' => '/rsrc/image/icon/lightbox/right-arrow-2.png',
'type' => 'png',
),
'/rsrc/image/icon/lightbox/right-arrow-hover-2.png' =>
array(
'hash' => '65d5756b7b9cfcdeb2eb197a9aa6bbd2',
'uri' => '/res/65d5756b/rsrc/image/icon/lightbox/right-arrow-hover-2.png',
'disk' => '/rsrc/image/icon/lightbox/right-arrow-hover-2.png',
'type' => 'png',
),
'/rsrc/image/icon/subscribe.png' =>
array(
'hash' => '5f47a4b17de245af39a4e7a097e40623',
'uri' => '/res/5f47a4b1/rsrc/image/icon/subscribe.png',
'disk' => '/rsrc/image/icon/subscribe.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/attachment.png' =>
array(
'hash' => '776fed2de89803fd8a0ba4b9deede230',
'uri' => '/res/776fed2d/rsrc/image/icon/tango/attachment.png',
'disk' => '/rsrc/image/icon/tango/attachment.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/edit.png' =>
array(
'hash' => 'c0028d99dcf4e9559bbf3c88ce2d8a8d',
'uri' => '/res/c0028d99/rsrc/image/icon/tango/edit.png',
'disk' => '/rsrc/image/icon/tango/edit.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/go-down.png' =>
array(
'hash' => '96862812cbb0445573c264dc057b8300',
'uri' => '/res/96862812/rsrc/image/icon/tango/go-down.png',
'disk' => '/rsrc/image/icon/tango/go-down.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/log.png' =>
array(
'hash' => 'a6f72499bef279ff6807a7dbc5148f1e',
'uri' => '/res/a6f72499/rsrc/image/icon/tango/log.png',
'disk' => '/rsrc/image/icon/tango/log.png',
'type' => 'png',
),
'/rsrc/image/icon/tango/upload.png' =>
array(
'hash' => '8c11b63d6d99db3d7159c5d9a94e3062',
'uri' => '/res/8c11b63d/rsrc/image/icon/tango/upload.png',
'disk' => '/rsrc/image/icon/tango/upload.png',
'type' => 'png',
),
'/rsrc/image/icon/unsubscribe.png' =>
array(
'hash' => '29429ad65aa3af50b072b32087057361',
'uri' => '/res/29429ad6/rsrc/image/icon/unsubscribe.png',
'disk' => '/rsrc/image/icon/unsubscribe.png',
'type' => 'png',
),
'/rsrc/image/loading.gif' =>
array(
'hash' => '664297671941142f37d8c89e717ff2ce',
'uri' => '/res/66429767/rsrc/image/loading.gif',
'disk' => '/rsrc/image/loading.gif',
'type' => 'gif',
),
'/rsrc/image/loading/loading_24.gif' =>
array(
'hash' => 'd6dcc5e6111a44fb9a160fc27b19d85c',
'uri' => '/res/d6dcc5e6/rsrc/image/loading/loading_24.gif',
'disk' => '/rsrc/image/loading/loading_24.gif',
'type' => 'gif',
),
'/rsrc/image/loading/loading_48.gif' =>
array(
'hash' => 'cb6fc6eb9c0a0efaf589978029080c58',
'uri' => '/res/cb6fc6eb/rsrc/image/loading/loading_48.gif',
'disk' => '/rsrc/image/loading/loading_48.gif',
'type' => 'gif',
),
'/rsrc/image/main_texture.png' =>
array(
'hash' => 'e34d8143384721be73ec9b7532a977ab',
'uri' => '/res/e34d8143/rsrc/image/main_texture.png',
'disk' => '/rsrc/image/main_texture.png',
'type' => 'png',
),
'/rsrc/image/menu_texture.png' =>
array(
'hash' => 'ad020b1529b3a3b3480ca9de1d5f1e40',
'uri' => '/res/ad020b15/rsrc/image/menu_texture.png',
'disk' => '/rsrc/image/menu_texture.png',
'type' => 'png',
),
'/rsrc/image/people/harding.png' =>
array(
'hash' => '818b035ace2c480aa8df7b7f11cef58b',
'uri' => '/res/818b035a/rsrc/image/people/harding.png',
'disk' => '/rsrc/image/people/harding.png',
'type' => 'png',
),
'/rsrc/image/people/jefferson.png' =>
array(
'hash' => '55fe807ff02f9320e595fb59442e2038',
'uri' => '/res/55fe807f/rsrc/image/people/jefferson.png',
'disk' => '/rsrc/image/people/jefferson.png',
'type' => 'png',
),
'/rsrc/image/people/lincoln.png' =>
array(
'hash' => '2363337947ab52fd5fda79e4a004e930',
'uri' => '/res/23633379/rsrc/image/people/lincoln.png',
'disk' => '/rsrc/image/people/lincoln.png',
'type' => 'png',
),
'/rsrc/image/people/mckinley.png' =>
array(
'hash' => '0b7b05dd47c49a0874670e5e8200bba8',
'uri' => '/res/0b7b05dd/rsrc/image/people/mckinley.png',
'disk' => '/rsrc/image/people/mckinley.png',
'type' => 'png',
),
'/rsrc/image/people/taft.png' =>
array(
'hash' => 'f3e47d45b59b0b009fd536dabae9a151',
'uri' => '/res/f3e47d45/rsrc/image/people/taft.png',
'disk' => '/rsrc/image/people/taft.png',
'type' => 'png',
),
'/rsrc/image/people/washington.png' =>
array(
'hash' => '01412761cab769f7993d69eba986d949',
'uri' => '/res/01412761/rsrc/image/people/washington.png',
'disk' => '/rsrc/image/people/washington.png',
'type' => 'png',
),
'/rsrc/image/phrequent_active.png' =>
array(
'hash' => '716cddc08630eaa33934b2008723cac0',
'uri' => '/res/716cddc0/rsrc/image/phrequent_active.png',
'disk' => '/rsrc/image/phrequent_active.png',
'type' => 'png',
),
'/rsrc/image/phrequent_inactive.png' =>
array(
'hash' => 'f9099683873c01c5de1dc6650bd668fe',
'uri' => '/res/f9099683/rsrc/image/phrequent_inactive.png',
'disk' => '/rsrc/image/phrequent_inactive.png',
'type' => 'png',
),
'/rsrc/image/search.png' =>
array(
'hash' => 'ff7da044e6f923b8f569dec11f97e5e5',
'uri' => '/res/ff7da044/rsrc/image/search.png',
'disk' => '/rsrc/image/search.png',
'type' => 'png',
),
'/rsrc/image/sprite-actions-X2.png' =>
array(
'hash' => '06962a5e8bea98ba7418d1d6cabcd7dc',
'uri' => '/res/06962a5e/rsrc/image/sprite-actions-X2.png',
'disk' => '/rsrc/image/sprite-actions-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-actions.png' =>
array(
'hash' => 'd5dda5fab1e61b00538c9a4fa1ee94c8',
'uri' => '/res/d5dda5fa/rsrc/image/sprite-actions.png',
'disk' => '/rsrc/image/sprite-actions.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps-X2.png' =>
array(
'hash' => '35a4b5c92f0b05a6a06c8a8e2f409d9e',
'uri' => '/res/35a4b5c9/rsrc/image/sprite-apps-X2.png',
'disk' => '/rsrc/image/sprite-apps-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps-large-X2.png' =>
array(
'hash' => '6295f60df446103f0de702f25bc502e1',
'uri' => '/res/6295f60d/rsrc/image/sprite-apps-large-X2.png',
'disk' => '/rsrc/image/sprite-apps-large-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps-large.png' =>
array(
'hash' => '734d9268dd3a69102b194a7461c68631',
'uri' => '/res/734d9268/rsrc/image/sprite-apps-large.png',
'disk' => '/rsrc/image/sprite-apps-large.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps-xlarge.png' =>
array(
'hash' => '992d2c278b6a22c0fa874d457a252fbd',
'uri' => '/res/992d2c27/rsrc/image/sprite-apps-xlarge.png',
'disk' => '/rsrc/image/sprite-apps-xlarge.png',
'type' => 'png',
),
'/rsrc/image/sprite-apps.png' =>
array(
'hash' => 'eed2e0e322821e1c0836fc62639c1af1',
'uri' => '/res/eed2e0e3/rsrc/image/sprite-apps.png',
'disk' => '/rsrc/image/sprite-apps.png',
'type' => 'png',
),
'/rsrc/image/sprite-conpherence-X2.png' =>
array(
'hash' => '5e47868b00933a9afb6c844e464e6b23',
'uri' => '/res/5e47868b/rsrc/image/sprite-conpherence-X2.png',
'disk' => '/rsrc/image/sprite-conpherence-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-conpherence.png' =>
array(
'hash' => 'ca51f1be25213262d68e626e4cab7f0f',
'uri' => '/res/ca51f1be/rsrc/image/sprite-conpherence.png',
'disk' => '/rsrc/image/sprite-conpherence.png',
'type' => 'png',
),
'/rsrc/image/sprite-docs-X2.png' =>
array(
'hash' => '57d3286ce88133f3ec9240e35f6bb897',
'uri' => '/res/57d3286c/rsrc/image/sprite-docs-X2.png',
'disk' => '/rsrc/image/sprite-docs-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-docs.png' =>
array(
'hash' => 'b2b089072d6eddd831402a77c02b5736',
'uri' => '/res/b2b08907/rsrc/image/sprite-docs.png',
'disk' => '/rsrc/image/sprite-docs.png',
'type' => 'png',
),
'/rsrc/image/sprite-gradient.png' =>
array(
'hash' => 'a49d2e493dba4bea85bb202af528106a',
'uri' => '/res/a49d2e49/rsrc/image/sprite-gradient.png',
'disk' => '/rsrc/image/sprite-gradient.png',
'type' => 'png',
),
'/rsrc/image/sprite-icons-X2.png' =>
array(
'hash' => '74551ad4423b882608a7325febe96a87',
'uri' => '/res/74551ad4/rsrc/image/sprite-icons-X2.png',
'disk' => '/rsrc/image/sprite-icons-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-icons.png' =>
array(
'hash' => '04e38e15232e1e0dee5acb9ae9b5ac72',
'uri' => '/res/04e38e15/rsrc/image/sprite-icons.png',
'disk' => '/rsrc/image/sprite-icons.png',
'type' => 'png',
),
'/rsrc/image/sprite-menu-X2.png' =>
array(
'hash' => '867092041ce0a62b7e50136213ca7be1',
'uri' => '/res/86709204/rsrc/image/sprite-menu-X2.png',
'disk' => '/rsrc/image/sprite-menu-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-menu.png' =>
array(
'hash' => '21508eebdf582d7251d62bb2cd09f66d',
'uri' => '/res/21508eeb/rsrc/image/sprite-menu.png',
'disk' => '/rsrc/image/sprite-menu.png',
'type' => 'png',
),
'/rsrc/image/sprite-minicons-X2.png' =>
array(
'hash' => 'c420c6462f7e50ca9941ccc5dd9e3dec',
'uri' => '/res/c420c646/rsrc/image/sprite-minicons-X2.png',
'disk' => '/rsrc/image/sprite-minicons-X2.png',
'type' => 'png',
),
'/rsrc/image/sprite-minicons.png' =>
array(
'hash' => '168bb875933624b3080a1cc134e5b4ed',
'uri' => '/res/168bb875/rsrc/image/sprite-minicons.png',
'disk' => '/rsrc/image/sprite-minicons.png',
'type' => 'png',
),
'/rsrc/image/sprite-payments.png' =>
array(
'hash' => '5ce73fb580609e7cda16832e3577b147',
'uri' => '/res/5ce73fb5/rsrc/image/sprite-payments.png',
'disk' => '/rsrc/image/sprite-payments.png',
'type' => 'png',
),
'/rsrc/image/sprite-tokens.png' =>
array(
'hash' => '67c46fd75c885b76ecbfe46e71a476cc',
'uri' => '/res/67c46fd7/rsrc/image/sprite-tokens.png',
'disk' => '/rsrc/image/sprite-tokens.png',
'type' => 'png',
),
'/rsrc/image/texture/card-gradient.png' =>
array(
'hash' => '268b7fdd758d4bf99db8de6770aae8af',
'uri' => '/res/268b7fdd/rsrc/image/texture/card-gradient.png',
'disk' => '/rsrc/image/texture/card-gradient.png',
'type' => 'png',
),
'/rsrc/image/texture/dark-menu-hover.png' =>
array(
'hash' => 'a214a732644be34872e895b338b5d639',
'uri' => '/res/a214a732/rsrc/image/texture/dark-menu-hover.png',
'disk' => '/rsrc/image/texture/dark-menu-hover.png',
'type' => 'png',
),
'/rsrc/image/texture/dark-menu.png' =>
array(
'hash' => '41ee673a762cec48a154b456ad5ac204',
'uri' => '/res/41ee673a/rsrc/image/texture/dark-menu.png',
'disk' => '/rsrc/image/texture/dark-menu.png',
'type' => 'png',
),
'/rsrc/image/texture/grip.png' =>
array(
'hash' => 'f11bc231d241f1335cfca2933ad234e0',
'uri' => '/res/f11bc231/rsrc/image/texture/grip.png',
'disk' => '/rsrc/image/texture/grip.png',
'type' => 'png',
),
'/rsrc/image/texture/panel-header-gradient.png' =>
array(
'hash' => 'ad9204dd3ef5b12b645d80677d8ccead',
'uri' => '/res/ad9204dd/rsrc/image/texture/panel-header-gradient.png',
'disk' => '/rsrc/image/texture/panel-header-gradient.png',
'type' => 'png',
),
'/rsrc/image/texture/pholio-background.gif' =>
array(
'hash' => 'cf4561af116edf393dc583e5119fb412',
'uri' => '/res/cf4561af/rsrc/image/texture/pholio-background.gif',
'disk' => '/rsrc/image/texture/pholio-background.gif',
'type' => 'gif',
),
'/rsrc/image/texture/table_header.png' =>
array(
'hash' => '4ed3f56a30d3749e8f62052b9735a316',
'uri' => '/res/4ed3f56a/rsrc/image/texture/table_header.png',
'disk' => '/rsrc/image/texture/table_header.png',
'type' => 'png',
),
'/rsrc/image/texture/table_header_hover.png' =>
array(
'hash' => 'ea1f71a604e9b4859de1e25751540437',
'uri' => '/res/ea1f71a6/rsrc/image/texture/table_header_hover.png',
'disk' => '/rsrc/image/texture/table_header_hover.png',
'type' => 'png',
),
'/rsrc/image/texture/table_header_tall.png' =>
array(
'hash' => 'b05525601f78d759f1c5e47fd9c1a8aa',
'uri' => '/res/b0552560/rsrc/image/texture/table_header_tall.png',
'disk' => '/rsrc/image/texture/table_header_tall.png',
'type' => 'png',
),
'/rsrc/swf/aphlict.swf' =>
array(
'hash' => '4b9a9d83bebaf254f3790e87b45c1f92',
'uri' => '/res/4b9a9d83/rsrc/swf/aphlict.swf',
'disk' => '/rsrc/swf/aphlict.swf',
'type' => 'swf',
),
'aphront-attached-file-view-css' =>
array(
'uri' => '/res/a6ca5487/rsrc/css/aphront/attached-file-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/attached-file-view.css',
),
'aphront-bars' =>
array(
'uri' => '/res/95a907d6/rsrc/css/aphront/aphront-bars.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/aphront-bars.css',
),
'aphront-calendar-view-css' =>
array(
'uri' => '/res/ae6f5b54/rsrc/css/aphront/calendar-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/calendar-view.css',
),
'aphront-contextbar-view-css' =>
array(
'uri' => '/res/ecfd5ba9/rsrc/css/aphront/context-bar.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/context-bar.css',
),
'aphront-dark-console-css' =>
array(
'uri' => '/res/0d316573/rsrc/css/aphront/dark-console.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/dark-console.css',
),
'aphront-dialog-view-css' =>
array(
'uri' => '/res/7060a2fe/rsrc/css/aphront/dialog-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/dialog-view.css',
),
'aphront-error-view-css' =>
array(
'uri' => '/res/5f43a7c5/rsrc/css/aphront/error-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/error-view.css',
),
'aphront-form-view-css' =>
array(
'uri' => '/res/cc40cdff/rsrc/css/aphront/form-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/form-view.css',
),
'aphront-list-filter-view-css' =>
array(
'uri' => '/res/639ea9e9/rsrc/css/aphront/list-filter-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/list-filter-view.css',
),
'aphront-multi-column-view-css' =>
array(
'uri' => '/res/4e5ae0f3/rsrc/css/aphront/multi-column.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/multi-column.css',
),
'aphront-notes' =>
array(
'uri' => '/res/5b8ebfa0/rsrc/css/aphront/aphront-notes.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/aphront-notes.css',
),
'aphront-pager-view-css' =>
array(
'uri' => '/res/43fb79f0/rsrc/css/aphront/pager-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/pager-view.css',
),
'aphront-panel-view-css' =>
array(
'uri' => '/res/4031ea99/rsrc/css/aphront/panel-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/panel-view.css',
),
'aphront-request-failure-view-css' =>
array(
'uri' => '/res/c9a43002/rsrc/css/aphront/request-failure-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/request-failure-view.css',
),
'aphront-table-view-css' =>
array(
'uri' => '/res/d3c44c69/rsrc/css/aphront/table-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/table-view.css',
),
'aphront-tokenizer-control-css' =>
array(
'uri' => '/res/793c5f36/rsrc/css/aphront/tokenizer.css',
'type' => 'css',
'requires' =>
array(
0 => 'aphront-typeahead-control-css',
),
'disk' => '/rsrc/css/aphront/tokenizer.css',
),
'aphront-tooltip-css' =>
array(
'uri' => '/res/3a7d8e07/rsrc/css/aphront/tooltip.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/tooltip.css',
),
'aphront-two-column-view-css' =>
array(
'uri' => '/res/4263aa98/rsrc/css/aphront/two-column.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/two-column.css',
),
'aphront-typeahead-control-css' =>
array(
'uri' => '/res/e4a4cd4b/rsrc/css/aphront/typeahead.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/typeahead.css',
),
'config-options-css' =>
array(
'uri' => '/res/be77d5a6/rsrc/css/application/config/config-options.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/config/config-options.css',
),
'conpherence-header-pane-css' =>
array(
'uri' => '/res/dc654fce/rsrc/css/application/conpherence/header-pane.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/header-pane.css',
),
'conpherence-menu-css' =>
array(
'uri' => '/res/9991071e/rsrc/css/application/conpherence/menu.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/menu.css',
),
'conpherence-message-pane-css' =>
array(
'uri' => '/res/52cf7ca3/rsrc/css/application/conpherence/message-pane.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/message-pane.css',
),
'conpherence-update-css' =>
array(
'uri' => '/res/92094ed7/rsrc/css/application/conpherence/update.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/update.css',
),
'conpherence-widget-pane-css' =>
array(
'uri' => '/res/197df36c/rsrc/css/application/conpherence/widget-pane.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/conpherence/widget-pane.css',
),
'differential-changeset-view-css' =>
array(
'uri' => '/res/8ee213f4/rsrc/css/application/differential/changeset-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/changeset-view.css',
),
'differential-core-view-css' =>
array(
'uri' => '/res/85fe5117/rsrc/css/application/differential/core.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/core.css',
),
'differential-inline-comment-editor' =>
array(
- 'uri' => '/res/e0ad34ac/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
+ 'uri' => '/res/37e0564f/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-dom',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-install',
4 => 'javelin-request',
5 => 'javelin-workflow',
),
'disk' => '/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
),
'differential-local-commits-view-css' =>
array(
'uri' => '/res/224f3703/rsrc/css/application/differential/local-commits-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/local-commits-view.css',
),
'differential-results-table-css' =>
array(
'uri' => '/res/aab3123c/rsrc/css/application/differential/results-table.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/results-table.css',
),
'differential-revision-add-comment-css' =>
array(
'uri' => '/res/849748d3/rsrc/css/application/differential/add-comment.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/add-comment.css',
),
'differential-revision-comment-css' =>
array(
'uri' => '/res/42c222f4/rsrc/css/application/differential/revision-comment.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/revision-comment.css',
),
'differential-revision-comment-list-css' =>
array(
'uri' => '/res/3b31faa3/rsrc/css/application/differential/revision-comment-list.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/revision-comment-list.css',
),
'differential-revision-history-css' =>
array(
'uri' => '/res/d41bc64c/rsrc/css/application/differential/revision-history.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/revision-history.css',
),
'differential-revision-list-css' =>
array(
'uri' => '/res/fe6c4721/rsrc/css/application/differential/revision-list.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/revision-list.css',
),
'differential-table-of-contents-css' =>
array(
'uri' => '/res/4fde8bfc/rsrc/css/application/differential/table-of-contents.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/differential/table-of-contents.css',
),
'diffusion-commit-view-css' =>
array(
'uri' => '/res/b445944e/rsrc/css/application/diffusion/commit-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/diffusion/commit-view.css',
),
'diffusion-icons-css' =>
array(
'uri' => '/res/b93e32c9/rsrc/css/application/diffusion/diffusion-icons.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/diffusion/diffusion-icons.css',
),
'diffusion-source-css' =>
array(
'uri' => '/res/e76bcd50/rsrc/css/application/diffusion/diffusion-source.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/diffusion/diffusion-source.css',
),
'global-drag-and-drop-css' =>
array(
'uri' => '/res/4e24cb65/rsrc/css/application/files/global-drag-and-drop.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/files/global-drag-and-drop.css',
),
'herald-css' =>
array(
'uri' => '/res/2150a55d/rsrc/css/application/herald/herald.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/herald/herald.css',
),
'herald-rule-editor' =>
array(
'uri' => '/res/f8ee0e9c/rsrc/js/application/herald/HeraldRuleEditor.js',
'type' => 'js',
'requires' =>
array(
0 => 'multirow-row-manager',
1 => 'javelin-install',
2 => 'javelin-typeahead',
3 => 'javelin-util',
4 => 'javelin-dom',
5 => 'javelin-tokenizer',
6 => 'javelin-typeahead-preloaded-source',
7 => 'javelin-stratcom',
8 => 'javelin-json',
9 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/application/herald/HeraldRuleEditor.js',
),
'herald-test-css' =>
array(
'uri' => '/res/c0cd6bdb/rsrc/css/application/herald/herald-test.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/herald/herald-test.css',
),
'inline-comment-summary-css' =>
array(
'uri' => '/res/338704f7/rsrc/css/application/diff/inline-comment-summary.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/diff/inline-comment-summary.css',
),
'javelin-aphlict' =>
array(
'uri' => '/res/c0b9e53f/rsrc/js/application/aphlict/Aphlict.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/js/application/aphlict/Aphlict.js',
),
'javelin-behavior' =>
array(
- 'uri' => '/res/adf7368b/rsrc/externals/javelin/lib/behavior.js',
+ 'uri' => '/res/15482715/rsrc/externals/javelin/lib/behavior.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-magical-init',
+ 1 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/lib/behavior.js',
),
'javelin-behavior-aphlict-dropdown' =>
array(
- 'uri' => '/res/2418f448/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
+ 'uri' => '/res/b3be58e8/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-request',
2 => 'javelin-stratcom',
3 => 'javelin-vector',
4 => 'javelin-dom',
5 => 'javelin-uri',
),
'disk' => '/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
),
'javelin-behavior-aphlict-listen' =>
array(
- 'uri' => '/res/6dde3f43/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
+ 'uri' => '/res/7487f207/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-aphlict',
2 => 'javelin-stratcom',
3 => 'javelin-request',
4 => 'javelin-uri',
5 => 'javelin-dom',
6 => 'javelin-json',
7 => 'phabricator-notification',
),
'disk' => '/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
),
'javelin-behavior-aphront-basic-tokenizer' =>
array(
'uri' => '/res/c7fd9a7b/rsrc/js/core/behavior-tokenizer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/core/behavior-tokenizer.js',
),
'javelin-behavior-aphront-crop' =>
array(
'uri' => '/res/8c800f36/rsrc/js/core/behavior-crop.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-vector',
3 => 'javelin-magical-init',
),
'disk' => '/rsrc/js/core/behavior-crop.js',
),
'javelin-behavior-aphront-drag-and-drop' =>
array(
'uri' => '/res/36335362/rsrc/js/core/behavior-drag-and-drop.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-file-upload',
3 => 'phabricator-drag-and-drop-file-upload',
),
'disk' => '/rsrc/js/core/behavior-drag-and-drop.js',
),
'javelin-behavior-aphront-drag-and-drop-textarea' =>
array(
'uri' => '/res/a261f6e6/rsrc/js/core/behavior-drag-and-drop-textarea.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-drag-and-drop-file-upload',
3 => 'phabricator-textareautils',
),
'disk' => '/rsrc/js/core/behavior-drag-and-drop-textarea.js',
),
'javelin-behavior-aphront-form-disable-on-submit' =>
array(
'uri' => '/res/a4a4ff07/rsrc/js/core/behavior-form.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/behavior-form.js',
),
'javelin-behavior-aphront-more' =>
array(
'uri' => '/res/fae13324/rsrc/js/core/behavior-more.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/behavior-more.js',
),
'javelin-behavior-audit-preview' =>
array(
- 'uri' => '/res/3048b073/rsrc/js/application/diffusion/behavior-audit-preview.js',
+ 'uri' => '/res/d8f31e46/rsrc/js/application/diffusion/behavior-audit-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/diffusion/behavior-audit-preview.js',
),
'javelin-behavior-balanced-payment-form' =>
array(
'uri' => '/res/6876492d/rsrc/js/application/phortune/behavior-balanced-payment-form.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phortune-credit-card-form',
),
'disk' => '/rsrc/js/application/phortune/behavior-balanced-payment-form.js',
),
'javelin-behavior-conpherence-drag-and-drop-photo' =>
array(
'uri' => '/res/9e3eb1cd/rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-workflow',
3 => 'phabricator-drag-and-drop-file-upload',
),
'disk' => '/rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js',
),
'javelin-behavior-conpherence-menu' =>
array(
'uri' => '/res/06bfc1a3/rsrc/js/application/conpherence/behavior-menu.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-request',
4 => 'javelin-stratcom',
5 => 'javelin-workflow',
6 => 'javelin-behavior-device',
7 => 'javelin-history',
8 => 'javelin-vector',
),
'disk' => '/rsrc/js/application/conpherence/behavior-menu.js',
),
'javelin-behavior-conpherence-pontificate' =>
array(
'uri' => '/res/88ac3361/rsrc/js/application/conpherence/behavior-pontificate.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-workflow',
4 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/conpherence/behavior-pontificate.js',
),
'javelin-behavior-conpherence-widget-pane' =>
array(
- 'uri' => '/res/a9bcb950/rsrc/js/application/conpherence/behavior-widget-pane.js',
+ 'uri' => '/res/d2063fd4/rsrc/js/application/conpherence/behavior-widget-pane.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
4 => 'javelin-util',
5 => 'phabricator-notification',
6 => 'javelin-behavior-device',
),
'disk' => '/rsrc/js/application/conpherence/behavior-widget-pane.js',
),
'javelin-behavior-countdown-timer' =>
array(
- 'uri' => '/res/7468acb7/rsrc/js/application/countdown/timer.js',
+ 'uri' => '/res/3c52aac2/rsrc/js/application/countdown/timer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
- 2 => 'javelin-util',
),
'disk' => '/rsrc/js/application/countdown/timer.js',
),
'javelin-behavior-dark-console' =>
array(
'uri' => '/res/1e2c7a5e/rsrc/js/core/behavior-dark-console.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-request',
5 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/core/behavior-dark-console.js',
),
'javelin-behavior-device' =>
array(
'uri' => '/res/12e43f5a/rsrc/js/core/behavior-device.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-install',
),
'disk' => '/rsrc/js/core/behavior-device.js',
),
'javelin-behavior-differential-accept-with-errors' =>
array(
'uri' => '/res/8fea67b3/rsrc/js/application/differential/behavior-accept-with-errors.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-accept-with-errors.js',
),
'javelin-behavior-differential-add-reviewers-and-ccs' =>
array(
'uri' => '/res/27be3f81/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js',
),
'javelin-behavior-differential-comment-jump' =>
array(
- 'uri' => '/res/b580229b/rsrc/js/application/differential/behavior-comment-jump.js',
+ 'uri' => '/res/8ffb4222/rsrc/js/application/differential/behavior-comment-jump.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
- 1 => 'javelin-util',
+ 1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-comment-jump.js',
),
'javelin-behavior-differential-diff-radios' =>
array(
'uri' => '/res/004cb66f/rsrc/js/application/differential/behavior-diff-radios.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-diff-radios.js',
),
'javelin-behavior-differential-dropdown-menus' =>
array(
- 'uri' => '/res/4e3f1e2f/rsrc/js/application/differential/behavior-dropdown-menus.js',
+ 'uri' => '/res/f04cf682/rsrc/js/application/differential/behavior-dropdown-menus.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-stratcom',
4 => 'phabricator-dropdown-menu',
5 => 'phabricator-menu-item',
6 => 'phabricator-phtize',
),
'disk' => '/rsrc/js/application/differential/behavior-dropdown-menus.js',
),
'javelin-behavior-differential-edit-inline-comments' =>
array(
- 'uri' => '/res/70c1f3a3/rsrc/js/application/differential/behavior-edit-inline-comments.js',
+ 'uri' => '/res/86f459a4/rsrc/js/application/differential/behavior-edit-inline-comments.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-util',
4 => 'javelin-vector',
5 => 'differential-inline-comment-editor',
),
'disk' => '/rsrc/js/application/differential/behavior-edit-inline-comments.js',
),
'javelin-behavior-differential-feedback-preview' =>
array(
- 'uri' => '/res/5fbce8db/rsrc/js/application/differential/behavior-comment-preview.js',
+ 'uri' => '/res/4421fac6/rsrc/js/application/differential/behavior-comment-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-request',
4 => 'javelin-util',
5 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/differential/behavior-comment-preview.js',
),
'javelin-behavior-differential-keyboard-navigation' =>
array(
- 'uri' => '/res/89e93cc9/rsrc/js/application/differential/behavior-keyboard-nav.js',
+ 'uri' => '/res/22ed93ba/rsrc/js/application/differential/behavior-keyboard-nav.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/application/differential/behavior-keyboard-nav.js',
),
'javelin-behavior-differential-populate' =>
array(
- 'uri' => '/res/526c2615/rsrc/js/application/differential/behavior-populate.js',
+ 'uri' => '/res/bb9a29f4/rsrc/js/application/differential/behavior-populate.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-workflow',
2 => 'javelin-util',
3 => 'javelin-dom',
4 => 'javelin-stratcom',
5 => 'javelin-behavior-device',
6 => 'javelin-vector',
7 => 'phabricator-tooltip',
),
'disk' => '/rsrc/js/application/differential/behavior-populate.js',
),
'javelin-behavior-differential-show-all-comments' =>
array(
- 'uri' => '/res/5a26be1a/rsrc/js/application/differential/behavior-show-all-comments.js',
+ 'uri' => '/res/8801848d/rsrc/js/application/differential/behavior-show-all-comments.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-show-all-comments.js',
),
'javelin-behavior-differential-show-field-details' =>
array(
'uri' => '/res/8d57f459/rsrc/js/application/differential/behavior-show-field-details.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/differential/behavior-show-field-details.js',
),
'javelin-behavior-differential-show-more' =>
array(
'uri' => '/res/b9f93090/rsrc/js/application/differential/behavior-show-more.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-workflow',
3 => 'javelin-util',
4 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/differential/behavior-show-more.js',
),
'javelin-behavior-differential-toggle-files' =>
array(
'uri' => '/res/ae937207/rsrc/js/application/differential/behavior-toggle-files.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/differential/behavior-toggle-files.js',
),
'javelin-behavior-differential-user-select' =>
array(
'uri' => '/res/23c51a5d/rsrc/js/application/differential/behavior-user-select.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/differential/behavior-user-select.js',
),
'javelin-behavior-diffusion-commit-branches' =>
array(
'uri' => '/res/1ede335a/rsrc/js/application/diffusion/behavior-commit-branches.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-request',
),
'disk' => '/rsrc/js/application/diffusion/behavior-commit-branches.js',
),
'javelin-behavior-diffusion-commit-graph' =>
array(
- 'uri' => '/res/62bd2035/rsrc/js/application/diffusion/behavior-commit-graph.js',
+ 'uri' => '/res/536b8483/rsrc/js/application/diffusion/behavior-commit-graph.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/diffusion/behavior-commit-graph.js',
),
'javelin-behavior-diffusion-jump-to' =>
array(
- 'uri' => '/res/7c42e1ba/rsrc/js/application/diffusion/behavior-jump-to.js',
+ 'uri' => '/res/bade44bd/rsrc/js/application/diffusion/behavior-jump-to.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
- 1 => 'javelin-util',
- 2 => 'javelin-vector',
- 3 => 'javelin-dom',
+ 1 => 'javelin-vector',
+ 2 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/diffusion/behavior-jump-to.js',
),
'javelin-behavior-diffusion-line-linker' =>
array(
'uri' => '/res/12866f13/rsrc/js/application/diffusion/behavior-line-linker.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-history',
),
'disk' => '/rsrc/js/application/diffusion/behavior-line-linker.js',
),
'javelin-behavior-diffusion-pull-lastmodified' =>
array(
'uri' => '/res/29fe2790/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-request',
),
'disk' => '/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
),
'javelin-behavior-error-log' =>
array(
'uri' => '/res/acefdea7/rsrc/js/core/behavior-error-log.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/behavior-error-log.js',
),
'javelin-behavior-fancy-datepicker' =>
array(
- 'uri' => '/res/9b67a0f4/rsrc/js/core/behavior-fancy-datepicker.js',
+ 'uri' => '/res/f5c13e07/rsrc/js/core/behavior-fancy-datepicker.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-stratcom',
4 => 'javelin-vector',
),
'disk' => '/rsrc/js/core/behavior-fancy-datepicker.js',
),
'javelin-behavior-global-drag-and-drop' =>
array(
- 'uri' => '/res/528e18ed/rsrc/js/core/behavior-global-drag-and-drop.js',
+ 'uri' => '/res/ee8e9c39/rsrc/js/core/behavior-global-drag-and-drop.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-uri',
3 => 'javelin-mask',
4 => 'phabricator-drag-and-drop-file-upload',
),
'disk' => '/rsrc/js/core/behavior-global-drag-and-drop.js',
),
'javelin-behavior-herald-rule-editor' =>
array(
'uri' => '/res/77a0c945/rsrc/js/application/herald/herald-rule-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'herald-rule-editor',
1 => 'javelin-behavior',
),
'disk' => '/rsrc/js/application/herald/herald-rule-editor.js',
),
'javelin-behavior-history-install' =>
array(
'uri' => '/res/9099a161/rsrc/js/core/behavior-history-install.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-history',
),
'disk' => '/rsrc/js/core/behavior-history-install.js',
),
'javelin-behavior-konami' =>
array(
'uri' => '/res/b7bb7c24/rsrc/js/core/behavior-konami.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/core/behavior-konami.js',
),
'javelin-behavior-lightbox-attachments' =>
array(
- 'uri' => '/res/f2b17609/rsrc/js/core/behavior-lightbox-attachments.js',
+ 'uri' => '/res/72b4d3a8/rsrc/js/core/behavior-lightbox-attachments.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-mask',
4 => 'javelin-util',
5 => 'phabricator-busy',
),
'disk' => '/rsrc/js/core/behavior-lightbox-attachments.js',
),
'javelin-behavior-line-chart' =>
array(
'uri' => '/res/1aa5ac88/rsrc/js/application/maniphest/behavior-line-chart.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-vector',
),
'disk' => '/rsrc/js/application/maniphest/behavior-line-chart.js',
),
'javelin-behavior-load-blame' =>
array(
'uri' => '/res/138e2961/rsrc/js/application/diffusion/behavior-load-blame.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-request',
),
'disk' => '/rsrc/js/application/diffusion/behavior-load-blame.js',
),
'javelin-behavior-maniphest-batch-editor' =>
array(
- 'uri' => '/res/00accaec/rsrc/js/application/maniphest/behavior-batch-editor.js',
+ 'uri' => '/res/81b2b86f/rsrc/js/application/maniphest/behavior-batch-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-prefab',
4 => 'multirow-row-manager',
5 => 'javelin-json',
),
'disk' => '/rsrc/js/application/maniphest/behavior-batch-editor.js',
),
'javelin-behavior-maniphest-batch-selector' =>
array(
- 'uri' => '/res/f8cf3b84/rsrc/js/application/maniphest/behavior-batch-selector.js',
+ 'uri' => '/res/c33cb5e3/rsrc/js/application/maniphest/behavior-batch-selector.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-util',
),
'disk' => '/rsrc/js/application/maniphest/behavior-batch-selector.js',
),
'javelin-behavior-maniphest-description-preview' =>
array(
- 'uri' => '/res/8acd6f07/rsrc/js/application/maniphest/behavior-task-preview.js',
+ 'uri' => '/res/58ba0ec2/rsrc/js/application/maniphest/behavior-task-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/maniphest/behavior-task-preview.js',
),
'javelin-behavior-maniphest-subpriority-editor' =>
array(
'uri' => '/res/21b73c2a/rsrc/js/application/maniphest/behavior-subpriorityeditor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-magical-init',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-stratcom',
5 => 'javelin-workflow',
),
'disk' => '/rsrc/js/application/maniphest/behavior-subpriorityeditor.js',
),
'javelin-behavior-maniphest-transaction-controls' =>
array(
- 'uri' => '/res/62465554/rsrc/js/application/maniphest/behavior-transaction-controls.js',
+ 'uri' => '/res/e8498688/rsrc/js/application/maniphest/behavior-transaction-controls.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/application/maniphest/behavior-transaction-controls.js',
),
'javelin-behavior-maniphest-transaction-expand' =>
array(
'uri' => '/res/966410de/rsrc/js/application/maniphest/behavior-transaction-expand.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-workflow',
3 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/application/maniphest/behavior-transaction-expand.js',
),
'javelin-behavior-maniphest-transaction-preview' =>
array(
- 'uri' => '/res/855c9f0c/rsrc/js/application/maniphest/behavior-transaction-preview.js',
+ 'uri' => '/res/9447a3f9/rsrc/js/application/maniphest/behavior-transaction-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-json',
4 => 'javelin-stratcom',
5 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/maniphest/behavior-transaction-preview.js',
),
'javelin-behavior-owners-path-editor' =>
array(
'uri' => '/res/9cf78ffc/rsrc/js/application/owners/owners-path-editor.js',
'type' => 'js',
'requires' =>
array(
0 => 'owners-path-editor',
1 => 'javelin-behavior',
),
'disk' => '/rsrc/js/application/owners/owners-path-editor.js',
),
'javelin-behavior-phabricator-active-nav' =>
array(
- 'uri' => '/res/326866c1/rsrc/js/core/behavior-active-nav.js',
+ 'uri' => '/res/9c8d3df8/rsrc/js/core/behavior-active-nav.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-vector',
3 => 'javelin-dom',
4 => 'javelin-uri',
),
'disk' => '/rsrc/js/core/behavior-active-nav.js',
),
'javelin-behavior-phabricator-autofocus' =>
array(
'uri' => '/res/bf92b8d6/rsrc/js/core/behavior-autofocus.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/behavior-autofocus.js',
),
'javelin-behavior-phabricator-file-tree' =>
array(
'uri' => '/res/e5bf93df/rsrc/js/core/behavior-file-tree.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'phabricator-keyboard-shortcut',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/core/behavior-file-tree.js',
),
'javelin-behavior-phabricator-gesture' =>
array(
'uri' => '/res/16e1e77c/rsrc/js/core/behavior-gesture.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'javelin-vector',
4 => 'javelin-dom',
5 => 'javelin-magical-init',
),
'disk' => '/rsrc/js/core/behavior-gesture.js',
),
'javelin-behavior-phabricator-gesture-example' =>
array(
- 'uri' => '/res/da636e19/rsrc/js/application/uiexample/gesture-example.js',
+ 'uri' => '/res/91d1e7f2/rsrc/js/application/uiexample/gesture-example.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-behavior',
2 => 'javelin-vector',
3 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/uiexample/gesture-example.js',
),
'javelin-behavior-phabricator-hovercards' =>
array(
- 'uri' => '/res/ed56d3c4/rsrc/js/core/behavior-hovercard.js',
+ 'uri' => '/res/4fe6b436/rsrc/js/core/behavior-hovercard.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'javelin-vector',
4 => 'phabricator-hovercard',
),
'disk' => '/rsrc/js/core/behavior-hovercard.js',
),
'javelin-behavior-phabricator-keyboard-pager' =>
array(
'uri' => '/res/6a5445b8/rsrc/js/core/behavior-keyboard-pager.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-uri',
2 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/core/behavior-keyboard-pager.js',
),
'javelin-behavior-phabricator-keyboard-shortcuts' =>
array(
'uri' => '/res/b971e713/rsrc/js/core/behavior-keyboard-shortcuts.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-workflow',
2 => 'javelin-json',
3 => 'javelin-dom',
4 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/core/behavior-keyboard-shortcuts.js',
),
'javelin-behavior-phabricator-nav' =>
array(
- 'uri' => '/res/ede26aac/rsrc/js/core/behavior-phabricator-nav.js',
+ 'uri' => '/res/afabcf16/rsrc/js/core/behavior-phabricator-nav.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-magical-init',
5 => 'javelin-vector',
+ 6 => 'javelin-request',
+ 7 => 'javelin-util',
),
'disk' => '/rsrc/js/core/behavior-phabricator-nav.js',
),
'javelin-behavior-phabricator-notification-example' =>
array(
- 'uri' => '/res/a6d51998/rsrc/js/application/uiexample/notification-example.js',
+ 'uri' => '/res/7c50cefd/rsrc/js/application/uiexample/notification-example.js',
'type' => 'js',
'requires' =>
array(
0 => 'phabricator-notification',
1 => 'javelin-stratcom',
2 => 'javelin-behavior',
- 3 => 'javelin-uri',
),
'disk' => '/rsrc/js/application/uiexample/notification-example.js',
),
'javelin-behavior-phabricator-object-selector' =>
array(
- 'uri' => '/res/31145104/rsrc/js/core/behavior-object-selector.js',
+ 'uri' => '/res/461f95f7/rsrc/js/core/behavior-object-selector.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-request',
3 => 'javelin-util',
),
'disk' => '/rsrc/js/core/behavior-object-selector.js',
),
'javelin-behavior-phabricator-oncopy' =>
array(
- 'uri' => '/res/c5839892/rsrc/js/core/behavior-oncopy.js',
+ 'uri' => '/res/cd3a9345/rsrc/js/core/behavior-oncopy.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/behavior-oncopy.js',
),
'javelin-behavior-phabricator-remarkup-assist' =>
array(
- 'uri' => '/res/ddfb4eba/rsrc/js/core/behavior-phabricator-remarkup-assist.js',
+ 'uri' => '/res/6d9c05d9/rsrc/js/core/behavior-phabricator-remarkup-assist.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'phabricator-textareautils',
4 => 'javelin-workflow',
5 => 'phabricator-notification',
6 => 'javelin-vector',
),
'disk' => '/rsrc/js/core/behavior-phabricator-remarkup-assist.js',
),
'javelin-behavior-phabricator-reveal-content' =>
array(
- 'uri' => '/res/5f9da91f/rsrc/js/core/behavior-reveal-content.js',
+ 'uri' => '/res/fef525ef/rsrc/js/core/behavior-reveal-content.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/behavior-reveal-content.js',
),
'javelin-behavior-phabricator-search-typeahead' =>
array(
- 'uri' => '/res/2662f34f/rsrc/js/core/behavior-search-typeahead.js',
+ 'uri' => '/res/b39896d5/rsrc/js/core/behavior-search-typeahead.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-typeahead-ondemand-source',
2 => 'javelin-typeahead',
3 => 'javelin-dom',
4 => 'javelin-uri',
5 => 'javelin-util',
6 => 'javelin-stratcom',
),
'disk' => '/rsrc/js/core/behavior-search-typeahead.js',
),
'javelin-behavior-phabricator-tooltips' =>
array(
'uri' => '/res/a0ac5320/rsrc/js/core/behavior-tooltip.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-behavior-device',
2 => 'javelin-stratcom',
3 => 'phabricator-tooltip',
),
'disk' => '/rsrc/js/core/behavior-tooltip.js',
),
'javelin-behavior-phabricator-transaction-comment-form' =>
array(
- 'uri' => '/res/acc3ada1/rsrc/js/application/transactions/behavior-transaction-comment-form.js',
+ 'uri' => '/res/7591a57f/rsrc/js/application/transactions/behavior-transaction-comment-form.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/transactions/behavior-transaction-comment-form.js',
),
'javelin-behavior-phabricator-transaction-list' =>
array(
'uri' => '/res/f1fbb474/rsrc/js/application/transactions/behavior-transaction-list.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-workflow',
3 => 'javelin-dom',
4 => 'javelin-fx',
),
'disk' => '/rsrc/js/application/transactions/behavior-transaction-list.js',
),
'javelin-behavior-phabricator-watch-anchor' =>
array(
'uri' => '/res/69a90817/rsrc/js/core/behavior-watch-anchor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-vector',
),
'disk' => '/rsrc/js/core/behavior-watch-anchor.js',
),
'javelin-behavior-phame-post-preview' =>
array(
- 'uri' => '/res/ac4c503a/rsrc/js/application/phame/phame-post-preview.js',
+ 'uri' => '/res/181d1cbe/rsrc/js/application/phame/phame-post-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/phame/phame-post-preview.js',
),
'javelin-behavior-pholio-mock-view' =>
array(
- 'uri' => '/res/ecf5f969/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
+ 'uri' => '/res/0632e7d9/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-vector',
5 => 'javelin-magical-init',
6 => 'javelin-request',
7 => 'javelin-history',
8 => 'javelin-workflow',
9 => 'javelin-mask',
10 => 'javelin-behavior-device',
11 => 'phabricator-keyboard-shortcut',
),
'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
),
'javelin-behavior-phriction-document-preview' =>
array(
- 'uri' => '/res/f1665ecd/rsrc/js/application/phriction/phriction-document-preview.js',
+ 'uri' => '/res/e2fe02de/rsrc/js/application/phriction/phriction-document-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/phriction/phriction-document-preview.js',
),
'javelin-behavior-ponder-feedback-preview' =>
array(
'uri' => '/res/2e802dd9/rsrc/js/application/ponder/behavior-comment-preview.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'phabricator-shaped-request',
),
'disk' => '/rsrc/js/application/ponder/behavior-comment-preview.js',
),
'javelin-behavior-ponder-votebox' =>
array(
- 'uri' => '/res/9d091af3/rsrc/js/application/ponder/behavior-votebox.js',
+ 'uri' => '/res/d8c973a2/rsrc/js/application/ponder/behavior-votebox.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-util',
3 => 'javelin-stratcom',
4 => 'javelin-request',
),
'disk' => '/rsrc/js/application/ponder/behavior-votebox.js',
),
'javelin-behavior-project-create' =>
array(
'uri' => '/res/e91f3f8f/rsrc/js/application/projects/behavior-project-create.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-workflow',
),
'disk' => '/rsrc/js/application/projects/behavior-project-create.js',
),
'javelin-behavior-refresh-csrf' =>
array(
- 'uri' => '/res/424ccc57/rsrc/js/core/behavior-refresh-csrf.js',
+ 'uri' => '/res/6c54100f/rsrc/js/core/behavior-refresh-csrf.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-request',
1 => 'javelin-behavior',
2 => 'javelin-dom',
3 => 'phabricator-busy',
),
'disk' => '/rsrc/js/core/behavior-refresh-csrf.js',
),
'javelin-behavior-releeph-preview-branch' =>
array(
- 'uri' => '/res/a77ebc86/rsrc/js/application/releeph/releeph-preview-branch.js',
+ 'uri' => '/res/f694854d/rsrc/js/application/releeph/releeph-preview-branch.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
- 2 => 'javelin-stratcom',
- 3 => 'javelin-uri',
- 4 => 'javelin-util',
+ 2 => 'javelin-uri',
+ 3 => 'javelin-request',
),
'disk' => '/rsrc/js/application/releeph/releeph-preview-branch.js',
),
'javelin-behavior-releeph-request-state-change' =>
array(
- 'uri' => '/res/38f96ba8/rsrc/js/application/releeph/releeph-request-state-change.js',
+ 'uri' => '/res/07ecde0c/rsrc/js/application/releeph/releeph-request-state-change.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
- 3 => 'javelin-util',
+ 3 => 'javelin-request',
4 => 'phabricator-keyboard-shortcut',
5 => 'phabricator-notification',
),
'disk' => '/rsrc/js/application/releeph/releeph-request-state-change.js',
),
'javelin-behavior-releeph-request-typeahead' =>
array(
- 'uri' => '/res/b52096e2/rsrc/js/application/releeph/releeph-request-typeahead.js',
+ 'uri' => '/res/2c2350a0/rsrc/js/application/releeph/releeph-request-typeahead.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
- 1 => 'javelin-util',
- 2 => 'javelin-dom',
- 3 => 'javelin-typeahead',
- 4 => 'javelin-tokenizer',
- 5 => 'javelin-typeahead-preloaded-source',
- 6 => 'javelin-typeahead-ondemand-source',
- 7 => 'javelin-dom',
- 8 => 'javelin-stratcom',
- 9 => 'javelin-util',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-typeahead',
+ 3 => 'javelin-typeahead-ondemand-source',
+ 4 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/releeph/releeph-request-typeahead.js',
),
'javelin-behavior-repository-crossreference' =>
array(
'uri' => '/res/d3f9d50b/rsrc/js/application/repository/repository-crossreference.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-uri',
),
'disk' => '/rsrc/js/application/repository/repository-crossreference.js',
),
'javelin-behavior-slowvote-embed' =>
array(
- 'uri' => '/res/eef0818f/rsrc/js/application/slowvote/behavior-slowvote-embed.js',
+ 'uri' => '/res/8e85e20d/rsrc/js/application/slowvote/behavior-slowvote-embed.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
- 1 => 'javelin-util',
+ 1 => 'javelin-request',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/slowvote/behavior-slowvote-embed.js',
),
'javelin-behavior-stripe-payment-form' =>
array(
'uri' => '/res/c1a12d77/rsrc/js/application/phortune/behavior-stripe-payment-form.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phortune-credit-card-form',
),
'disk' => '/rsrc/js/application/phortune/behavior-stripe-payment-form.js',
),
'javelin-behavior-test-payment-form' =>
array(
'uri' => '/res/a8fe8616/rsrc/js/application/phortune/behavior-test-payment-form.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'phortune-credit-card-form',
),
'disk' => '/rsrc/js/application/phortune/behavior-test-payment-form.js',
),
'javelin-behavior-toggle-class' =>
array(
'uri' => '/res/79921b7f/rsrc/js/core/behavior-toggle-class.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/behavior-toggle-class.js',
),
'javelin-behavior-view-placeholder' =>
array(
- 'uri' => '/res/faaf0af7/rsrc/externals/javelin/ext/view/ViewPlaceholder.js',
+ 'uri' => '/res/6abdb85b/rsrc/externals/javelin/ext/view/ViewPlaceholder.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
2 => 'javelin-view-renderer',
+ 3 => 'javelin-install',
),
'disk' => '/rsrc/externals/javelin/ext/view/ViewPlaceholder.js',
),
'javelin-behavior-workflow' =>
array(
'uri' => '/res/425777cc/rsrc/js/core/behavior-workflow.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-stratcom',
2 => 'javelin-workflow',
3 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/behavior-workflow.js',
),
'javelin-color' =>
array(
'uri' => '/res/f17034de/rsrc/externals/javelin/ext/fx/Color.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/externals/javelin/ext/fx/Color.js',
),
'javelin-cookie' =>
array(
'uri' => '/res/ee0d399f/rsrc/externals/javelin/lib/Cookie.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/lib/Cookie.js',
),
'javelin-dom' =>
array(
- 'uri' => '/res/64689b54/rsrc/externals/javelin/lib/DOM.js',
+ 'uri' => '/res/175211d6/rsrc/externals/javelin/lib/DOM.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-magical-init',
1 => 'javelin-install',
2 => 'javelin-util',
3 => 'javelin-vector',
4 => 'javelin-stratcom',
),
'disk' => '/rsrc/externals/javelin/lib/DOM.js',
),
'javelin-dynval' =>
array(
'uri' => '/res/ea6f2a9d/rsrc/externals/javelin/ext/reactor/core/DynVal.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactornode',
2 => 'javelin-util',
3 => 'javelin-reactor',
),
'disk' => '/rsrc/externals/javelin/ext/reactor/core/DynVal.js',
),
'javelin-event' =>
array(
- 'uri' => '/res/0a4efce8/rsrc/externals/javelin/core/Event.js',
+ 'uri' => '/res/5f70f4d0/rsrc/externals/javelin/core/Event.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/externals/javelin/core/Event.js',
),
'javelin-fx' =>
array(
'uri' => '/res/c7cefec3/rsrc/externals/javelin/ext/fx/FX.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-color',
1 => 'javelin-install',
2 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/ext/fx/FX.js',
),
'javelin-history' =>
array(
'uri' => '/res/6c084b09/rsrc/externals/javelin/lib/History.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-install',
2 => 'javelin-uri',
3 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/lib/History.js',
),
'javelin-install' =>
array(
'uri' => '/res/904356c0/rsrc/externals/javelin/core/install.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-util',
1 => 'javelin-magical-init',
),
'disk' => '/rsrc/externals/javelin/core/install.js',
),
'javelin-json' =>
array(
'uri' => '/res/cf83e72c/rsrc/externals/javelin/lib/JSON.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/externals/javelin/lib/JSON.js',
),
'javelin-magical-init' =>
array(
- 'uri' => '/res/7af6987f/rsrc/externals/javelin/core/init.js',
+ 'uri' => '/res/7c6c8d5a/rsrc/externals/javelin/core/init.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/externals/javelin/core/init.js',
),
'javelin-mask' =>
array(
- 'uri' => '/res/5c40c29f/rsrc/externals/javelin/lib/Mask.js',
+ 'uri' => '/res/465cf513/rsrc/externals/javelin/lib/Mask.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
),
'disk' => '/rsrc/externals/javelin/lib/Mask.js',
),
'javelin-reactor' =>
array(
'uri' => '/res/c05f2658/rsrc/externals/javelin/ext/reactor/core/Reactor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/ext/reactor/core/Reactor.js',
),
'javelin-reactor-dom' =>
array(
- 'uri' => '/res/477f5d3b/rsrc/externals/javelin/ext/reactor/dom/RDOM.js',
+ 'uri' => '/res/5e03117e/rsrc/externals/javelin/ext/reactor/dom/RDOM.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-dom',
1 => 'javelin-dynval',
- 2 => 'javelin-reactornode',
- 3 => 'javelin-install',
- 4 => 'javelin-util',
+ 2 => 'javelin-reactor',
+ 3 => 'javelin-reactornode',
+ 4 => 'javelin-install',
+ 5 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/ext/reactor/dom/RDOM.js',
),
'javelin-reactor-node-calmer' =>
array(
'uri' => '/res/a93dd6b6/rsrc/externals/javelin/ext/reactor/core/ReactorNodeCalmer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactor',
2 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/ext/reactor/core/ReactorNodeCalmer.js',
),
'javelin-reactornode' =>
array(
'uri' => '/res/4eac475b/rsrc/externals/javelin/ext/reactor/core/ReactorNode.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-reactor',
2 => 'javelin-util',
3 => 'javelin-reactor-node-calmer',
),
'disk' => '/rsrc/externals/javelin/ext/reactor/core/ReactorNode.js',
),
'javelin-request' =>
array(
- 'uri' => '/res/a9fbc4ae/rsrc/externals/javelin/lib/Request.js',
+ 'uri' => '/res/687bdcfc/rsrc/externals/javelin/lib/Request.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-stratcom',
2 => 'javelin-util',
3 => 'javelin-behavior',
4 => 'javelin-json',
5 => 'javelin-dom',
6 => 'javelin-resource',
),
'disk' => '/rsrc/externals/javelin/lib/Request.js',
),
'javelin-resource' =>
array(
- 'uri' => '/res/1020e732/rsrc/externals/javelin/lib/Resource.js',
+ 'uri' => '/res/33a3bb57/rsrc/externals/javelin/lib/Resource.js',
'type' => 'js',
'requires' =>
array(
- 0 => 'javelin-magical-init',
- 1 => 'javelin-stratcom',
- 2 => 'javelin-util',
- 3 => 'javelin-uri',
+ 0 => 'javelin-util',
+ 1 => 'javelin-uri',
+ 2 => 'javelin-install',
),
'disk' => '/rsrc/externals/javelin/lib/Resource.js',
),
'javelin-stratcom' =>
array(
'uri' => '/res/714946e7/rsrc/externals/javelin/core/Stratcom.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-event',
2 => 'javelin-util',
3 => 'javelin-magical-init',
),
'disk' => '/rsrc/externals/javelin/core/Stratcom.js',
),
'javelin-tokenizer' =>
array(
- 'uri' => '/res/2c55cb68/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js',
+ 'uri' => '/res/7c117141/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-dom',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-install',
),
'disk' => '/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js',
),
'javelin-typeahead' =>
array(
'uri' => '/res/fd79f758/rsrc/externals/javelin/lib/control/typeahead/Typeahead.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-vector',
3 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/lib/control/typeahead/Typeahead.js',
),
'javelin-typeahead-composite-source' =>
array(
'uri' => '/res/487b3da2/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
2 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js',
),
'javelin-typeahead-normalizer' =>
array(
'uri' => '/res/5a4bd979/rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/externals/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js',
),
'javelin-typeahead-ondemand-source' =>
array(
- 'uri' => '/res/9ab98c3d/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js',
+ 'uri' => '/res/4e5add88/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
- 2 => 'javelin-stratcom',
- 3 => 'javelin-request',
- 4 => 'javelin-typeahead-source',
+ 2 => 'javelin-request',
+ 3 => 'javelin-typeahead-source',
),
'disk' => '/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js',
),
'javelin-typeahead-preloaded-source' =>
array(
- 'uri' => '/res/ffc234d1/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js',
+ 'uri' => '/res/147900c7/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
- 2 => 'javelin-stratcom',
- 3 => 'javelin-request',
- 4 => 'javelin-typeahead-source',
+ 2 => 'javelin-request',
+ 3 => 'javelin-typeahead-source',
),
'disk' => '/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js',
),
'javelin-typeahead-source' =>
array(
- 'uri' => '/res/df206a51/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js',
+ 'uri' => '/res/13289259/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-typeahead-normalizer',
),
'disk' => '/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js',
),
'javelin-typeahead-static-source' =>
array(
'uri' => '/res/bb0a5173/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead-source',
),
'disk' => '/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js',
),
'javelin-uri' =>
array(
- 'uri' => '/res/a1e5cbb3/rsrc/externals/javelin/lib/URI.js',
+ 'uri' => '/res/75aa4597/rsrc/externals/javelin/lib/URI.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
),
'disk' => '/rsrc/externals/javelin/lib/URI.js',
),
'javelin-util' =>
array(
- 'uri' => '/res/322fc289/rsrc/externals/javelin/core/util.js',
+ 'uri' => '/res/90222113/rsrc/externals/javelin/core/util.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/externals/javelin/core/util.js',
),
'javelin-vector' =>
array(
- 'uri' => '/res/c8c64ab7/rsrc/externals/javelin/lib/Vector.js',
+ 'uri' => '/res/58ea3dd7/rsrc/externals/javelin/lib/Vector.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-event',
),
'disk' => '/rsrc/externals/javelin/lib/Vector.js',
),
'javelin-view' =>
array(
- 'uri' => '/res/3022e596/rsrc/externals/javelin/ext/view/View.js',
+ 'uri' => '/res/38daaec0/rsrc/externals/javelin/ext/view/View.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/ext/view/View.js',
),
'javelin-view-html' =>
array(
- 'uri' => '/res/1b6e621c/rsrc/externals/javelin/ext/view/HTMLView.js',
+ 'uri' => '/res/0d225e8c/rsrc/externals/javelin/ext/view/HTMLView.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-view-visitor',
+ 3 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/ext/view/HTMLView.js',
),
'javelin-view-interpreter' =>
array(
- 'uri' => '/res/39fe3ad3/rsrc/externals/javelin/ext/view/ViewInterpreter.js',
+ 'uri' => '/res/b0c07f96/rsrc/externals/javelin/ext/view/ViewInterpreter.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-view',
1 => 'javelin-install',
+ 2 => 'javelin-dom',
),
'disk' => '/rsrc/externals/javelin/ext/view/ViewInterpreter.js',
),
'javelin-view-renderer' =>
array(
- 'uri' => '/res/d2119b79/rsrc/externals/javelin/ext/view/ViewRenderer.js',
+ 'uri' => '/res/fe0d2f60/rsrc/externals/javelin/ext/view/ViewRenderer.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
+ 1 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/ext/view/ViewRenderer.js',
),
'javelin-view-visitor' =>
array(
'uri' => '/res/b1606cec/rsrc/externals/javelin/ext/view/ViewVisitor.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
),
'disk' => '/rsrc/externals/javelin/ext/view/ViewVisitor.js',
),
'javelin-workflow' =>
array(
- 'uri' => '/res/73e8d0e2/rsrc/externals/javelin/lib/Workflow.js',
+ 'uri' => '/res/8274d65f/rsrc/externals/javelin/lib/Workflow.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-stratcom',
1 => 'javelin-request',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-install',
5 => 'javelin-util',
6 => 'javelin-mask',
7 => 'javelin-uri',
),
'disk' => '/rsrc/externals/javelin/lib/Workflow.js',
),
'lightbox-attachment-css' =>
array(
'uri' => '/res/4657e15d/rsrc/css/aphront/lightbox-attachment.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/lightbox-attachment.css',
),
'maniphest-batch-editor' =>
array(
'uri' => '/res/fb15d744/rsrc/css/application/maniphest/batch-editor.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/batch-editor.css',
),
'maniphest-report-css' =>
array(
'uri' => '/res/2e633fcf/rsrc/css/application/maniphest/report.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/report.css',
),
'maniphest-task-edit-css' =>
array(
'uri' => '/res/0760f768/rsrc/css/application/maniphest/task-edit.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/task-edit.css',
),
'maniphest-task-summary-css' =>
array(
'uri' => '/res/7aa9e2eb/rsrc/css/application/maniphest/task-summary.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/task-summary.css',
),
'maniphest-transaction-detail-css' =>
array(
'uri' => '/res/fb430d3e/rsrc/css/application/maniphest/transaction-detail.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/maniphest/transaction-detail.css',
),
'multirow-row-manager' =>
array(
'uri' => '/res/408fae4f/rsrc/js/core/MultirowRowManager.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-stratcom',
2 => 'javelin-dom',
3 => 'javelin-util',
),
'disk' => '/rsrc/js/core/MultirowRowManager.js',
),
'owners-path-editor' =>
array(
'uri' => '/res/29b68354/rsrc/js/application/owners/OwnersPathEditor.js',
'type' => 'js',
'requires' =>
array(
0 => 'multirow-row-manager',
1 => 'javelin-install',
2 => 'path-typeahead',
3 => 'javelin-dom',
4 => 'javelin-util',
5 => 'phabricator-prefab',
),
'disk' => '/rsrc/js/application/owners/OwnersPathEditor.js',
),
'owners-path-editor-css' =>
array(
'uri' => '/res/1b9b5456/rsrc/css/application/owners/owners-path-editor.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/owners/owners-path-editor.css',
),
'paste-css' =>
array(
'uri' => '/res/216fbfe9/rsrc/css/application/paste/paste.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/paste/paste.css',
),
'path-typeahead' =>
array(
'uri' => '/res/50246fb6/rsrc/js/application/herald/PathTypeahead.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-typeahead',
2 => 'javelin-dom',
3 => 'javelin-request',
4 => 'javelin-typeahead-ondemand-source',
5 => 'javelin-util',
),
'disk' => '/rsrc/js/application/herald/PathTypeahead.js',
),
'phabricator-action-header-view-css' =>
array(
'uri' => '/res/3b701648/rsrc/css/layout/phabricator-action-header-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-action-header-view.css',
),
'phabricator-action-list-view-css' =>
array(
'uri' => '/res/f63afae7/rsrc/css/layout/phabricator-action-list-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-action-list-view.css',
),
'phabricator-application-launch-view-css' =>
array(
'uri' => '/res/dffb18f3/rsrc/css/application/base/phabricator-application-launch-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/base/phabricator-application-launch-view.css',
),
'phabricator-busy' =>
array(
'uri' => '/res/8e3f036d/rsrc/js/core/Busy.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/Busy.js',
),
'phabricator-chatlog-css' =>
array(
'uri' => '/res/5542e247/rsrc/css/application/chatlog/chatlog.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/chatlog/chatlog.css',
),
'phabricator-content-source-view-css' =>
array(
'uri' => '/res/8c738a93/rsrc/css/application/contentsource/content-source-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/contentsource/content-source-view.css',
),
'phabricator-core-buttons-css' =>
array(
'uri' => '/res/da2e42df/rsrc/css/core/buttons.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/buttons.css',
),
'phabricator-core-css' =>
array(
'uri' => '/res/dc204369/rsrc/css/core/core.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/core.css',
),
'phabricator-countdown-css' =>
array(
'uri' => '/res/0f646281/rsrc/css/application/countdown/timer.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/countdown/timer.css',
),
'phabricator-crumbs-view-css' =>
array(
'uri' => '/res/feeb02f0/rsrc/css/layout/phabricator-crumbs-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-crumbs-view.css',
),
'phabricator-directory-css' =>
array(
'uri' => '/res/61afca2b/rsrc/css/application/directory/phabricator-directory.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/directory/phabricator-directory.css',
),
'phabricator-drag-and-drop-file-upload' =>
array(
- 'uri' => '/res/3991c1b6/rsrc/js/core/DragAndDropFileUpload.js',
+ 'uri' => '/res/396d3b3b/rsrc/js/core/DragAndDropFileUpload.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
3 => 'javelin-dom',
4 => 'javelin-uri',
5 => 'phabricator-file-upload',
),
'disk' => '/rsrc/js/core/DragAndDropFileUpload.js',
),
'phabricator-dropdown-menu' =>
array(
'uri' => '/res/efe00353/rsrc/js/core/DropdownMenu.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-vector',
4 => 'javelin-stratcom',
5 => 'phabricator-menu-item',
),
'disk' => '/rsrc/js/core/DropdownMenu.js',
),
'phabricator-fatal-config-template-css' =>
array(
'uri' => '/res/6e1a8d22/rsrc/css/application/config/config-template.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/config/config-template.css',
),
'phabricator-feed-css' =>
array(
'uri' => '/res/e19633ed/rsrc/css/application/feed/feed.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/feed/feed.css',
),
'phabricator-file-upload' =>
array(
- 'uri' => '/res/ee9664fd/rsrc/js/core/FileUpload.js',
+ 'uri' => '/res/c9605008/rsrc/js/core/FileUpload.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'phabricator-notification',
),
'disk' => '/rsrc/js/core/FileUpload.js',
),
'phabricator-filetree-view-css' =>
array(
'uri' => '/res/c912ed91/rsrc/css/layout/phabricator-filetree-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-filetree-view.css',
),
'phabricator-flag-css' =>
array(
'uri' => '/res/237234d7/rsrc/css/application/flag/flag.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/flag/flag.css',
),
'phabricator-form-view-css' =>
array(
'uri' => '/res/ba05f8ba/rsrc/css/layout/phabricator-form-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-form-view.css',
),
'phabricator-header-view-css' =>
array(
'uri' => '/res/585b771c/rsrc/css/layout/phabricator-header-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-header-view.css',
),
'phabricator-hovercard' =>
array(
- 'uri' => '/res/2cf2c195/rsrc/js/core/Hovercard.js',
+ 'uri' => '/res/7fb94260/rsrc/js/core/Hovercard.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-vector',
3 => 'javelin-request',
4 => 'javelin-uri',
),
'disk' => '/rsrc/js/core/Hovercard.js',
),
'phabricator-hovercard-view-css' =>
array(
'uri' => '/res/80683f88/rsrc/css/layout/phabricator-hovercard-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-hovercard-view.css',
),
'phabricator-jump-nav' =>
array(
'uri' => '/res/37ab43b8/rsrc/css/application/directory/phabricator-jump-nav.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/directory/phabricator-jump-nav.css',
),
'phabricator-keyboard-shortcut' =>
array(
'uri' => '/res/44747afd/rsrc/js/core/KeyboardShortcut.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'phabricator-keyboard-shortcut-manager',
),
'disk' => '/rsrc/js/core/KeyboardShortcut.js',
),
'phabricator-keyboard-shortcut-manager' =>
array(
'uri' => '/res/bf9bc02a/rsrc/js/core/KeyboardShortcutManager.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-stratcom',
3 => 'javelin-dom',
4 => 'javelin-vector',
),
'disk' => '/rsrc/js/core/KeyboardShortcutManager.js',
),
'phabricator-main-menu-view' =>
array(
'uri' => '/res/50479234/rsrc/css/application/base/main-menu-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/base/main-menu-view.css',
),
'phabricator-menu-item' =>
array(
'uri' => '/res/2add4594/rsrc/js/core/DropdownMenuItem.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
),
'disk' => '/rsrc/js/core/DropdownMenuItem.js',
),
'phabricator-nav-view-css' =>
array(
'uri' => '/res/37955b6a/rsrc/css/aphront/phabricator-nav-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/phabricator-nav-view.css',
),
'phabricator-notification' =>
array(
'uri' => '/res/0764da14/rsrc/js/core/Notification.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-stratcom',
3 => 'javelin-util',
4 => 'phabricator-notification-css',
),
'disk' => '/rsrc/js/core/Notification.js',
),
'phabricator-notification-css' =>
array(
'uri' => '/res/664b9bec/rsrc/css/aphront/notification.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/notification.css',
),
'phabricator-notification-menu-css' =>
array(
'uri' => '/res/bc245b67/rsrc/css/application/base/notification-menu.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/base/notification-menu.css',
),
'phabricator-object-item-list-view-css' =>
array(
'uri' => '/res/96dce9f3/rsrc/css/layout/phabricator-object-item-list-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-object-item-list-view.css',
),
'phabricator-object-list-view-css' =>
array(
'uri' => '/res/4f183668/rsrc/css/application/projects/phabricator-object-list-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/projects/phabricator-object-list-view.css',
),
'phabricator-object-selector-css' =>
array(
'uri' => '/res/502f1bb9/rsrc/css/application/objectselector/object-selector.css',
'type' => 'css',
'requires' =>
array(
0 => 'aphront-dialog-view-css',
),
'disk' => '/rsrc/css/application/objectselector/object-selector.css',
),
'phabricator-phtize' =>
array(
- 'uri' => '/res/50a80ff1/rsrc/js/core/phtize.js',
+ 'uri' => '/res/dc655a81/rsrc/js/core/phtize.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-util',
),
'disk' => '/rsrc/js/core/phtize.js',
),
'phabricator-pinboard-view-css' =>
array(
'uri' => '/res/61ecd7cf/rsrc/css/layout/phabricator-pinboard-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-pinboard-view.css',
),
'phabricator-prefab' =>
array(
- 'uri' => '/res/513c4313/rsrc/js/core/Prefab.js',
+ 'uri' => '/res/511859ca/rsrc/js/core/Prefab.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-typeahead',
4 => 'javelin-tokenizer',
5 => 'javelin-typeahead-preloaded-source',
6 => 'javelin-typeahead-ondemand-source',
7 => 'javelin-dom',
8 => 'javelin-stratcom',
9 => 'javelin-util',
),
'disk' => '/rsrc/js/core/Prefab.js',
),
'phabricator-profile-css' =>
array(
'uri' => '/res/87229261/rsrc/css/application/profile/profile-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/profile/profile-view.css',
),
'phabricator-profile-header-css' =>
array(
'uri' => '/res/a03c1e20/rsrc/css/application/profile/profile-header-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/profile/profile-header-view.css',
),
'phabricator-project-tag-css' =>
array(
'uri' => '/res/1b5efcb2/rsrc/css/application/projects/project-tag.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/projects/project-tag.css',
),
'phabricator-property-list-view-css' =>
array(
'uri' => '/res/a04cc81d/rsrc/css/layout/phabricator-property-list-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-property-list-view.css',
),
'phabricator-remarkup-css' =>
array(
'uri' => '/res/07cab525/rsrc/css/core/remarkup.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/remarkup.css',
),
'phabricator-search-results-css' =>
array(
'uri' => '/res/9b749d7d/rsrc/css/application/search/search-results.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/search/search-results.css',
),
'phabricator-settings-css' =>
array(
'uri' => '/res/fb9d017f/rsrc/css/application/settings/settings.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/settings/settings.css',
),
'phabricator-shaped-request' =>
array(
'uri' => '/res/d173af85/rsrc/js/core/ShapedRequest.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-request',
),
'disk' => '/rsrc/js/core/ShapedRequest.js',
),
'phabricator-side-menu-view-css' =>
array(
'uri' => '/res/2a1ac469/rsrc/css/layout/phabricator-side-menu-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-side-menu-view.css',
),
'phabricator-slowvote-css' =>
array(
'uri' => '/res/d1c2e05a/rsrc/css/application/slowvote/slowvote.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/slowvote/slowvote.css',
),
'phabricator-source-code-view-css' =>
array(
'uri' => '/res/979d5280/rsrc/css/layout/phabricator-source-code-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-source-code-view.css',
),
'phabricator-standard-page-view' =>
array(
'uri' => '/res/70fa2da4/rsrc/css/application/base/standard-page-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/base/standard-page-view.css',
),
'phabricator-tag-view-css' =>
array(
'uri' => '/res/e10bf844/rsrc/css/layout/phabricator-tag-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-tag-view.css',
),
'phabricator-textareautils' =>
array(
'uri' => '/res/03c03e8b/rsrc/js/core/TextAreaUtils.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
),
'disk' => '/rsrc/js/core/TextAreaUtils.js',
),
'phabricator-timeline-view-css' =>
array(
'uri' => '/res/5517bf1a/rsrc/css/layout/phabricator-timeline-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-timeline-view.css',
),
'phabricator-tooltip' =>
array(
- 'uri' => '/res/1dc73d91/rsrc/js/core/ToolTip.js',
+ 'uri' => '/res/a23bc887/rsrc/js/core/ToolTip.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-util',
2 => 'javelin-dom',
3 => 'javelin-vector',
),
'disk' => '/rsrc/js/core/ToolTip.js',
),
'phabricator-transaction-view-css' =>
array(
'uri' => '/res/00be4b1a/rsrc/css/aphront/transaction.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/aphront/transaction.css',
),
'phabricator-ui-example-css' =>
array(
'uri' => '/res/376ab671/rsrc/css/application/uiexample/example.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/uiexample/example.css',
),
'phabricator-uiexample-javelin-view' =>
array(
- 'uri' => '/res/a2ce2cfc/rsrc/js/application/uiexample/JavelinViewExample.js',
+ 'uri' => '/res/2da87384/rsrc/js/application/uiexample/JavelinViewExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
- 2 => 'javelin-util',
- 3 => 'javelin-dom',
+ 1 => 'javelin-dom',
),
'disk' => '/rsrc/js/application/uiexample/JavelinViewExample.js',
),
'phabricator-uiexample-reactor-button' =>
array(
- 'uri' => '/res/142127f6/rsrc/js/application/uiexample/ReactorButtonExample.js',
+ 'uri' => '/res/6bfe4f05/rsrc/js/application/uiexample/ReactorButtonExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
+ 1 => 'javelin-dom',
2 => 'javelin-util',
- 3 => 'javelin-dom',
+ 3 => 'javelin-dynval',
4 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorButtonExample.js',
),
'phabricator-uiexample-reactor-checkbox' =>
array(
- 'uri' => '/res/c75cb9e9/rsrc/js/application/uiexample/ReactorCheckboxExample.js',
+ 'uri' => '/res/3e8b30ac/rsrc/js/application/uiexample/ReactorCheckboxExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
- 2 => 'javelin-util',
- 3 => 'javelin-dom',
- 4 => 'javelin-reactor-dom',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorCheckboxExample.js',
),
'phabricator-uiexample-reactor-focus' =>
array(
- 'uri' => '/res/3cc992eb/rsrc/js/application/uiexample/ReactorFocusExample.js',
+ 'uri' => '/res/d8f3b56e/rsrc/js/application/uiexample/ReactorFocusExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
- 2 => 'javelin-util',
- 3 => 'javelin-dom',
- 4 => 'javelin-reactor-dom',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorFocusExample.js',
),
'phabricator-uiexample-reactor-input' =>
array(
- 'uri' => '/res/4953da16/rsrc/js/application/uiexample/ReactorInputExample.js',
+ 'uri' => '/res/936352d9/rsrc/js/application/uiexample/ReactorInputExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
- 2 => 'javelin-util',
- 3 => 'javelin-dom',
- 4 => 'javelin-reactor-dom',
- 5 => 'javelin-view-html',
- 6 => 'javelin-view-interpreter',
- 7 => 'javelin-view-renderer',
+ 1 => 'javelin-reactor-dom',
+ 2 => 'javelin-view-html',
+ 3 => 'javelin-view-interpreter',
+ 4 => 'javelin-view-renderer',
),
'disk' => '/rsrc/js/application/uiexample/ReactorInputExample.js',
),
'phabricator-uiexample-reactor-mouseover' =>
array(
- 'uri' => '/res/52a355b6/rsrc/js/application/uiexample/ReactorMouseoverExample.js',
+ 'uri' => '/res/031a9f4f/rsrc/js/application/uiexample/ReactorMouseoverExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
- 2 => 'javelin-util',
- 3 => 'javelin-dom',
- 4 => 'javelin-reactor-dom',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorMouseoverExample.js',
),
'phabricator-uiexample-reactor-radio' =>
array(
- 'uri' => '/res/ae87f3af/rsrc/js/application/uiexample/ReactorRadioExample.js',
+ 'uri' => '/res/208c58e3/rsrc/js/application/uiexample/ReactorRadioExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
- 2 => 'javelin-util',
- 3 => 'javelin-dom',
- 4 => 'javelin-reactor-dom',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorRadioExample.js',
),
'phabricator-uiexample-reactor-select' =>
array(
- 'uri' => '/res/23cb448a/rsrc/js/application/uiexample/ReactorSelectExample.js',
+ 'uri' => '/res/1b68a6db/rsrc/js/application/uiexample/ReactorSelectExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
- 2 => 'javelin-util',
- 3 => 'javelin-dom',
- 4 => 'javelin-reactor-dom',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorSelectExample.js',
),
'phabricator-uiexample-reactor-sendclass' =>
array(
- 'uri' => '/res/8cd34264/rsrc/js/application/uiexample/ReactorSendClassExample.js',
+ 'uri' => '/res/00cb3131/rsrc/js/application/uiexample/ReactorSendClassExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
- 2 => 'javelin-util',
- 3 => 'javelin-dom',
- 4 => 'javelin-reactor-dom',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorSendClassExample.js',
),
'phabricator-uiexample-reactor-sendproperties' =>
array(
- 'uri' => '/res/18af54aa/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
+ 'uri' => '/res/392f1e02/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
- 1 => 'javelin-view',
- 2 => 'javelin-util',
- 3 => 'javelin-dom',
- 4 => 'javelin-reactor-dom',
+ 1 => 'javelin-dom',
+ 2 => 'javelin-reactor-dom',
),
'disk' => '/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
),
'phabricator-workboard-view-css' =>
array(
'uri' => '/res/f598d215/rsrc/css/layout/phabricator-workboard-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-workboard-view.css',
),
'phabricator-workpanel-view-css' =>
array(
'uri' => '/res/ff5d5b26/rsrc/css/layout/phabricator-workpanel-view.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/layout/phabricator-workpanel-view.css',
),
'phabricator-zindex-css' =>
array(
'uri' => '/res/d4048e34/rsrc/css/core/z-index.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/z-index.css',
),
'phame-css' =>
array(
'uri' => '/res/8e3edb71/rsrc/css/application/phame/phame.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/phame/phame.css',
),
'pholio-css' =>
array(
'uri' => '/res/0daaf1ca/rsrc/css/application/pholio/pholio.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/pholio/pholio.css',
),
'pholio-inline-comments-css' =>
array(
'uri' => '/res/006fc575/rsrc/css/application/pholio/pholio-inline-comments.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/pholio/pholio-inline-comments.css',
),
'phortune-credit-card-form' =>
array(
'uri' => '/res/bc948778/rsrc/js/application/phortune/phortune-credit-card-form.js',
'type' => 'js',
'requires' =>
array(
0 => 'javelin-install',
1 => 'javelin-dom',
2 => 'javelin-json',
3 => 'javelin-workflow',
4 => 'javelin-util',
),
'disk' => '/rsrc/js/application/phortune/phortune-credit-card-form.js',
),
'phortune-credit-card-form-css' =>
array(
'uri' => '/res/563c8c6d/rsrc/css/application/phortune/phortune-credit-card-form.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/phortune/phortune-credit-card-form.css',
),
'phrequent-css' =>
array(
'uri' => '/res/9d6f3eb7/rsrc/css/application/phrequent/phrequent.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/phrequent/phrequent.css',
),
'phriction-document-css' =>
array(
'uri' => '/res/cc6cefba/rsrc/css/application/phriction/phriction-document-css.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/phriction/phriction-document-css.css',
),
'phui-box-css' =>
array(
'uri' => '/res/1b741073/rsrc/css/phui/phui-box.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/phui/phui-box.css',
),
'phui-feed-story-css' =>
array(
'uri' => '/res/2fb3c729/rsrc/css/phui/phui-feed-story.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/phui/phui-feed-story.css',
),
'phui-form-css' =>
array(
'uri' => '/res/ba4d7995/rsrc/css/phui/phui-form.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/phui/phui-form.css',
),
'phui-icon-view-css' =>
array(
'uri' => '/res/1b1a37b5/rsrc/css/phui/phui-icon.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/phui/phui-icon.css',
),
'phui-text-css' =>
array(
'uri' => '/res/ca884ca6/rsrc/css/phui/phui-text.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/phui/phui-text.css',
),
'ponder-comment-table-css' =>
array(
'uri' => '/res/a1bb9056/rsrc/css/application/ponder/comments.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/comments.css',
),
'ponder-core-view-css' =>
array(
'uri' => '/res/3a2d5e18/rsrc/css/application/ponder/core.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/core.css',
),
'ponder-feed-view-css' =>
array(
'uri' => '/res/df22bd20/rsrc/css/application/ponder/feed.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/feed.css',
),
'ponder-post-css' =>
array(
'uri' => '/res/013b9e2c/rsrc/css/application/ponder/post.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/post.css',
),
'ponder-vote-css' =>
array(
'uri' => '/res/ea8316c2/rsrc/css/application/ponder/vote.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/ponder/vote.css',
),
'raphael-core' =>
array(
- 'uri' => '/res/0939b925/rsrc/externals/raphael/raphael.js',
+ 'uri' => '/res/5dc5e17c/rsrc/externals/raphael/raphael.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/externals/raphael/raphael.js',
),
'raphael-g' =>
array(
- 'uri' => '/res/e14432ce/rsrc/externals/raphael/g.raphael.js',
+ 'uri' => '/res/229b89a1/rsrc/externals/raphael/g.raphael.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/externals/raphael/g.raphael.js',
),
'raphael-g-line' =>
array(
- 'uri' => '/res/2c9e6746/rsrc/externals/raphael/g.raphael.line.js',
+ 'uri' => '/res/96da30f7/rsrc/externals/raphael/g.raphael.line.js',
'type' => 'js',
'requires' =>
array(
),
'disk' => '/rsrc/externals/raphael/g.raphael.line.js',
),
'releeph-branch' =>
array(
'uri' => '/res/6ad6420d/rsrc/css/application/releeph/releeph-branch.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/releeph/releeph-branch.css',
),
'releeph-colors' =>
array(
'uri' => '/res/dff4b26a/rsrc/css/application/releeph/releeph-colors.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/releeph/releeph-colors.css',
),
'releeph-core' =>
array(
'uri' => '/res/853f4a73/rsrc/css/application/releeph/releeph-core.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/releeph/releeph-core.css',
),
'releeph-intents' =>
array(
'uri' => '/res/4e73e9dd/rsrc/css/application/releeph/releeph-intents.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/releeph/releeph-intents.css',
),
'releeph-preview-branch' =>
array(
'uri' => '/res/65e5dece/rsrc/css/application/releeph/releeph-preview-branch.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/releeph/releeph-preview-branch.css',
),
'releeph-project' =>
array(
'uri' => '/res/b9376e59/rsrc/css/application/releeph/releeph-project.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/releeph/releeph-project.css',
),
'releeph-request-differential-create-dialog' =>
array(
'uri' => '/res/4df30ce1/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css',
),
'releeph-request-typeahead-css' =>
array(
'uri' => '/res/9c9a1acf/rsrc/css/application/releeph/releeph-request-typeahead.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/releeph/releeph-request-typeahead.css',
),
'releeph-status' =>
array(
'uri' => '/res/588529df/rsrc/css/application/releeph/releeph-status.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/releeph/releeph-status.css',
),
'setup-issue-css' =>
array(
'uri' => '/res/efbb3673/rsrc/css/application/config/setup-issue.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/config/setup-issue.css',
),
'spacing-css' =>
array(
'uri' => '/res/59e4c9b1/rsrc/css/core/spacing.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/spacing.css',
),
'sprite-actions-css' =>
array(
'uri' => '/res/bd43efa8/rsrc/css/sprite-actions.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-actions.css',
),
'sprite-apps-css' =>
array(
'uri' => '/res/edc99ce1/rsrc/css/sprite-apps.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-apps.css',
),
'sprite-apps-large-css' =>
array(
'uri' => '/res/40397d93/rsrc/css/sprite-apps-large.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-apps-large.css',
),
'sprite-apps-xlarge-css' =>
array(
'uri' => '/res/33a8e644/rsrc/css/sprite-apps-xlarge.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-apps-xlarge.css',
),
'sprite-conpherence-css' =>
array(
'uri' => '/res/f6793453/rsrc/css/sprite-conpherence.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-conpherence.css',
),
'sprite-docs-css' =>
array(
'uri' => '/res/b32f93bc/rsrc/css/sprite-docs.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-docs.css',
),
'sprite-gradient-css' =>
array(
'uri' => '/res/ca88b981/rsrc/css/sprite-gradient.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-gradient.css',
),
'sprite-icons-css' =>
array(
'uri' => '/res/cc45e87c/rsrc/css/sprite-icons.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-icons.css',
),
'sprite-menu-css' =>
array(
'uri' => '/res/e4e428f9/rsrc/css/sprite-menu.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-menu.css',
),
'sprite-minicons-css' =>
array(
'uri' => '/res/2dba70cd/rsrc/css/sprite-minicons.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-minicons.css',
),
'sprite-payments-css' =>
array(
'uri' => '/res/876697b6/rsrc/css/sprite-payments.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-payments.css',
),
'sprite-tokens-css' =>
array(
'uri' => '/res/edb4e341/rsrc/css/sprite-tokens.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/sprite-tokens.css',
),
'syntax-highlighting-css' =>
array(
'uri' => '/res/cb3b9dc0/rsrc/css/core/syntax.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/core/syntax.css',
),
'tokens-css' =>
array(
'uri' => '/res/dae13a94/rsrc/css/application/tokens/tokens.css',
'type' => 'css',
'requires' =>
array(
),
'disk' => '/rsrc/css/application/tokens/tokens.css',
),
), array(
'packages' =>
array(
'bdba44f0' =>
array(
'name' => 'core.pkg.css',
'symbols' =>
array(
0 => 'phabricator-core-css',
1 => 'phabricator-zindex-css',
2 => 'phabricator-core-buttons-css',
3 => 'phabricator-standard-page-view',
4 => 'aphront-dialog-view-css',
5 => 'aphront-form-view-css',
6 => 'aphront-panel-view-css',
7 => 'aphront-table-view-css',
8 => 'aphront-tokenizer-control-css',
9 => 'aphront-typeahead-control-css',
10 => 'aphront-list-filter-view-css',
11 => 'phabricator-directory-css',
12 => 'phabricator-jump-nav',
13 => 'phabricator-remarkup-css',
14 => 'syntax-highlighting-css',
15 => 'aphront-pager-view-css',
16 => 'phabricator-transaction-view-css',
17 => 'aphront-tooltip-css',
18 => 'phabricator-flag-css',
19 => 'aphront-error-view-css',
20 => 'sprite-icons-css',
21 => 'sprite-gradient-css',
22 => 'sprite-menu-css',
23 => 'sprite-apps-large-css',
24 => 'phabricator-main-menu-view',
25 => 'phabricator-notification-css',
26 => 'phabricator-notification-menu-css',
27 => 'lightbox-attachment-css',
28 => 'phabricator-header-view-css',
29 => 'phabricator-form-view-css',
30 => 'phabricator-filetree-view-css',
31 => 'phabricator-nav-view-css',
32 => 'phabricator-side-menu-view-css',
33 => 'phabricator-crumbs-view-css',
34 => 'phabricator-object-item-list-view-css',
35 => 'global-drag-and-drop-css',
),
'uri' => '/res/pkg/bdba44f0/core.pkg.css',
'type' => 'css',
),
- '26980a1c' =>
+ '25aa6fec' =>
array(
'name' => 'core.pkg.js',
'symbols' =>
array(
0 => 'javelin-behavior-aphront-basic-tokenizer',
1 => 'javelin-behavior-workflow',
2 => 'javelin-behavior-aphront-form-disable-on-submit',
3 => 'phabricator-keyboard-shortcut-manager',
4 => 'phabricator-keyboard-shortcut',
5 => 'javelin-behavior-phabricator-keyboard-shortcuts',
6 => 'javelin-behavior-refresh-csrf',
7 => 'javelin-behavior-phabricator-watch-anchor',
8 => 'javelin-behavior-phabricator-autofocus',
9 => 'phabricator-menu-item',
10 => 'phabricator-dropdown-menu',
11 => 'phabricator-phtize',
12 => 'javelin-behavior-phabricator-oncopy',
13 => 'phabricator-tooltip',
14 => 'javelin-behavior-phabricator-tooltips',
15 => 'phabricator-prefab',
16 => 'javelin-behavior-device',
17 => 'javelin-behavior-toggle-class',
18 => 'javelin-behavior-lightbox-attachments',
19 => 'phabricator-busy',
20 => 'javelin-aphlict',
21 => 'phabricator-notification',
22 => 'javelin-behavior-aphlict-listen',
23 => 'javelin-behavior-phabricator-search-typeahead',
24 => 'javelin-behavior-konami',
25 => 'javelin-behavior-aphlict-dropdown',
26 => 'javelin-behavior-history-install',
27 => 'javelin-behavior-phabricator-gesture',
28 => 'javelin-behavior-phabricator-active-nav',
29 => 'javelin-behavior-phabricator-nav',
30 => 'javelin-behavior-phabricator-remarkup-assist',
31 => 'phabricator-textareautils',
32 => 'phabricator-file-upload',
33 => 'javelin-behavior-global-drag-and-drop',
34 => 'javelin-behavior-phabricator-reveal-content',
),
- 'uri' => '/res/pkg/26980a1c/core.pkg.js',
+ 'uri' => '/res/pkg/25aa6fec/core.pkg.js',
'type' => 'js',
),
'4ccfeb47' =>
array(
'name' => 'darkconsole.pkg.js',
'symbols' =>
array(
0 => 'javelin-behavior-dark-console',
1 => 'javelin-behavior-error-log',
),
'uri' => '/res/pkg/4ccfeb47/darkconsole.pkg.js',
'type' => 'js',
),
'dd27a69b' =>
array(
'name' => 'differential.pkg.css',
'symbols' =>
array(
0 => 'differential-core-view-css',
1 => 'differential-changeset-view-css',
2 => 'differential-results-table-css',
3 => 'differential-revision-history-css',
4 => 'differential-revision-list-css',
5 => 'differential-table-of-contents-css',
6 => 'differential-revision-comment-css',
7 => 'differential-revision-add-comment-css',
8 => 'differential-revision-comment-list-css',
9 => 'phabricator-object-selector-css',
10 => 'phabricator-content-source-view-css',
11 => 'differential-local-commits-view-css',
12 => 'inline-comment-summary-css',
),
'uri' => '/res/pkg/dd27a69b/differential.pkg.css',
'type' => 'css',
),
- '77e07ff4' =>
+ '9488bb69' =>
array(
'name' => 'differential.pkg.js',
'symbols' =>
array(
0 => 'phabricator-drag-and-drop-file-upload',
1 => 'phabricator-shaped-request',
2 => 'javelin-behavior-differential-feedback-preview',
3 => 'javelin-behavior-differential-edit-inline-comments',
4 => 'javelin-behavior-differential-populate',
5 => 'javelin-behavior-differential-show-more',
6 => 'javelin-behavior-differential-diff-radios',
7 => 'javelin-behavior-differential-accept-with-errors',
8 => 'javelin-behavior-differential-comment-jump',
9 => 'javelin-behavior-differential-add-reviewers-and-ccs',
10 => 'javelin-behavior-differential-keyboard-navigation',
11 => 'javelin-behavior-aphront-drag-and-drop',
12 => 'javelin-behavior-aphront-drag-and-drop-textarea',
13 => 'javelin-behavior-phabricator-object-selector',
14 => 'javelin-behavior-repository-crossreference',
15 => 'javelin-behavior-load-blame',
16 => 'differential-inline-comment-editor',
17 => 'javelin-behavior-differential-dropdown-menus',
18 => 'javelin-behavior-differential-toggle-files',
19 => 'javelin-behavior-differential-user-select',
),
- 'uri' => '/res/pkg/77e07ff4/differential.pkg.js',
+ 'uri' => '/res/pkg/9488bb69/differential.pkg.js',
'type' => 'js',
),
'c8ce2d88' =>
array(
'name' => 'diffusion.pkg.css',
'symbols' =>
array(
0 => 'diffusion-commit-view-css',
1 => 'diffusion-icons-css',
),
'uri' => '/res/pkg/c8ce2d88/diffusion.pkg.css',
'type' => 'css',
),
- 'f96657b8' =>
+ 96909266 =>
array(
'name' => 'diffusion.pkg.js',
'symbols' =>
array(
0 => 'javelin-behavior-diffusion-pull-lastmodified',
1 => 'javelin-behavior-diffusion-commit-graph',
2 => 'javelin-behavior-audit-preview',
),
- 'uri' => '/res/pkg/f96657b8/diffusion.pkg.js',
+ 'uri' => '/res/pkg/96909266/diffusion.pkg.js',
'type' => 'js',
),
- '202a3dd0' =>
+ '565e00f7' =>
array(
'name' => 'javelin.pkg.js',
'symbols' =>
array(
0 => 'javelin-util',
1 => 'javelin-install',
2 => 'javelin-event',
3 => 'javelin-stratcom',
4 => 'javelin-behavior',
5 => 'javelin-resource',
6 => 'javelin-request',
7 => 'javelin-vector',
8 => 'javelin-dom',
9 => 'javelin-json',
10 => 'javelin-uri',
11 => 'javelin-workflow',
12 => 'javelin-mask',
13 => 'javelin-typeahead',
14 => 'javelin-typeahead-normalizer',
15 => 'javelin-typeahead-source',
16 => 'javelin-typeahead-preloaded-source',
17 => 'javelin-typeahead-ondemand-source',
18 => 'javelin-tokenizer',
),
- 'uri' => '/res/pkg/202a3dd0/javelin.pkg.js',
+ 'uri' => '/res/pkg/565e00f7/javelin.pkg.js',
'type' => 'js',
),
'6b1fccc6' =>
array(
'name' => 'maniphest.pkg.css',
'symbols' =>
array(
0 => 'maniphest-task-summary-css',
1 => 'maniphest-transaction-detail-css',
2 => 'aphront-attached-file-view-css',
3 => 'phabricator-project-tag-css',
),
'uri' => '/res/pkg/6b1fccc6/maniphest.pkg.css',
'type' => 'css',
),
- 'f85eb6d8' =>
+ '1621e522' =>
array(
'name' => 'maniphest.pkg.js',
'symbols' =>
array(
0 => 'javelin-behavior-maniphest-batch-selector',
1 => 'javelin-behavior-maniphest-transaction-controls',
2 => 'javelin-behavior-maniphest-transaction-preview',
3 => 'javelin-behavior-maniphest-transaction-expand',
4 => 'javelin-behavior-maniphest-subpriority-editor',
),
- 'uri' => '/res/pkg/f85eb6d8/maniphest.pkg.js',
+ 'uri' => '/res/pkg/1621e522/maniphest.pkg.js',
'type' => 'js',
),
),
'reverse' =>
array(
'aphront-attached-file-view-css' => '6b1fccc6',
'aphront-dialog-view-css' => 'bdba44f0',
'aphront-error-view-css' => 'bdba44f0',
'aphront-form-view-css' => 'bdba44f0',
'aphront-list-filter-view-css' => 'bdba44f0',
'aphront-pager-view-css' => 'bdba44f0',
'aphront-panel-view-css' => 'bdba44f0',
'aphront-table-view-css' => 'bdba44f0',
'aphront-tokenizer-control-css' => 'bdba44f0',
'aphront-tooltip-css' => 'bdba44f0',
'aphront-typeahead-control-css' => 'bdba44f0',
'differential-changeset-view-css' => 'dd27a69b',
'differential-core-view-css' => 'dd27a69b',
- 'differential-inline-comment-editor' => '77e07ff4',
+ 'differential-inline-comment-editor' => '9488bb69',
'differential-local-commits-view-css' => 'dd27a69b',
'differential-results-table-css' => 'dd27a69b',
'differential-revision-add-comment-css' => 'dd27a69b',
'differential-revision-comment-css' => 'dd27a69b',
'differential-revision-comment-list-css' => 'dd27a69b',
'differential-revision-history-css' => 'dd27a69b',
'differential-revision-list-css' => 'dd27a69b',
'differential-table-of-contents-css' => 'dd27a69b',
'diffusion-commit-view-css' => 'c8ce2d88',
'diffusion-icons-css' => 'c8ce2d88',
'global-drag-and-drop-css' => 'bdba44f0',
'inline-comment-summary-css' => 'dd27a69b',
- 'javelin-aphlict' => '26980a1c',
- 'javelin-behavior' => '202a3dd0',
- 'javelin-behavior-aphlict-dropdown' => '26980a1c',
- 'javelin-behavior-aphlict-listen' => '26980a1c',
- 'javelin-behavior-aphront-basic-tokenizer' => '26980a1c',
- 'javelin-behavior-aphront-drag-and-drop' => '77e07ff4',
- 'javelin-behavior-aphront-drag-and-drop-textarea' => '77e07ff4',
- 'javelin-behavior-aphront-form-disable-on-submit' => '26980a1c',
- 'javelin-behavior-audit-preview' => 'f96657b8',
+ 'javelin-aphlict' => '25aa6fec',
+ 'javelin-behavior' => '565e00f7',
+ 'javelin-behavior-aphlict-dropdown' => '25aa6fec',
+ 'javelin-behavior-aphlict-listen' => '25aa6fec',
+ 'javelin-behavior-aphront-basic-tokenizer' => '25aa6fec',
+ 'javelin-behavior-aphront-drag-and-drop' => '9488bb69',
+ 'javelin-behavior-aphront-drag-and-drop-textarea' => '9488bb69',
+ 'javelin-behavior-aphront-form-disable-on-submit' => '25aa6fec',
+ 'javelin-behavior-audit-preview' => '96909266',
'javelin-behavior-dark-console' => '4ccfeb47',
- 'javelin-behavior-device' => '26980a1c',
- 'javelin-behavior-differential-accept-with-errors' => '77e07ff4',
- 'javelin-behavior-differential-add-reviewers-and-ccs' => '77e07ff4',
- 'javelin-behavior-differential-comment-jump' => '77e07ff4',
- 'javelin-behavior-differential-diff-radios' => '77e07ff4',
- 'javelin-behavior-differential-dropdown-menus' => '77e07ff4',
- 'javelin-behavior-differential-edit-inline-comments' => '77e07ff4',
- 'javelin-behavior-differential-feedback-preview' => '77e07ff4',
- 'javelin-behavior-differential-keyboard-navigation' => '77e07ff4',
- 'javelin-behavior-differential-populate' => '77e07ff4',
- 'javelin-behavior-differential-show-more' => '77e07ff4',
- 'javelin-behavior-differential-toggle-files' => '77e07ff4',
- 'javelin-behavior-differential-user-select' => '77e07ff4',
- 'javelin-behavior-diffusion-commit-graph' => 'f96657b8',
- 'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8',
+ 'javelin-behavior-device' => '25aa6fec',
+ 'javelin-behavior-differential-accept-with-errors' => '9488bb69',
+ 'javelin-behavior-differential-add-reviewers-and-ccs' => '9488bb69',
+ 'javelin-behavior-differential-comment-jump' => '9488bb69',
+ 'javelin-behavior-differential-diff-radios' => '9488bb69',
+ 'javelin-behavior-differential-dropdown-menus' => '9488bb69',
+ 'javelin-behavior-differential-edit-inline-comments' => '9488bb69',
+ 'javelin-behavior-differential-feedback-preview' => '9488bb69',
+ 'javelin-behavior-differential-keyboard-navigation' => '9488bb69',
+ 'javelin-behavior-differential-populate' => '9488bb69',
+ 'javelin-behavior-differential-show-more' => '9488bb69',
+ 'javelin-behavior-differential-toggle-files' => '9488bb69',
+ 'javelin-behavior-differential-user-select' => '9488bb69',
+ 'javelin-behavior-diffusion-commit-graph' => '96909266',
+ 'javelin-behavior-diffusion-pull-lastmodified' => '96909266',
'javelin-behavior-error-log' => '4ccfeb47',
- 'javelin-behavior-global-drag-and-drop' => '26980a1c',
- 'javelin-behavior-history-install' => '26980a1c',
- 'javelin-behavior-konami' => '26980a1c',
- 'javelin-behavior-lightbox-attachments' => '26980a1c',
- 'javelin-behavior-load-blame' => '77e07ff4',
- 'javelin-behavior-maniphest-batch-selector' => 'f85eb6d8',
- 'javelin-behavior-maniphest-subpriority-editor' => 'f85eb6d8',
- 'javelin-behavior-maniphest-transaction-controls' => 'f85eb6d8',
- 'javelin-behavior-maniphest-transaction-expand' => 'f85eb6d8',
- 'javelin-behavior-maniphest-transaction-preview' => 'f85eb6d8',
- 'javelin-behavior-phabricator-active-nav' => '26980a1c',
- 'javelin-behavior-phabricator-autofocus' => '26980a1c',
- 'javelin-behavior-phabricator-gesture' => '26980a1c',
- 'javelin-behavior-phabricator-keyboard-shortcuts' => '26980a1c',
- 'javelin-behavior-phabricator-nav' => '26980a1c',
- 'javelin-behavior-phabricator-object-selector' => '77e07ff4',
- 'javelin-behavior-phabricator-oncopy' => '26980a1c',
- 'javelin-behavior-phabricator-remarkup-assist' => '26980a1c',
- 'javelin-behavior-phabricator-reveal-content' => '26980a1c',
- 'javelin-behavior-phabricator-search-typeahead' => '26980a1c',
- 'javelin-behavior-phabricator-tooltips' => '26980a1c',
- 'javelin-behavior-phabricator-watch-anchor' => '26980a1c',
- 'javelin-behavior-refresh-csrf' => '26980a1c',
- 'javelin-behavior-repository-crossreference' => '77e07ff4',
- 'javelin-behavior-toggle-class' => '26980a1c',
- 'javelin-behavior-workflow' => '26980a1c',
- 'javelin-dom' => '202a3dd0',
- 'javelin-event' => '202a3dd0',
- 'javelin-install' => '202a3dd0',
- 'javelin-json' => '202a3dd0',
- 'javelin-mask' => '202a3dd0',
- 'javelin-request' => '202a3dd0',
- 'javelin-resource' => '202a3dd0',
- 'javelin-stratcom' => '202a3dd0',
- 'javelin-tokenizer' => '202a3dd0',
- 'javelin-typeahead' => '202a3dd0',
- 'javelin-typeahead-normalizer' => '202a3dd0',
- 'javelin-typeahead-ondemand-source' => '202a3dd0',
- 'javelin-typeahead-preloaded-source' => '202a3dd0',
- 'javelin-typeahead-source' => '202a3dd0',
- 'javelin-uri' => '202a3dd0',
- 'javelin-util' => '202a3dd0',
- 'javelin-vector' => '202a3dd0',
- 'javelin-workflow' => '202a3dd0',
+ 'javelin-behavior-global-drag-and-drop' => '25aa6fec',
+ 'javelin-behavior-history-install' => '25aa6fec',
+ 'javelin-behavior-konami' => '25aa6fec',
+ 'javelin-behavior-lightbox-attachments' => '25aa6fec',
+ 'javelin-behavior-load-blame' => '9488bb69',
+ 'javelin-behavior-maniphest-batch-selector' => '1621e522',
+ 'javelin-behavior-maniphest-subpriority-editor' => '1621e522',
+ 'javelin-behavior-maniphest-transaction-controls' => '1621e522',
+ 'javelin-behavior-maniphest-transaction-expand' => '1621e522',
+ 'javelin-behavior-maniphest-transaction-preview' => '1621e522',
+ 'javelin-behavior-phabricator-active-nav' => '25aa6fec',
+ 'javelin-behavior-phabricator-autofocus' => '25aa6fec',
+ 'javelin-behavior-phabricator-gesture' => '25aa6fec',
+ 'javelin-behavior-phabricator-keyboard-shortcuts' => '25aa6fec',
+ 'javelin-behavior-phabricator-nav' => '25aa6fec',
+ 'javelin-behavior-phabricator-object-selector' => '9488bb69',
+ 'javelin-behavior-phabricator-oncopy' => '25aa6fec',
+ 'javelin-behavior-phabricator-remarkup-assist' => '25aa6fec',
+ 'javelin-behavior-phabricator-reveal-content' => '25aa6fec',
+ 'javelin-behavior-phabricator-search-typeahead' => '25aa6fec',
+ 'javelin-behavior-phabricator-tooltips' => '25aa6fec',
+ 'javelin-behavior-phabricator-watch-anchor' => '25aa6fec',
+ 'javelin-behavior-refresh-csrf' => '25aa6fec',
+ 'javelin-behavior-repository-crossreference' => '9488bb69',
+ 'javelin-behavior-toggle-class' => '25aa6fec',
+ 'javelin-behavior-workflow' => '25aa6fec',
+ 'javelin-dom' => '565e00f7',
+ 'javelin-event' => '565e00f7',
+ 'javelin-install' => '565e00f7',
+ 'javelin-json' => '565e00f7',
+ 'javelin-mask' => '565e00f7',
+ 'javelin-request' => '565e00f7',
+ 'javelin-resource' => '565e00f7',
+ 'javelin-stratcom' => '565e00f7',
+ 'javelin-tokenizer' => '565e00f7',
+ 'javelin-typeahead' => '565e00f7',
+ 'javelin-typeahead-normalizer' => '565e00f7',
+ 'javelin-typeahead-ondemand-source' => '565e00f7',
+ 'javelin-typeahead-preloaded-source' => '565e00f7',
+ 'javelin-typeahead-source' => '565e00f7',
+ 'javelin-uri' => '565e00f7',
+ 'javelin-util' => '565e00f7',
+ 'javelin-vector' => '565e00f7',
+ 'javelin-workflow' => '565e00f7',
'lightbox-attachment-css' => 'bdba44f0',
'maniphest-task-summary-css' => '6b1fccc6',
'maniphest-transaction-detail-css' => '6b1fccc6',
- 'phabricator-busy' => '26980a1c',
+ 'phabricator-busy' => '25aa6fec',
'phabricator-content-source-view-css' => 'dd27a69b',
'phabricator-core-buttons-css' => 'bdba44f0',
'phabricator-core-css' => 'bdba44f0',
'phabricator-crumbs-view-css' => 'bdba44f0',
'phabricator-directory-css' => 'bdba44f0',
- 'phabricator-drag-and-drop-file-upload' => '77e07ff4',
- 'phabricator-dropdown-menu' => '26980a1c',
- 'phabricator-file-upload' => '26980a1c',
+ 'phabricator-drag-and-drop-file-upload' => '9488bb69',
+ 'phabricator-dropdown-menu' => '25aa6fec',
+ 'phabricator-file-upload' => '25aa6fec',
'phabricator-filetree-view-css' => 'bdba44f0',
'phabricator-flag-css' => 'bdba44f0',
'phabricator-form-view-css' => 'bdba44f0',
'phabricator-header-view-css' => 'bdba44f0',
'phabricator-jump-nav' => 'bdba44f0',
- 'phabricator-keyboard-shortcut' => '26980a1c',
- 'phabricator-keyboard-shortcut-manager' => '26980a1c',
+ 'phabricator-keyboard-shortcut' => '25aa6fec',
+ 'phabricator-keyboard-shortcut-manager' => '25aa6fec',
'phabricator-main-menu-view' => 'bdba44f0',
- 'phabricator-menu-item' => '26980a1c',
+ 'phabricator-menu-item' => '25aa6fec',
'phabricator-nav-view-css' => 'bdba44f0',
- 'phabricator-notification' => '26980a1c',
+ 'phabricator-notification' => '25aa6fec',
'phabricator-notification-css' => 'bdba44f0',
'phabricator-notification-menu-css' => 'bdba44f0',
'phabricator-object-item-list-view-css' => 'bdba44f0',
'phabricator-object-selector-css' => 'dd27a69b',
- 'phabricator-phtize' => '26980a1c',
- 'phabricator-prefab' => '26980a1c',
+ 'phabricator-phtize' => '25aa6fec',
+ 'phabricator-prefab' => '25aa6fec',
'phabricator-project-tag-css' => '6b1fccc6',
'phabricator-remarkup-css' => 'bdba44f0',
- 'phabricator-shaped-request' => '77e07ff4',
+ 'phabricator-shaped-request' => '9488bb69',
'phabricator-side-menu-view-css' => 'bdba44f0',
'phabricator-standard-page-view' => 'bdba44f0',
- 'phabricator-textareautils' => '26980a1c',
- 'phabricator-tooltip' => '26980a1c',
+ 'phabricator-textareautils' => '25aa6fec',
+ 'phabricator-tooltip' => '25aa6fec',
'phabricator-transaction-view-css' => 'bdba44f0',
'phabricator-zindex-css' => 'bdba44f0',
'sprite-apps-large-css' => 'bdba44f0',
'sprite-gradient-css' => 'bdba44f0',
'sprite-icons-css' => 'bdba44f0',
'sprite-menu-css' => 'bdba44f0',
'syntax-highlighting-css' => 'bdba44f0',
),
));
diff --git a/src/infrastructure/celerity/CelerityResourceTransformer.php b/src/infrastructure/celerity/CelerityResourceTransformer.php
index 180de4941b..922f41dab8 100644
--- a/src/infrastructure/celerity/CelerityResourceTransformer.php
+++ b/src/infrastructure/celerity/CelerityResourceTransformer.php
@@ -1,111 +1,122 @@
<?php
/**
* @group celerity
*/
final class CelerityResourceTransformer {
private $minify;
private $rawResourceMap;
private $celerityMap;
private $translateURICallback;
public function setTranslateURICallback($translate_uricallback) {
$this->translateURICallback = $translate_uricallback;
return $this;
}
public function setMinify($minify) {
$this->minify = $minify;
return $this;
}
public function setRawResourceMap(array $raw_resource_map) {
$this->rawResourceMap = $raw_resource_map;
return $this;
}
public function setCelerityMap(CelerityResourceMap $celerity_map) {
$this->celerityMap = $celerity_map;
return $this;
}
+ /**
+ * @phutil-external-symbol function jsShrink
+ */
public function transformResource($path, $data) {
$type = self::getResourceType($path);
switch ($type) {
case 'css':
$data = preg_replace_callback(
'@url\s*\((\s*[\'"]?.*?)\)@s',
nonempty(
$this->translateURICallback,
array($this, 'translateResourceURI')),
$data);
break;
}
if (!$this->minify) {
return $data;
}
// Some resources won't survive minification (like Raphael.js), and are
// marked so as not to be minified.
if (strpos($data, '@'.'do-not-minify') !== false) {
return $data;
}
switch ($type) {
case 'css':
// Remove comments.
$data = preg_replace('@/\*.*?\*/@s', '', $data);
// Remove whitespace around symbols.
$data = preg_replace('@\s*([{}:;,])\s*@', '\1', $data);
// Remove unnecessary semicolons.
$data = preg_replace('@;}@', '}', $data);
// Replace #rrggbb with #rgb when possible.
$data = preg_replace(
'@#([a-f0-9])\1([a-f0-9])\2([a-f0-9])\3@i',
'#\1\2\3',
$data);
$data = trim($data);
break;
case 'js':
- $root = dirname(phutil_get_library_root('phabricator'));
- $bin = $root.'/externals/javelin/support/jsxmin/jsxmin';
- if (@file_exists($bin)) {
- $future = new ExecFuture('%s __DEV__:0', $bin);
+ // If `jsxmin` is available, use it. jsxmin is the Javelin minifier and
+ // produces the smallest output, but is complicated to build.
+ if (Filesystem::binaryExists('jsxmin')) {
+ $future = new ExecFuture('jsxmin __DEV__:0');
$future->write($data);
list($err, $result) = $future->resolve();
if (!$err) {
$data = $result;
+ break;
}
}
+
+ // If `jsxmin` is not available, use `JsShrink`, which doesn't compress
+ // quite as well but is always available.
+ $root = dirname(phutil_get_library_root('phabricator'));
+ require_once $root.'/externals/JsShrink/jsShrink.php';
+ $data = jsShrink($data);
+
break;
}
return $data;
}
public static function getResourceType($path) {
return last(explode('.', $path));
}
public function translateResourceURI(array $matches) {
$uri = trim($matches[1], "'\" \r\t\n");
if ($this->rawResourceMap) {
if (isset($this->rawResourceMap[$uri]['uri'])) {
$uri = $this->rawResourceMap[$uri]['uri'];
}
} else if ($this->celerityMap) {
$info = $this->celerityMap->lookupFileInformation($uri);
if ($info) {
$uri = $info['uri'];
}
}
return 'url('.$uri.')';
}
}
diff --git a/src/infrastructure/lint/PhabricatorLintEngine.php b/src/infrastructure/lint/PhabricatorLintEngine.php
index 5248891b0e..1b247698f8 100644
--- a/src/infrastructure/lint/PhabricatorLintEngine.php
+++ b/src/infrastructure/lint/PhabricatorLintEngine.php
@@ -1,55 +1,74 @@
<?php
/**
* @concrete-extensible
*/
class PhabricatorLintEngine extends PhutilLintEngine {
public function buildLinters() {
$linters = parent::buildLinters();
foreach ($linters as $linter) {
if ($linter instanceof ArcanistPhutilXHPASTLinter) {
$linter->setDeprecatedFunctions(array(
'phutil_escape_html' =>
'The phutil_escape_html() function is deprecated. Raw strings '.
'passed to phutil_tag() or hsprintf() are escaped automatically.',
'javelin_render_tag' =>
'The javelin_render_tag() function is deprecated and unsafe. '.
'Use javelin_tag() instead.',
'phabricator_render_form' =>
'The phabricator_render_form() function is deprecated and unsafe. '.
'Use phabricator_form() instead.',
));
}
}
$paths = $this->getPaths();
foreach ($paths as $key => $path) {
if (!$this->pathExists($path)) {
unset($paths[$key]);
}
}
$javelin_linter = new PhabricatorJavelinLinter();
$linters[] = $javelin_linter;
+ $jshint_linter = new ArcanistJSHintLinter();
+ $linters[] = $jshint_linter;
+
foreach ($paths as $path) {
+ if (!preg_match('/\.js$/', $path)) {
+ continue;
+ }
+
+ if (strpos($path, 'externals/JsShrink') !== false) {
+ // Ignore warnings in JsShrink tests.
+ continue;
+ }
+
+ if (strpos($path, 'externals/raphael') !== false) {
+ // Ignore Raphael.
+ continue;
+ }
+
+ $jshint_linter->addPath($path);
+ $jshint_linter->addData($path, $this->loadData($path));
+
if (strpos($path, 'support/aphlict/') !== false) {
// This stuff is Node.js, not Javelin, so don't apply the Javelin
// linter.
continue;
}
- if (preg_match('/\.js$/', $path)) {
- $javelin_linter->addPath($path);
- $javelin_linter->addData($path, $this->loadData($path));
- }
+
+ $javelin_linter->addPath($path);
+ $javelin_linter->addData($path, $this->loadData($path));
}
return $linters;
}
}
diff --git a/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php b/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php
index 3fa5a2052d..a1f9cd9974 100644
--- a/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php
+++ b/src/infrastructure/lint/linter/PhabricatorJavelinLinter.php
@@ -1,261 +1,266 @@
<?php
final class PhabricatorJavelinLinter extends ArcanistLinter {
private $symbols = array();
private $symbolsBinary;
private $haveWarnedAboutBinary;
const LINT_PRIVATE_ACCESS = 1;
const LINT_MISSING_DEPENDENCY = 2;
const LINT_UNNECESSARY_DEPENDENCY = 3;
const LINT_UNKNOWN_DEPENDENCY = 4;
const LINT_MISSING_BINARY = 5;
private function getBinaryPath() {
if ($this->symbolsBinary === null) {
list($err, $stdout) = exec_manual('which javelinsymbols');
$this->symbolsBinary = ($err ? false : rtrim($stdout));
}
return $this->symbolsBinary;
}
public function willLintPaths(array $paths) {
if (!$this->getBinaryPath()) {
return;
}
$root = dirname(phutil_get_library_root('phabricator'));
require_once $root.'/scripts/__init_script__.php';
$futures = array();
foreach ($paths as $path) {
if ($this->shouldIgnorePath($path)) {
continue;
}
$future = $this->newSymbolsFuture($path);
$futures[$path] = $future;
}
foreach (Futures($futures)->limit(8) as $path => $future) {
$this->symbols[$path] = $future->resolvex();
}
}
public function getLinterName() {
return 'JAVELIN';
}
public function getLintSeverityMap() {
return array(
self::LINT_MISSING_BINARY => ArcanistLintSeverity::SEVERITY_WARNING,
);
}
public function getLintNameMap() {
return array(
self::LINT_PRIVATE_ACCESS => 'Private Method/Member Access',
self::LINT_MISSING_DEPENDENCY => 'Missing Javelin Dependency',
self::LINT_UNNECESSARY_DEPENDENCY => 'Unnecessary Javelin Dependency',
self::LINT_UNKNOWN_DEPENDENCY => 'Unknown Javelin Dependency',
self::LINT_MISSING_BINARY => '`javelinsymbols` Not In Path',
);
}
public function getCacheGranularity() {
return ArcanistLinter::GRANULARITY_REPOSITORY;
}
public function getCacheVersion() {
$version = '0';
$binary_path = $this->getBinaryPath();
if ($binary_path) {
$version .= '-'.md5_file($binary_path);
}
return $version;
}
private function shouldIgnorePath($path) {
- return preg_match('@/__tests__/|externals/javelinjs/src/docs/@', $path);
+ return preg_match('@/__tests__/|externals/javelin/docs/@', $path);
}
public function lintPath($path) {
if ($this->shouldIgnorePath($path)) {
return;
}
if (!$this->symbolsBinary) {
if (!$this->haveWarnedAboutBinary) {
$this->haveWarnedAboutBinary = true;
// TODO: Write build documentation for the Javelin binaries and point
// the user at it.
$this->raiseLintAtLine(
1,
0,
self::LINT_MISSING_BINARY,
"The 'javelinsymbols' binary in the Javelin project is not ".
"available in \$PATH, so the Javelin linter can't run. This ".
"isn't a big concern, but means some Javelin problems can't be ".
"automatically detected.");
}
return;
}
list($uses, $installs) = $this->getUsedAndInstalledSymbolsForPath($path);
foreach ($uses as $symbol => $line) {
$parts = explode('.', $symbol);
foreach ($parts as $part) {
if ($part[0] == '_' && $part[1] != '_') {
$base = implode('.', array_slice($parts, 0, 2));
if (!array_key_exists($base, $installs)) {
$this->raiseLintAtLine(
$line,
0,
self::LINT_PRIVATE_ACCESS,
"This file accesses private symbol '{$symbol}' across file ".
"boundaries. You may only access private members and methods ".
"from the file where they are defined.");
}
break;
}
}
}
if ($this->getEngine()->getCommitHookMode()) {
// Don't do the dependency checks in commit-hook mode because we won't
// have an available working copy.
return;
}
$external_classes = array();
foreach ($uses as $symbol => $line) {
$parts = explode('.', $symbol);
$class = implode('.', array_slice($parts, 0, 2));
if (!array_key_exists($class, $external_classes) &&
!array_key_exists($class, $installs)) {
$external_classes[$class] = $line;
}
}
$celerity = CelerityResourceMap::getInstance();
$path = preg_replace(
'@^externals/javelinjs/src/@',
'webroot/rsrc/js/javelin/',
$path);
$need = $external_classes;
$info = $celerity->lookupFileInformation(substr($path, strlen('webroot')));
if (!$info) {
$info = array();
}
$requires = idx($info, 'requires', array());
foreach ($requires as $key => $name) {
$symbol_info = $celerity->lookupSymbolInformation($name);
if (!$symbol_info) {
$this->raiseLintAtLine(
0,
0,
self::LINT_UNKNOWN_DEPENDENCY,
"This file @requires component '{$name}', but it does not ".
"exist. You may need to rebuild the Celerity map.");
unset($requires[$key]);
continue;
}
- $symbol_path = 'webroot'.$symbol_info['disk'];
- list($ignored, $req_install) = $this->getUsedAndInstalledSymbolsForPath(
- $symbol_path);
- if (array_intersect_key($req_install, $external_classes)) {
- $need = array_diff_key($need, $req_install);
+ if (preg_match('/\\.css$/', $symbol_info['disk'])) {
+ // If JS requires CSS, just assume everything is fine.
unset($requires[$key]);
+ } else {
+ $symbol_path = 'webroot'.$symbol_info['disk'];
+ list($ignored, $req_install) = $this->getUsedAndInstalledSymbolsForPath(
+ $symbol_path);
+ if (array_intersect_key($req_install, $external_classes)) {
+ $need = array_diff_key($need, $req_install);
+ unset($requires[$key]);
+ }
}
}
foreach ($need as $class => $line) {
$this->raiseLintAtLine(
$line,
0,
self::LINT_MISSING_DEPENDENCY,
"This file uses '{$class}' but does not @requires the component ".
"which installs it. You may need to rebuild the Celerity map.");
}
foreach ($requires as $component) {
$this->raiseLintAtLine(
0,
0,
self::LINT_UNNECESSARY_DEPENDENCY,
"This file @requires component '{$component}' but does not use ".
"anything it provides.");
}
}
private function loadSymbols($path) {
if (empty($this->symbols[$path])) {
$this->symbols[$path] = $this->newSymbolsFuture($path)->resolvex();
}
return $this->symbols[$path];
}
private function newSymbolsFuture($path) {
$future = new ExecFuture('javelinsymbols # %s', $path);
$future->write($this->getData($path));
return $future;
}
private function getUsedAndInstalledSymbolsForPath($path) {
list($symbols) = $this->loadSymbols($path);
$symbols = trim($symbols);
$uses = array();
$installs = array();
if (empty($symbols)) {
// This file has no symbols.
return array($uses, $installs);
}
$symbols = explode("\n", trim($symbols));
foreach ($symbols as $line) {
$matches = null;
if (!preg_match('/^([?+\*])([^:]*):(\d+)$/', $line, $matches)) {
throw new Exception(
"Received malformed output from `javelinsymbols`.");
}
$type = $matches[1];
$symbol = $matches[2];
$line = $matches[3];
switch ($type) {
case '?':
$uses[$symbol] = $line;
break;
case '+':
$installs['JX.'.$symbol] = $line;
break;
}
}
$contents = $this->getData($path);
$matches = null;
$count = preg_match_all(
'/@javelin-installs\W+(\S+)/',
$contents,
$matches,
PREG_PATTERN_ORDER);
if ($count) {
foreach ($matches[1] as $symbol) {
$installs[$symbol] = 0;
}
}
return array($uses, $installs);
}
}
diff --git a/support/aphlict/server/aphlict_server.js b/support/aphlict/server/aphlict_server.js
index 8ac4f137e9..09869e9f99 100755
--- a/support/aphlict/server/aphlict_server.js
+++ b/support/aphlict/server/aphlict_server.js
@@ -1,230 +1,230 @@
/**
* Notification server. Launch with:
*
* sudo node aphlict_server.js --user=aphlict
*
* You can also specify `port`, `admin`, `host` and `log`.
*/
var config = parse_command_line_arguments(process.argv);
function parse_command_line_arguments(argv) {
var config = {
port : 22280,
admin : 22281,
host : '127.0.0.1',
user : null,
log: '/var/log/aphlict.log'
};
for (var ii = 2; ii < argv.length; ii++) {
var arg = argv[ii];
var matches = arg.match(/^--([^=]+)=(.*)$/);
if (!matches) {
throw new Error("Unknown argument '"+arg+"'!");
}
if (!(matches[1] in config)) {
throw new Error("Unknown argument '"+matches[1]+"'!");
}
config[matches[1]] = matches[2];
}
config.port = parseInt(config.port, 10);
config.admin = parseInt(config.admin, 10);
return config;
}
-if (process.getuid() != 0) {
+if (process.getuid() !== 0) {
console.log(
"ERROR: "+
"This server must be run as root because it needs to bind to privileged "+
"port 843 to start a Flash policy server. It will downgrade to run as a "+
"less-privileged user after binding if you pass a user in the command "+
"line arguments with '--user=alincoln'.");
process.exit(1);
}
var net = require('net');
var http = require('http');
var url = require('url');
var querystring = require('querystring');
var fs = require('fs');
// set up log file
var logfile = fs.createWriteStream(
config.log,
{
flags: 'a',
encoding: null,
mode: 0666
});
function log(str) {
console.log(str);
logfile.write(str + '\n');
}
process.on('uncaughtException', function (err) {
log("\n<<< UNCAUGHT EXCEPTION! >>>\n\n" + err);
process.exit(1);
});
log('----- ' + (new Date()).toLocaleString() + ' -----\n');
function getFlashPolicy() {
return [
'<?xml version="1.0"?>',
'<!DOCTYPE cross-domain-policy SYSTEM ' +
'"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">',
'<cross-domain-policy>',
'<allow-access-from domain="*" to-ports="'+config.port+'"/>',
'</cross-domain-policy>'
].join('\n');
}
net.createServer(function(socket) {
socket.write(getFlashPolicy() + '\0');
socket.end();
log('[' + socket.remoteAddress + '] Sent Flash Policy');
socket.on('error', function (e) {
log('Error in policy server: ' + e);
});
}).listen(843);
function write_json(socket, data) {
var serial = JSON.stringify(data);
var length = Buffer.byteLength(serial, 'utf8');
length = length.toString();
while (length.length < 8) {
length = '0' + length;
}
socket.write(length + serial);
}
var clients = {};
var current_connections = 0;
// According to the internet up to 2^53 can
// be stored in javascript, this is less than that
var MAX_ID = 9007199254740991;//2^53 -1
// If we get one connections per millisecond this will
// be fine as long as someone doesn't maintain a
// connection for longer than 6854793 years. If
// you want to write something pretty be my guest
function generate_id() {
- if (typeof generate_id.current_id == 'undefined'
- || generate_id.current_id > MAX_ID) {
+ if (typeof generate_id.current_id == 'undefined' ||
+ generate_id.current_id > MAX_ID) {
generate_id.current_id = 0;
}
return generate_id.current_id++;
}
var send_server = net.createServer(function(socket) {
var client_id = generate_id();
var client_name = '[' + socket.remoteAddress + '] [#' + client_id + '] ';
socket.on('connect', function() {
clients[client_id] = socket;
current_connections++;
- log(client_name + 'connected\t\t('
- + current_connections + ' current connections)');
+ log(client_name + 'connected\t\t(' +
+ current_connections + ' current connections)');
});
socket.on('close', function() {
delete clients[client_id];
current_connections--;
- log(client_name + 'closed\t\t('
- + current_connections + ' current connections)');
+ log(client_name + 'closed\t\t(' +
+ current_connections + ' current connections)');
});
socket.on('timeout', function() {
log(client_name + 'timed out!');
});
socket.on('end', function() {
log(client_name + 'ended the connection');
// node automatically closes half-open connections
});
socket.on('error', function (e) {
log(cliient_name + 'Uncaught error in send server: ' + e);
});
}).listen(config.port);
var messages_out = 0;
var messages_in = 0;
var start_time = new Date().getTime();
var receive_server = http.createServer(function(request, response) {
response.writeHead(200, {'Content-Type' : 'text/plain'});
// Publishing a notification.
if (request.method == 'POST') {
var body = '';
request.on('data', function (data) {
body += data;
});
request.on('end', function () {
++messages_in;
var data = querystring.parse(body);
log('notification: ' + JSON.stringify(data));
broadcast(data);
response.end();
});
} else if (request.url == '/status/') {
request.on('data', function(data) {
// We just ignore the request data, but newer versions of Node don't
// get to 'end' if we don't process the data. See T2953.
});
request.on('end', function() {
var status = {
'uptime': (new Date().getTime() - start_time),
'clients.active': current_connections,
'clients.total': generate_id.current_id || 0,
'messages.in': messages_in,
'messages.out': messages_out,
'log': config.log
};
response.write(JSON.stringify(status));
response.end();
});
} else {
response.statusCode = 400;
response.write('400 Bad Request');
response.end();
}
}).listen(config.admin, config.host);
function broadcast(data) {
for (var client_id in clients) {
try {
write_json(clients[client_id], data);
++messages_out;
log('wrote to client ' + client_id);
} catch (error) {
delete clients[client_id];
current_connections--;
log('ERROR: could not write to client ' + client_id);
}
}
}
// If we're configured to drop permissions, get rid of them now that we've
// bound to the ports we need and opened logfiles.
if (config.user) {
process.setuid(config.user);
}
diff --git a/support/jshint/jshintconfig b/support/jshint/jshintconfig
new file mode 100644
index 0000000000..e753307f4a
--- /dev/null
+++ b/support/jshint/jshintconfig
@@ -0,0 +1,5 @@
+{
+ "expr" : true,
+ "loopfunc" : true,
+ "sub" : true
+}
diff --git a/webroot/rsrc/externals/javelin/core/Event.js b/webroot/rsrc/externals/javelin/core/Event.js
index 0ef0f19709..51e3cfd897 100644
--- a/webroot/rsrc/externals/javelin/core/Event.js
+++ b/webroot/rsrc/externals/javelin/core/Event.js
@@ -1,343 +1,343 @@
/**
* @requires javelin-install
* @provides javelin-event
* @javelin
*/
/**
* A generic event, routed by @{class:JX.Stratcom}. All events within Javelin
* are represented by a {@class:JX.Event}, regardless of whether they originate
* from a native DOM event (like a mouse click) or are custom application
* events.
*
* See @{article:Concepts: Event Delegation} for an introduction to Javelin's
* event delegation model.
*
* Events have a propagation model similar to native Javascript events, in that
* they can be stopped with stop() (which stops them from continuing to
* propagate to other handlers) or prevented with prevent() (which prevents them
* from taking their default action, like following a link). You can do both at
* once with kill().
*
* @task stop Stopping Event Behaviors
* @task info Getting Event Information
* @group event
*/
JX.install('Event', {
members : {
/**
* Stop an event from continuing to propagate. No other handler will
* receive this event, but its default behavior will still occur. See
* ""Using Events"" for more information on the distinction between
* 'stopping' and 'preventing' an event. See also prevent() (which prevents
* an event but does not stop it) and kill() (which stops and prevents an
* event).
*
* @return this
* @task stop
*/
stop : function() {
var r = this.getRawEvent();
if (r) {
r.cancelBubble = true;
r.stopPropagation && r.stopPropagation();
}
this.setStopped(true);
return this;
},
/**
* Prevent an event's default action. This depends on the event type, but
* the common default actions are following links, submitting forms,
* and typing text. Event prevention is generally used when you have a link
* or form which work properly without Javascript but have a specialized
* Javascript behavior. When you intercept the event and make the behavior
* occur, you prevent it to keep the browser from following the link.
*
* Preventing an event does not stop it from propagating, so other handlers
* will still receive it. See ""Using Events"" for more information on the
* distinction between 'stopping' and 'preventing' an event. See also
* stop() (which stops an event but does not prevent it) and kill()
* (which stops and prevents an event).
*
* @return this
* @task stop
*/
prevent : function() {
var r = this.getRawEvent();
if (r) {
r.returnValue = false;
r.preventDefault && r.preventDefault();
}
this.setPrevented(true);
return this;
},
/**
* Stop and prevent an event, which stops it from propagating and prevents
* its defualt behavior. This is a convenience function, see stop() and
* prevent() for information on what it means to stop or prevent an event.
*
* @return this
* @task stop
*/
kill : function() {
this.prevent();
this.stop();
return this;
},
/**
* Get the special key (like tab or return), if any, associated with this
* event. Browsers report special keys differently; this method allows you
* to identify a keypress in a browser-agnostic way. Note that this detects
* only some special keys: delete, tab, return escape, left, up, right,
* down.
*
* For example, if you want to react to the escape key being pressed, you
* could install a listener like this:
*
* JX.Stratcom.listen('keydown', 'example', function(e) {
* if (e.getSpecialKey() == 'esc') {
* JX.log("You pressed 'Escape'! Well done! Bravo!");
* }
* });
*
* @return string|null ##null## if there is no associated special key,
* or one of the strings 'delete', 'tab', 'return',
* 'esc', 'left', 'up', 'right', or 'down'.
* @task info
*/
getSpecialKey : function() {
var r = this.getRawEvent();
if (!r) {
return null;
}
return JX.Event._keymap[r.keyCode] || null;
},
/**
* Get whether the mouse button associated with the mouse event is the
* right-side button in a browser-agnostic way.
*
* @return bool
* @task info
*/
isRightButton : function() {
var r = this.getRawEvent();
return r.which == 3 || r.button == 2;
},
/**
* Determine if a mouse event is a normal event (left mouse button, no
* modifier keys).
*
* @return bool
* @task info
*/
isNormalMouseEvent : function() {
var supportedEvents = ['click', 'mouseup', 'mousedown'];
if (supportedEvents.indexOf(this.getType()) == -1) {
return false;
}
var r = this.getRawEvent();
if (r.metaKey || r.altKey || r.ctrlKey || r.shiftKey) {
return false;
}
if (('which' in r) && (r.which != 1)) {
return false;
}
if (('button' in r) && r.button) {
return false;
}
return true;
},
/**
* Determine if a click event is a normal click (left mouse button, no
* modifier keys).
*
* @return bool
* @task info
*/
isNormalClick : function() {
if (this.getType() != 'click') {
return false;
}
return this.isNormalMouseEvent();
},
/**
* Get the node corresponding to the specified key in this event's node map.
* This is a simple helper method that makes the API for accessing nodes
* less ugly.
*
* JX.Stratcom.listen('click', 'tag:a', function(e) {
* var a = e.getNode('tag:a');
* // do something with the link that was clicked
* });
*
* @param string sigil or stratcom node key
* @return node|null Node mapped to the specified key, or null if it the
* key does not exist. The available keys include:
* - 'tag:'+tag - first node of each type
* - 'id:'+id - all nodes with an id
* - sigil - first node of each sigil
* @task info
*/
getNode : function(key) {
return this.getNodes()[key] || null;
},
/**
* Get the metadata associated with the node that corresponds to the key
* in this event's node map. This is a simple helper method that makes
* the API for accessing metadata associated with specific nodes less ugly.
*
* JX.Stratcom.listen('click', 'tag:a', function(event) {
* var anchorData = event.getNodeData('tag:a');
* // do something with the metadata of the link that was clicked
* });
*
* @param string sigil or stratcom node key
* @return dict dictionary of the node's metadata
* @task info
*/
getNodeData : function(key) {
// Evade static analysis - JX.Stratcom
return JX['Stratcom'].getData(this.getNode(key));
}
},
statics : {
_keymap : {
8 : 'delete',
9 : 'tab',
// On Windows and Linux, Chrome sends '10' for return. On Mac OS X, it
// sends 13. Other browsers evidence varying degrees of diversity in their
// behavior. Treat '10' and '13' identically.
10 : 'return',
13 : 'return',
27 : 'esc',
37 : 'left',
38 : 'up',
39 : 'right',
40 : 'down',
63232 : 'up',
63233 : 'down',
62234 : 'left',
62235 : 'right'
}
},
properties : {
/**
* Native Javascript event which generated this @{class:JX.Event}. Not every
* event is generated by a native event, so there may be ##null## in
* this field.
*
* @type Event|null
* @task info
*/
rawEvent : null,
/**
* String describing the event type, like 'click' or 'mousedown'. This
* may also be an application or object event.
*
* @type string
* @task info
*/
type : null,
/**
* If available, the DOM node where this event occurred. For example, if
* this event is a click on a button, the target will be the button which
* was clicked. Application events will not have a target, so this property
* will return the value ##null##.
*
* @type DOMNode|null
* @task info
*/
target : null,
/**
* Metadata attached to nodes associated with this event.
*
* For native events, the DOM is walked from the event target to the root
* element. Each sigil which is encountered while walking up the tree is
* added to the map as a key. If the node has associated metainformation,
* it is set as the value; otherwise, the value is null.
*
* @type dict<string, *>
* @task info
*/
data : null,
/**
* Sigil path this event was activated from. TODO: explain this
*
* @type list<string>
* @task info
*/
path : [],
/**
* True if propagation of the event has been stopped. See stop().
*
* @type bool
* @task stop
*/
stopped : false,
/**
* True if default behavior of the event has been prevented. See prevent().
*
* @type bool
* @task stop
*/
prevented : false,
/**
* @task info
*/
nodes : {},
/**
* @task info
*/
nodeDistances : {}
},
/**
* @{class:JX.Event} installs a toString() method in ##__DEV__## which allows
* you to log or print events and get a reasonable representation of them:
*
* Event<'click', ['path', 'stuff'], [object HTMLDivElement]>
*/
initialize : function() {
if (__DEV__) {
JX.Event.prototype.toString = function() {
var path = '['+this.getPath().join(', ')+']';
return 'Event<'+this.getType()+', '+path+', '+this.getTarget()+'>';
- }
+ };
}
}
});
diff --git a/webroot/rsrc/externals/javelin/core/init.js b/webroot/rsrc/externals/javelin/core/init.js
index a5aadd5a39..cab62d34f8 100644
--- a/webroot/rsrc/externals/javelin/core/init.js
+++ b/webroot/rsrc/externals/javelin/core/init.js
@@ -1,225 +1,227 @@
/**
* Javelin core; installs Javelin and Stratcom event delegation.
*
* @provides javelin-magical-init
*
* @javelin-installs JX.__rawEventQueue
* @javelin-installs JX.__simulate
* @javelin-installs JX.__allowedEvents
* @javelin-installs JX.enableDispatch
* @javelin-installs JX.onload
* @javelin-installs JX.flushHoldingQueue
*
* @javelin
*/
(function() {
if (window.JX) {
return;
}
window.JX = {};
// The holding queues hold calls to functions (JX.install() and JX.behavior())
// before they load, so if you're async-loading them later in the document
// the page will execute correctly regardless of the order resources arrive
// in.
var holding_queues = {};
function makeHoldingQueue(name) {
if (JX[name]) {
return;
}
holding_queues[name] = [];
- JX[name] = function() { holding_queues[name].push(arguments); }
+ JX[name] = function() { holding_queues[name].push(arguments); };
}
JX.flushHoldingQueue = function(name, fn) {
for (var ii = 0; ii < holding_queues[name].length; ii++) {
fn.apply(null, holding_queues[name][ii]);
}
holding_queues[name] = {};
- }
+ };
makeHoldingQueue('install');
makeHoldingQueue('behavior');
makeHoldingQueue('install-init');
window['__DEV__'] = window['__DEV__'] || 0;
var loaded = false;
var onload = [];
var master_event_queue = [];
var root = document.documentElement;
var has_add_event_listener = !!root.addEventListener;
JX.__rawEventQueue = function(what) {
master_event_queue.push(what);
// Evade static analysis - JX.Stratcom
var Stratcom = JX['Stratcom'];
if (Stratcom && Stratcom.ready) {
// Empty the queue now so that exceptions don't cause us to repeatedly
// try to handle events.
var local_queue = master_event_queue;
master_event_queue = [];
for (var ii = 0; ii < local_queue.length; ++ii) {
var evt = local_queue[ii];
// Sometimes IE gives us events which throw when ".type" is accessed;
// just ignore them since we can't meaningfully dispatch them. TODO:
// figure out where these are coming from.
try { var test = evt.type; } catch (x) { continue; }
if (!loaded && evt.type == 'domready') {
document.body && (document.body.id = null);
loaded = true;
for (var jj = 0; jj < onload.length; jj++) {
onload[jj]();
}
}
Stratcom.dispatch(evt);
}
} else {
var target = what.srcElement || what.target;
if (target &&
(what.type in {click: 1, submit: 1}) &&
target.getAttribute &&
target.getAttribute('data-mustcapture') === '1') {
what.returnValue = false;
what.preventDefault && what.preventDefault();
document.body.id = 'event_capture';
// For versions of IE that use attachEvent, the event object is somehow
// stored globally by reference, and all the references we push to the
// master_event_queue will always refer to the most recent event. We
// work around this by popping the useless global event off the queue,
// and pushing a clone of the event that was just fired using the IE's
// proprietary createEventObject function.
// see: http://msdn.microsoft.com/en-us/library/ms536390(v=vs.85).aspx
if (!add_event_listener && document.createEventObject) {
master_event_queue.pop();
master_event_queue.push(document.createEventObject(what));
}
return false;
}
}
- }
+ };
JX.enableDispatch = function(target, type) {
if (__DEV__) {
JX.__allowedEvents[type] = true;
}
if (target.addEventListener) {
target.addEventListener(type, JX.__rawEventQueue, true);
} else if (target.attachEvent) {
target.attachEvent('on' + type, JX.__rawEventQueue);
}
};
var document_events = [
'click',
'dblclick',
'change',
'submit',
'keypress',
'mousedown',
'mouseover',
'mouseout',
'mouseup',
'keyup',
'keydown',
'input',
'drop',
'dragenter',
'dragleave',
'dragover',
'paste',
'touchstart',
'touchmove',
'touchend',
'touchcancel'
];
// Simulate focus and blur in old versions of IE using focusin and focusout
// TODO: Document the gigantic IE mess here with focus/blur.
// TODO: beforeactivate/beforedeactivate?
// http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
if (!has_add_event_listener) {
document_events.push('focusin', 'focusout');
}
// Opera is multilol: it propagates focus / blur oddly
if (window.opera) {
document_events.push('focus', 'blur');
}
if (__DEV__) {
JX.__allowedEvents = {};
if ('onpagehide' in window) {
JX.__allowedEvents.unload = true;
}
}
- for (var ii = 0; ii < document_events.length; ++ii) {
+ var ii;
+ for (ii = 0; ii < document_events.length; ++ii) {
JX.enableDispatch(root, document_events[ii]);
}
// In particular, we're interested in capturing window focus/blur here so
// long polls can abort when the window is not focused.
var window_events = [
('onpagehide' in window) ? 'pagehide' : 'unload',
'resize',
'scroll',
'focus',
'blur',
'popstate',
'hashchange'
];
- for (var ii = 0; ii < window_events.length; ++ii) {
+ for (ii = 0; ii < window_events.length; ++ii) {
JX.enableDispatch(window, window_events[ii]);
}
JX.__simulate = function(node, event) {
if (!has_add_event_listener) {
var e = {target: node, type: event};
JX.__rawEventQueue(e);
if (e.returnValue === false) {
return false;
}
}
};
if (has_add_event_listener) {
document.addEventListener('DOMContentLoaded', function() {
JX.__rawEventQueue({type: 'domready'});
}, true);
} else {
var ready =
"if (this.readyState == 'complete') {" +
"JX.__rawEventQueue({type: 'domready'});" +
"}";
// NOTE: Don't write a 'src' attribute, because "javascript:void(0)" causes
// a mixed content warning in IE8 if the page is served over SSL.
document.write(
'<script' +
' defer="defer"' +
' onreadystatechange="' + ready + '"' +
- '><\/sc' + 'ript\>');
+ '><\/sc' + 'ript' + '>');
}
JX.onload = function(func) {
if (loaded) {
func();
} else {
onload.push(func);
}
- }
+ };
+
})();
diff --git a/webroot/rsrc/externals/javelin/core/util.js b/webroot/rsrc/externals/javelin/core/util.js
index c6b9f50ccc..cf29f246a5 100644
--- a/webroot/rsrc/externals/javelin/core/util.js
+++ b/webroot/rsrc/externals/javelin/core/util.js
@@ -1,367 +1,367 @@
/**
* Javelin utility functions.
*
* @provides javelin-util
*
* @javelin-installs JX.$E
* @javelin-installs JX.$A
* @javelin-installs JX.$AX
* @javelin-installs JX.isArray
* @javelin-installs JX.copy
* @javelin-installs JX.bind
* @javelin-installs JX.bag
* @javelin-installs JX.keys
* @javelin-installs JX.log
* @javelin-installs JX.id
* @javelin-installs JX.now
*
* @javelin
*/
/**
* Throw an exception and attach the caller data in the exception.
*
* @param string Exception message.
*
* @group util
*/
JX.$E = function(message) {
var e = new Error(message);
var caller_fn = JX.$E.caller;
if (caller_fn) {
e.caller_fn = caller_fn.caller;
}
throw e;
};
/**
* Convert an array-like object (usually ##arguments##) into a real Array. An
* "array-like object" is something with a ##length## property and numerical
* keys. The most common use for this is to let you call Array functions on the
* magical ##arguments## object.
*
* JX.$A(arguments).slice(1);
*
* @param obj Array, or array-like object.
* @return Array Actual array.
*
* @group util
*/
JX.$A = function(mysterious_arraylike_object) {
// NOTE: This avoids the Array.slice() trick because some bizarre COM object
// I dug up somewhere was freaking out when I tried to do it and it made me
// very upset, so do not replace this with Array.slice() cleverness.
var r = [];
for (var ii = 0; ii < mysterious_arraylike_object.length; ii++) {
r.push(mysterious_arraylike_object[ii]);
}
return r;
};
/**
* Cast a value into an array, by wrapping scalars into singletons. If the
* argument is an array, it is returned unmodified. If it is a scalar, an array
* with a single element is returned. For example:
*
* JX.$AX([3]); // Returns [3].
* JX.$AX(3); // Returns [3].
*
* Note that this function uses a @{function:JX.isArray} check whether or not
* the argument is an array, so you may need to convert array-like objects (such
* as ##arguments##) into real arrays with @{function:JX.$A}.
*
* This function is mostly useful to create methods which accept either a
* value or a list of values.
*
* @param wild Scalar or Array.
* @return Array If the argument was a scalar, an Array with the argument as
* its only element. Otherwise, the original Array.
*
* @group util
*/
JX.$AX = function(maybe_scalar) {
return JX.isArray(maybe_scalar) ? maybe_scalar : [maybe_scalar];
};
/**
* Checks whether a value is an array.
*
* JX.isArray(['an', 'array']); // Returns true.
* JX.isArray('Not an Array'); // Returns false.
*
* @param wild Any value.
* @return bool true if the argument is an array, false otherwise.
*
* @group util
*/
JX.isArray = Array.isArray || function(maybe_array) {
return Object.prototype.toString.call(maybe_array) == '[object Array]';
};
/**
* Copy properties from one object to another. If properties already exist, they
* are overwritten.
*
* var cat = {
* ears: 'clean',
* paws: 'clean',
* nose: 'DIRTY OH NOES'
* };
* var more = {
* nose: 'clean',
* tail: 'clean'
* };
*
* JX.copy(cat, more);
*
* // cat is now:
* // {
* // ears: 'clean',
* // paws: 'clean',
* // nose: 'clean',
* // tail: 'clean'
* // }
*
* NOTE: This function does not copy the ##toString## property or anything else
* which isn't enumerable or is somehow magic or just doesn't work. But it's
* usually what you want.
*
* @param obj Destination object, which properties should be copied to.
* @param obj Source object, which properties should be copied from.
* @return obj Modified destination object.
*
* @group util
*/
JX.copy = function(copy_dst, copy_src) {
for (var k in copy_src) {
copy_dst[k] = copy_src[k];
}
return copy_dst;
};
/**
* Create a function which invokes another function with a bound context and
* arguments (i.e., partial function application) when called; king of all
* functions.
*
* Bind performs context binding (letting you select what the value of ##this##
* will be when a function is invoked) and partial function application (letting
* you create some function which calls another one with bound arguments).
*
* = Context Binding =
*
* Normally, when you call ##obj.method()##, the magic ##this## object will be
* the ##obj## you invoked the method from. This can be undesirable when you
* need to pass a callback to another function. For instance:
*
* COUNTEREXAMPLE
* var dog = new JX.Dog();
* dog.barkNow(); // Makes the dog bark.
*
* JX.Stratcom.listen('click', 'bark', dog.barkNow); // Does not work!
*
* This doesn't work because ##this## is ##window## when the function is
* later invoked; @{method:JX.Stratcom.listen} does not know about the context
* object ##dog##. The solution is to pass a function with a bound context
* object:
*
* var dog = new JX.Dog();
* var bound_function = JX.bind(dog, dog.barkNow);
*
* JX.Stratcom.listen('click', 'bark', bound_function);
*
* ##bound_function## is a function with ##dog## bound as ##this##; ##this##
* will always be ##dog## when the function is called, no matter what
* property chain it is invoked from.
*
* You can also pass ##null## as the context argument to implicitly bind
* ##window##.
*
* = Partial Function Application =
*
* @{function:JX.bind} also performs partial function application, which allows
* you to bind one or more arguments to a function. For instance, if we have a
* simple function which adds two numbers:
*
* function add(a, b) { return a + b; }
* add(3, 4); // 7
*
* Suppose we want a new function, like this:
*
* function add3(b) { return 3 + b; }
* add3(4); // 7
*
* Instead of doing this, we can define ##add3()## in terms of ##add()## by
* binding the value ##3## to the ##a## argument:
*
* var add3_bound = JX.bind(null, add, 3);
* add3_bound(4); // 7
*
* Zero or more arguments may be bound in this way. This is particularly useful
* when using closures in a loop:
*
* COUNTEREXAMPLE
* for (var ii = 0; ii < button_list.length; ii++) {
* button_list[ii].onclick = function() {
* JX.log('You clicked button number '+ii+'!'); // Fails!
* };
* }
*
* This doesn't work; all the buttons report the highest number when clicked.
* This is because the local ##ii## is captured by the closure. Instead, bind
* the current value of ##ii##:
*
* var func = function(button_num) {
* JX.log('You clicked button number '+button_num+'!');
* }
* for (var ii = 0; ii < button_list.length; ii++) {
* button_list[ii].onclick = JX.bind(null, func, ii);
* }
*
* @param obj|null Context object to bind as ##this##.
* @param function Function to bind context and arguments to.
* @param ... Zero or more arguments to bind.
* @return function New function which invokes the original function with
* bound context and arguments when called.
*
* @group util
*/
JX.bind = function(context, func, more) {
if (__DEV__) {
if (typeof func != 'function') {
JX.$E(
'JX.bind(context, <yuck>, ...): '+
'Attempting to bind something that is not a function.');
}
}
var bound = JX.$A(arguments).slice(2);
if (func.bind) {
return func.bind.apply(func, [context].concat(bound));
}
return function() {
return func.apply(context || window, bound.concat(JX.$A(arguments)));
- }
+ };
};
/**
* "Bag of holding"; function that does nothing. Primarily, it's used as a
* placeholder when you want something to be callable but don't want it to
* actually have an effect.
*
* @return void
*
* @group util
*/
JX.bag = function() {
// \o\ \o/ /o/ woo dance party
};
/**
* Convert an object's keys into a list. For example:
*
* JX.keys({sun: 1, moon: 1, stars: 1}); // Returns: ['sun', 'moon', 'stars']
*
* @param obj Object to retrieve keys from.
* @return list List of keys.
*
* @group util
*/
JX.keys = Object.keys || function(obj) {
var r = [];
for (var k in obj) {
r.push(k);
}
return r;
};
/**
* Identity function; returns the argument unmodified. This is primarily useful
* as a placeholder for some callback which may transform its argument.
*
* @param wild Any value.
* @return wild The passed argument.
*
* @group util
*/
JX.id = function(any) {
return any;
};
JX.log = JX.bag;
if (__DEV__) {
if (!window.console || !window.console.log) {
if (window.opera && window.opera.postError) {
window.console = {log: function(m) { window.opera.postError(m); }};
} else {
window.console = {log: function(m) { }};
}
}
/**
* Print a message to the browser debugging console (like Firebug). This
* method exists only in ##__DEV__##.
*
* @param string Message to print to the browser debugging console.
* @return void
*
* @group util
*/
JX.log = function(message) {
window.console.log(message);
- }
+ };
window.alert = (function(native_alert) {
var recent_alerts = [];
var in_alert = false;
return function(msg) {
if (in_alert) {
JX.log(
'alert(...): '+
'discarded reentrant alert.');
return;
}
in_alert = true;
recent_alerts.push(JX.now());
if (recent_alerts.length > 3) {
recent_alerts.splice(0, recent_alerts.length - 3);
}
if (recent_alerts.length >= 3 &&
(recent_alerts[recent_alerts.length - 1] - recent_alerts[0]) < 5000) {
if (confirm(msg + "\n\nLots of alert()s recently. Kill them?")) {
window.alert = JX.bag;
}
} else {
// Note that we can't .apply() the IE6 version of this "function".
native_alert(msg);
}
in_alert = false;
- }
+ };
})(window.alert);
}
/**
* Date.now is the fastest timestamp function, but isn't supported by every
* browser. This gives the fastest version the environment can support.
* The wrapper function makes the getTime call even slower, but benchmarking
* shows it to be a marginal perf loss. Considering how small of a perf
* difference this makes overall, it's not really a big deal. The primary
* reason for this is to avoid hacky "just think of the byte savings" JS
* like +new Date() that has an unclear outcome for the unexposed.
*
* @return Int A Unix timestamp of the current time on the local machine
*/
JX.now = (Date.now || function() { return new Date().getTime(); });
diff --git a/webroot/rsrc/externals/javelin/ext/reactor/dom/RDOM.js b/webroot/rsrc/externals/javelin/ext/reactor/dom/RDOM.js
index c9cde5ae8b..48b7b9687f 100644
--- a/webroot/rsrc/externals/javelin/ext/reactor/dom/RDOM.js
+++ b/webroot/rsrc/externals/javelin/ext/reactor/dom/RDOM.js
@@ -1,406 +1,407 @@
/**
* Javelin Reactive functions to work with the DOM.
* @provides javelin-reactor-dom
* @requires javelin-dom
* javelin-dynval
+ * javelin-reactor
* javelin-reactornode
* javelin-install
* javelin-util
* @javelin
*/
JX.install('RDOM', {
statics : {
_time : null,
/**
* DynVal of the current time in milliseconds.
*/
time : function() {
if (JX.RDOM._time === null) {
var time = new JX.ReactorNode([], JX.id);
window.setInterval(function() {
time.forceSendValue(JX.now());
}, 100);
JX.RDOM._time = new JX.DynVal(time, JX.now());
}
return JX.RDOM._time;
},
/**
* Given a DynVal[String], return a DOM text node whose value tracks it.
*/
$DT : function(dyn_string) {
var node = document.createTextNode(dyn_string.getValueNow());
dyn_string.transform(function(s) { node.data = s; });
return node;
},
_recvEventPulses : function(node, event) {
var reactor_node = new JX.ReactorNode([], JX.id);
var no_path = null;
JX.DOM.listen(
node,
event,
no_path,
JX.bind(reactor_node, reactor_node.forceSendValue)
);
reactor_node.setGraphID(JX.DOM.uniqID(node));
return reactor_node;
},
_recvChangePulses : function(node) {
return JX.RDOM._recvEventPulses(node, 'change').transform(function() {
return node.value;
});
},
/**
* Sets up a bidirectional DynVal for a node.
* @param node :: DOM Node
* @param inPulsesFn :: DOM Node -> ReactorNode
* @param inDynValFn :: DOM Node -> ReactorNode -> DynVal
* @param outFn :: ReactorNode -> DOM Node
*/
_bidi : function(node, inPulsesFn, inDynValFn, outFn) {
var inPulses = inPulsesFn(node);
var inDynVal = inDynValFn(node, inPulses);
outFn(inDynVal.getChanges(), node);
inDynVal.getChanges().listen(inPulses);
return inDynVal;
},
/**
* ReactorNode[String] of the incoming values of a radio group.
* @param Array of DOM elements, all the radio buttons in a group.
*/
_recvRadioPulses : function(buttons) {
var ins = [];
for (var ii = 0; ii < buttons.length; ii++) {
ins.push(JX.RDOM._recvChangePulses(buttons[ii]));
}
return new JX.ReactorNode(ins, JX.id);
},
/**
* DynVal[String] of the incoming values of a radio group.
* pulses is a ReactorNode[String] of the incoming values of the group
*/
_recvRadio : function(buttons, pulses) {
var init = '';
for (var ii = 0; ii < buttons.length; ii++) {
if (buttons[ii].checked) {
init = buttons[ii].value;
break;
}
}
return new JX.DynVal(pulses, init);
},
/**
* Send the pulses from the ReactorNode[String] to the radio group.
* Sending an invalid value will result in a log message in __DEV__.
*/
_sendRadioPulses : function(rnode, buttons) {
return rnode.transform(function(val) {
var found;
if (__DEV__) {
found = false;
}
for (var ii = 0; ii < buttons.length; ii++) {
if (buttons[ii].value == val) {
buttons[ii].checked = true;
if (__DEV__) {
found = true;
}
}
}
if (__DEV__) {
if (!found) {
throw new Error("Mismatched radio button value");
}
}
});
},
/**
* Bidirectional DynVal[String] for a radio group.
* Sending an invalid value will result in a log message in __DEV__.
*/
radio : function(input) {
return JX.RDOM._bidi(
input,
JX.RDOM._recvRadioPulses,
JX.RDOM._recvRadio,
JX.RDOM._sendRadioPulses
);
},
/**
* ReactorNode[Boolean] of the values of the checkbox when it changes.
*/
_recvCheckboxPulses : function(checkbox) {
return JX.RDOM._recvChangePulses(checkbox).transform(function(val) {
return Boolean(val);
});
},
/**
* DynVal[Boolean] of the value of a checkbox.
*/
_recvCheckbox : function(checkbox, pulses) {
return new JX.DynVal(pulses, Boolean(checkbox.checked));
},
/**
* Send the pulses from the ReactorNode[Boolean] to the checkbox
*/
_sendCheckboxPulses : function(rnode, checkbox) {
return rnode.transform(function(val) {
if (__DEV__) {
if (!(val === true || val === false)) {
throw new Error("Send boolean values to checkboxes.");
}
}
checkbox.checked = val;
});
},
/**
* Bidirectional DynVal[Boolean] for a checkbox.
*/
checkbox : function(input) {
return JX.RDOM._bidi(
input,
JX.RDOM._recvCheckboxPulses,
JX.RDOM._recvCheckbox,
JX.RDOM._sendCheckboxPulses
);
},
/**
* ReactorNode[String] of the changing values of a text input.
*/
_recvInputPulses : function(input) {
// This misses advanced changes like paste events.
var live_changes = [
JX.RDOM._recvChangePulses(input),
JX.RDOM._recvEventPulses(input, 'keyup'),
JX.RDOM._recvEventPulses(input, 'keypress'),
JX.RDOM._recvEventPulses(input, 'keydown')
];
return new JX.ReactorNode(live_changes, function() {
return input.value;
});
},
/**
* DynVal[String] of the value of a text input.
*/
_recvInput : function(input, pulses) {
return new JX.DynVal(pulses, input.value);
},
/**
* Send the pulses from the ReactorNode[String] to the input
*/
_sendInputPulses : function(rnode, input) {
var result = rnode.transform(function(val) {
input.value = val;
});
result.setGraphID(JX.DOM.uniqID(input));
return result;
},
/**
* Bidirectional DynVal[String] for a text input.
*/
input : function(input) {
return JX.RDOM._bidi(
input,
JX.RDOM._recvInputPulses,
JX.RDOM._recvInput,
JX.RDOM._sendInputPulses
);
},
/**
* ReactorNode[String] of the incoming changes in value of a select element.
*/
_recvSelectPulses : function(select) {
return JX.RDOM._recvChangePulses(select);
},
/**
* DynVal[String] of the value of a select element.
*/
_recvSelect : function(select, pulses) {
return new JX.DynVal(pulses, select.value);
},
/**
* Send the pulses from the ReactorNode[String] to the select.
* Sending an invalid value will result in a log message in __DEV__.
*/
_sendSelectPulses : function(rnode, select) {
return rnode.transform(function(val) {
select.value = val;
if (__DEV__) {
if (select.value !== val) {
throw new Error("Mismatched select value");
}
}
});
},
/**
* Bidirectional DynVal[String] for the value of a select.
*/
select : function(select) {
return JX.RDOM._bidi(
select,
JX.RDOM._recvSelectPulses,
JX.RDOM._recvSelect,
JX.RDOM._sendSelectPulses
);
},
/**
* ReactorNode[undefined] that fires when a button is clicked.
*/
clickPulses : function(button) {
return JX.RDOM._recvEventPulses(button, 'click').transform(function() {
return null;
});
},
/**
* ReactorNode[Boolean] of whether the mouse is over a target.
*/
_recvIsMouseOverPulses : function(target) {
var mouseovers = JX.RDOM._recvEventPulses(target, 'mouseover').transform(
function() {
return true;
});
var mouseouts = JX.RDOM._recvEventPulses(target, 'mouseout').transform(
function() {
return false;
});
return new JX.ReactorNode([mouseovers, mouseouts], JX.id);
},
/**
* DynVal[Boolean] of whether the mouse is over a target.
*/
isMouseOver : function(target) {
// Not worth it to initialize this properly.
return new JX.DynVal(JX.RDOM._recvIsMouseOverPulses(target), false);
},
/**
* ReactorNode[Boolean] of whether an element has the focus.
*/
_recvHasFocusPulses : function(target) {
var focuses = JX.RDOM._recvEventPulses(target, 'focus').transform(
function() {
return true;
});
var blurs = JX.RDOM._recvEventPulses(target, 'blur').transform(
function() {
return false;
});
return new JX.ReactorNode([focuses, blurs], JX.id);
},
/**
* DynVal[Boolean] of whether an element has the focus.
*/
_recvHasFocus : function(target) {
var is_focused_now = (target === document.activeElement);
return new JX.DynVal(JX.RDOM._recvHasFocusPulses(target), is_focused_now);
},
_sendHasFocusPulses : function(rnode, target) {
rnode.transform(function(should_focus) {
if (should_focus) {
target.focus();
} else {
target.blur();
}
return should_focus;
});
},
/**
* Bidirectional DynVal[Boolean] of whether an element has the focus.
*/
hasFocus : function(target) {
return JX.RDOM._bidi(
target,
JX.RDOM._recvHasFocusPulses,
JX.RDOM._recvHasFocus,
JX.RDOM._sendHasFocusPulses
);
},
/**
* Send a CSS class from a DynVal to a node
*/
sendClass : function(dynval, node, className) {
return dynval.transform(function(add) {
JX.DOM.alterClass(node, className, add);
});
},
/**
* Dynamically attach a set of DynVals to a DOM node's properties as
* specified by props.
* props: {left: someDynVal, style: {backgroundColor: someOtherDynVal}}
*/
sendProps : function(node, props) {
var dynvals = [];
var keys = [];
var style_keys = [];
for (var key in props) {
keys.push(key);
if (key === 'style') {
for (var style_key in props[key]) {
style_keys.push(style_key);
dynvals.push(props[key][style_key]);
node.style[style_key] = props[key][style_key].getValueNow();
}
} else {
dynvals.push(props[key]);
node[key] = props[key].getValueNow();
}
}
return JX.Reactor.lift(JX.bind(null, function(keys, style_keys, node) {
var args = JX.$A(arguments).slice(3);
for (var ii = 0; ii < args.length; ii++) {
if (keys[ii] === 'style') {
for (var jj = 0; jj < style_keys.length; jj++) {
node.style[style_keys[jj]] = args[ii];
ii++;
}
ii--;
} else {
node[keys[ii]] = args[ii];
}
}
}, keys, style_keys, node), dynvals);
}
}
});
diff --git a/webroot/rsrc/externals/javelin/ext/view/HTMLView.js b/webroot/rsrc/externals/javelin/ext/view/HTMLView.js
index 115aa4fff8..aea6f7c7bd 100644
--- a/webroot/rsrc/externals/javelin/ext/view/HTMLView.js
+++ b/webroot/rsrc/externals/javelin/ext/view/HTMLView.js
@@ -1,136 +1,138 @@
/**
* Dumb HTML views. Mostly to demonstrate how the visitor pattern over these
* views works, as driven by validation. I'm not convinced it's actually a good
* idea to do validation.
*
* @provides javelin-view-html
* @requires javelin-install
- * javelin-view
+ * javelin-dom
+ * javelin-view-visitor
+ * javelin-util
*/
JX.install('HTMLView', {
extend: 'View',
members : {
render: function(rendered_children) {
return JX.$N(this.getName(), this.getAllAttributes(), rendered_children);
},
validate: function() {
this.accept(JX.HTMLView.getValidatingVisitor());
}
},
statics: {
getValidatingVisitor: function() {
return new JX.ViewVisitor(JX.HTMLView.validate);
},
validate: function(view, children) {
var spec = this._getHTMLSpec();
- if (!view.getName() in spec) {
+ if (!(view.getName() in spec)) {
throw new Error("invalid tag");
}
var tag_spec = spec[view.getName()];
var attrs = view.getAllAttributes();
for (var attr in attrs) {
if (!(attr in tag_spec)) {
throw new Error("invalid attr");
}
var validator = tag_spec[attr];
if (typeof validator === "function") {
return validator(attrs[attr]);
}
}
return true;
},
_validateRel: function(target) {
return target in {
"_blank": 1,
"_self": 1,
"_parent": 1,
"_top": 1
};
},
_getHTMLSpec: function() {
var attrs_any_can_have = {
className: 1,
id: 1,
sigil: 1
};
var form_elem_attrs = {
name: 1,
value: 1
};
var spec = {
a: { href: 1, target: JX.HTMLView._validateRel },
b: {},
blockquote: {},
br: {},
button: JX.copy({}, form_elem_attrs),
canvas: {},
code: {},
dd: {},
div: {},
dl: {},
dt: {},
em: {},
embed: {},
fieldset: {},
form: { type: 1 },
h1: {},
h2: {},
h3: {},
h4: {},
h5: {},
h6: {},
hr: {},
i: {},
iframe: { src: 1 },
img: { src: 1, alt: 1 },
input: JX.copy({}, form_elem_attrs),
label: {'for': 1},
li: {},
ol: {},
optgroup: {},
option: JX.copy({}, form_elem_attrs),
p: {},
pre: {},
q: {},
select: {},
span: {},
strong: {},
sub: {},
sup: {},
table: {},
tbody: {},
td: {},
textarea: {},
tfoot: {},
th: {},
thead: {},
tr: {},
ul: {}
};
for (var k in spec) {
JX.copy(spec[k], attrs_any_can_have);
}
return spec;
},
registerToInterpreter: function(view_interpreter) {
var spec = this._getHTMLSpec();
for (var tag in spec) {
view_interpreter.register(tag, JX.HTMLView);
}
return view_interpreter;
}
}
});
diff --git a/webroot/rsrc/externals/javelin/ext/view/View.js b/webroot/rsrc/externals/javelin/ext/view/View.js
index a016ce531a..39d608a715 100644
--- a/webroot/rsrc/externals/javelin/ext/view/View.js
+++ b/webroot/rsrc/externals/javelin/ext/view/View.js
@@ -1,189 +1,192 @@
/**
* A View is a composable wrapper on JX.$N, allowing abstraction of higher-order
* views and a consistent pattern of parameterization. It is intended
* to be used either directly or as a building block for a syntactic sugar layer
* for concise expression of markup patterns.
*
* @provides javelin-view
* @requires javelin-install
* javelin-util
*/
JX.install('View', {
construct : function(attrs, children) {
this._attributes = JX.copy({}, this.getDefaultAttributeValues());
JX.copy(this._attributes, attrs);
this._rawChildren = {};
this._childKeys = [];
if (children) {
this.addChildren(JX.$AX(children));
}
this.setName(this.__class__.__readable__);
},
events: [
'change'
],
properties: {
'name': null
},
members : {
_attributes : null,
_rawChildren : null,
_childKeys: null, // keys of rawChildren, kept ordered.
_nextChildKey: 0, // next key to use for a new child
/*
* Don't override.
* TODO: Strongly typed attribute access (getIntAttr, getStringAttr...)?
*/
getAttr : function(attrName) {
return this._attributes[attrName];
},
/*
* Don't override.
*/
multisetAttr : function(attrs) {
JX.copy(this._attributes, attrs);
this.invoke('change');
return this;
},
/*
* Don't override.
*/
setAttr : function(attrName, value) {
this._attributes[attrName] = value;
this.invoke('change');
return this;
},
/*
* Child views can override to specify default values for attributes.
*/
getDefaultAttributeValues : function() {
return {};
},
/**
* Don't override.
*/
getAllAttributes: function() {
return JX.copy({}, this._attributes);
},
/**
* Get the children. Don't override.
*/
getChildren : function() {
var result = [];
var should_repack = false;
- for(var ii = 0; ii < this._childKeys.length; ii++) {
- var key = this._childKeys[ii];
+ var ii;
+ var key;
+
+ for (ii = 0; ii < this._childKeys.length; ii++) {
+ key = this._childKeys[ii];
if (this._rawChildren[key] === undefined) {
should_repack = true;
} else {
result.push(this._rawChildren[key]);
}
}
if (should_repack) {
var new_child_keys = [];
- for(var ii = 0; ii < this._childKeys.length; ii++) {
- var key = this._childKeys[ii];
+ for (ii = 0; ii < this._childKeys.length; ii++) {
+ key = this._childKeys[ii];
if (this._rawChildren[key] !== undefined) {
new_child_keys.push(key);
}
}
this._childKeys = new_child_keys;
}
return result;
},
/**
* Add children to the view. Returns array of removal handles.
* Don't override.
*/
addChildren : function(children) {
var result = [];
for (var ii = 0; ii < children.length; ii++) {
result.push(this._addChild(children[ii]));
}
this.invoke('change');
return result;
},
/**
* Add a single child view to the view.
* Returns a removal handle, i.e. an object that has a method remove(),
* that removes the added child from the view.
*
* Don't override.
*/
addChild: function(child) {
var result = this._addChild(child);
this.invoke('change');
return result;
},
_addChild: function(child) {
var key = this._nextChildKey++;
this._rawChildren[key] = child;
this._childKeys.push(key);
return {
remove: JX.bind(this, this._removeChild, key)
};
},
_removeChild: function(child_key) {
delete this._rawChildren[child_key];
this.invoke('change');
},
/**
* Accept visitors. This allows adding new behaviors to Views without
* having to change View classes themselves.
*
* This implements a post-order traversal over the tree of views. Children
* are processed before parents, and for convenience the results of the
* visitor on the children are passed to it when processing the parent.
*
* The visitor parameter is a callable which receives two parameters.
* The first parameter is the view to visit. The second parameter is an
* array of the results of visiting the view's children.
*
* Don't override.
*/
accept: function(visitor) {
var results = [];
var children = this.getChildren();
for(var ii = 0; ii < children.length; ii++) {
var result;
if (children[ii].accept) {
result = children[ii].accept(visitor);
} else {
result = children[ii];
}
results.push(result);
}
return visitor(this, results);
},
/**
* Given the already-rendered children, return the rendered result of
* this view.
* By default, just pass the children through.
*/
render: function(rendered_children) {
return rendered_children;
}
}
});
diff --git a/webroot/rsrc/externals/javelin/ext/view/ViewInterpreter.js b/webroot/rsrc/externals/javelin/ext/view/ViewInterpreter.js
index cd89d68676..743071e101 100644
--- a/webroot/rsrc/externals/javelin/ext/view/ViewInterpreter.js
+++ b/webroot/rsrc/externals/javelin/ext/view/ViewInterpreter.js
@@ -1,71 +1,71 @@
/**
* Experimental interpreter for nice views.
* This is CoffeeScript:
*
* d = declare
* selectable: false
* boxOrientation: Orientation.HORIZONTAL
* additionalClasses: ['some-css-class']
* MultiAvatar ref: 'avatars'
* div
* flex: 1
* div(
* span className: 'some-css-class', ref: 'actorTargetLine'
* span className: 'message-css', ref: 'message'
* )
*
* div
* boxOrientation: Orientation.HORIZONTAL
* className: 'attachment-css-class'
* div
* className: 'attachment-image-css-class'
* ref: 'attachmentImageContainer'
* boxOrientation: Orientation.HORIZONTAL
* div className: 'inline attachment-text', ref: 'attachmentText',
* div
* className: 'attachment-title'
* ref: 'attachmentTitle'
* flex: 1
* div
* className: 'attachment-subtitle'
* ref: 'attachmentSubtitle'
* flex: 1
* div className: 'clear'
* MiniUfi ref: 'miniUfi'
* FeedbackFlyout ref: 'feedbackFlyout'
*
* It renders to nested function calls of the form:
* view({....options...}, child1, child2, ...);
*
* This view interpreter is meant to make it work.
*
* @provides javelin-view-interpreter
* @requires javelin-view
* javelin-install
- *
+ * javelin-dom
*/
JX.install('ViewInterpreter', {
members : {
register : function(name, view_cls) {
this[name] = function(/* [properties, ]children... */) {
var properties = arguments[0] || {};
var children = Array.prototype.slice.call(arguments, 1);
// Passing properties is optional
if (properties instanceof JX.View ||
properties instanceof JX.HTML ||
properties.nodeType ||
typeof properties === "string") {
children.unshift(properties);
properties = {};
}
var result = new view_cls(properties).setName(name);
result.addChildren(children);
return result;
- }
+ };
}
}
});
diff --git a/webroot/rsrc/externals/javelin/ext/view/ViewPlaceholder.js b/webroot/rsrc/externals/javelin/ext/view/ViewPlaceholder.js
index a0c3d67797..7a2b79cfc2 100644
--- a/webroot/rsrc/externals/javelin/ext/view/ViewPlaceholder.js
+++ b/webroot/rsrc/externals/javelin/ext/view/ViewPlaceholder.js
@@ -1,103 +1,105 @@
/**
* Initialize a client-side view from the server. The main idea here is to
* give server-side views a way to integrate with client-side views.
*
* The idea is that a client-side view will have an accompanying
* thin server-side component. The server-side component renders a placeholder
* element in the document, and then it will invoke this behavior to initialize
* the view into the placeholder.
*
* Because server-side views may be nested, we need to add complexity to
* handle nesting properly.
*
* Assuming a server-side view design that looks like hierarchical views,
* we have to handle structures like
*
* <server:component>
* <client:component id="1">
* <server:component>
* <client:component id="2">
* </client:component>
* </server:component>
* </client:component>
* </server:component>
*
* This leads to a problem: Client component 1 needs to initialize the behavior
* with its children, which includes client component 2. So client component
* 2 must be rendered first. When client component 2 is rendered, it will also
* initialize a copy of this behavior. If behaviors are run in the order they
* are initialized, the child component will run before the parent, and its
* placeholder won't exist yet.
*
* To solve this problem, placeholder behaviors are initialized with the token
* of a containing view that must be rendered first (if any) and a token
* representing it for its own children to depend on. This means the server code
* is free to call initBehavior in any order.
*
* In Phabricator, AphrontJavelinView demonstrates how to handle this correctly.
*
* config: {
* id: Node id to replace.
* view: class of view, without the 'JX.' prefix.
* params: view parameters
* children: messy and loud, cute when drunk
* trigger_id: id of containing view that must be rendered first
* }
*
* @provides javelin-behavior-view-placeholder
* @requires javelin-behavior
* javelin-dom
* javelin-view-renderer
+ * javelin-install
*/
JX.behavior('view-placeholder', function(config, statics) {
JX.ViewPlaceholder.register(config.trigger_id, config.id, function() {
var replace = JX.$(config.id);
var children = config.children;
if (typeof children === "string") {
children = JX.$H(children);
}
var view = new JX[config.view](config.params, children);
var rendered = JX.ViewRenderer.render(view);
JX.DOM.replace(replace, rendered);
});
});
JX.install('ViewPlaceholder', {
statics: {
register: function(wait_on_token, token, cb) {
var ready_q = [];
+ var waiting;
if (!wait_on_token || wait_on_token in JX.ViewPlaceholder.ready) {
ready_q.push({token: token, cb: cb});
} else {
- var waiting = JX.ViewPlaceholder.waiting;
+ waiting = JX.ViewPlaceholder.waiting;
waiting[wait_on_token] = waiting[wait_on_token] || [];
waiting[wait_on_token].push({token: token, cb: cb});
}
while(ready_q.length) {
var ready = ready_q.shift();
- var waiting = JX.ViewPlaceholder.waiting[ready.token];
+ waiting = JX.ViewPlaceholder.waiting[ready.token];
if (waiting) {
for (var ii = 0; ii < waiting.length; ii++) {
ready_q.push(waiting[ii]);
}
delete JX.ViewPlaceholder.waiting[ready.token];
}
ready.cb();
JX.ViewPlaceholder.ready[token] = true;
}
},
ready: {},
waiting: {}
}
});
diff --git a/webroot/rsrc/externals/javelin/ext/view/ViewRenderer.js b/webroot/rsrc/externals/javelin/ext/view/ViewRenderer.js
index f919484448..3f11a3bec0 100644
--- a/webroot/rsrc/externals/javelin/ext/view/ViewRenderer.js
+++ b/webroot/rsrc/externals/javelin/ext/view/ViewRenderer.js
@@ -1,19 +1,20 @@
/**
* @provides javelin-view-renderer
* @requires javelin-install
+ * javelin-util
*/
JX.install('ViewRenderer', {
members: {
visit: function(view, children) {
return view.render(children);
}
},
statics: {
render: function(view) {
var renderer = new JX.ViewRenderer();
return view.accept(JX.bind(renderer, renderer.visit));
}
}
});
diff --git a/webroot/rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js b/webroot/rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js
index a4d874365a..1e8729e5c4 100644
--- a/webroot/rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js
+++ b/webroot/rsrc/externals/javelin/ext/view/__tests__/ViewRenderer.js
@@ -1,25 +1,25 @@
/**
* @requires javelin-view-renderer
* javelin-view
*/
describe('JX.ViewRenderer', function() {
it('should render children then parent', function() {
var child_rendered = false;
var child_rendered_first = false;
var child = new JX.View({});
var parent = new JX.View({});
parent.addChild(child);
child.render = function(_) {
child_rendered = true;
- }
+ };
parent.render = function(rendered_children) {
child_rendered_first = child_rendered;
- }
+ };
JX.ViewRenderer.render(parent);
expect(child_rendered_first).toBe(true);
});
});
diff --git a/webroot/rsrc/externals/javelin/lib/DOM.js b/webroot/rsrc/externals/javelin/lib/DOM.js
index b2bf50b65c..95496f4887 100644
--- a/webroot/rsrc/externals/javelin/lib/DOM.js
+++ b/webroot/rsrc/externals/javelin/lib/DOM.js
@@ -1,894 +1,898 @@
/**
* @requires javelin-magical-init
* javelin-install
* javelin-util
* javelin-vector
* javelin-stratcom
* @provides javelin-dom
*
* @javelin-installs JX.$
* @javelin-installs JX.$N
* @javelin-installs JX.$H
*
* @javelin
*/
/**
* Select an element by its "id" attribute, like ##document.getElementById()##.
* For example:
*
* var node = JX.$('some_id');
*
* This will select the node with the specified "id" attribute:
*
* LANG=HTML
* <div id="some_id">...</div>
*
* If the specified node does not exist, @{JX.$()} will throw an exception.
*
* For other ways to select nodes from the document, see @{JX.DOM.scry()} and
* @{JX.DOM.find()}.
*
* @param string "id" attribute to select from the document.
* @return Node Node with the specified "id" attribute.
*
* @group dom
*/
JX.$ = function(id) {
if (__DEV__) {
if (!id) {
JX.$E('Empty ID passed to JX.$()!');
}
}
var node = document.getElementById(id);
if (!node || (node.id != id)) {
if (__DEV__) {
if (node && (node.id != id)) {
JX.$E(
'JX.$("'+id+'"): '+
'document.getElementById() returned an element without the '+
'correct ID. This usually means that the element you are trying '+
'to select is being masked by a form with the same value in its '+
'"name" attribute.');
}
}
JX.$E("JX.$('" + id + "') call matched no nodes.");
}
return node;
};
/**
* Upcast a string into an HTML object so it is treated as markup instead of
* plain text. See @{JX.$N} for discussion of Javelin's security model. Every
* time you call this function you potentially open up a security hole. Avoid
* its use wherever possible.
*
* This class intentionally supports only a subset of HTML because many browsers
* named "Internet Explorer" have awkward restrictions around what they'll
* accept for conversion to document fragments. Alter your datasource to emit
* valid HTML within this subset if you run into an unsupported edge case. All
* the edge cases are crazy and you should always be reasonably able to emit
* a cohesive tag instead of an unappendable fragment.
*
* You may use @{JX.$H} as a shortcut for creating new JX.HTML instances:
*
* JX.$N('div', {}, some_html_blob); // Treat as string (safe)
* JX.$N('div', {}, JX.$H(some_html_blob)); // Treat as HTML (unsafe!)
*
* @task build String into HTML
* @task nodes HTML into Nodes
*
* @group dom
*/
JX.install('HTML', {
construct : function(str) {
if (str instanceof JX.HTML) {
this._content = str._content;
return;
}
if (__DEV__) {
if ((typeof str !== 'string') && (!str || !str.match)) {
JX.$E(
'new JX.HTML(<empty?>): ' +
'call initializes an HTML object with an empty value.');
}
var tags = ['legend', 'thead', 'tbody', 'tfoot', 'column', 'colgroup',
'caption', 'tr', 'th', 'td', 'option'];
var evil_stuff = new RegExp('^\\s*<(' + tags.join('|') + ')\\b', 'i');
- var match = null;
- if (match = str.match(evil_stuff)) {
+ var match = str.match(evil_stuff);
+ if (match) {
JX.$E(
'new JX.HTML("<' + match[1] + '>..."): ' +
'call initializes an HTML object with an invalid partial fragment ' +
'and can not be converted into DOM nodes. The enclosing tag of an ' +
'HTML content string must be appendable to a document fragment. ' +
'For example, <table> is allowed but <tr> or <tfoot> are not.');
}
var really_evil = /<script\b/;
if (str.match(really_evil)) {
JX.$E(
'new JX.HTML("...<script>..."): ' +
'call initializes an HTML object with an embedded script tag! ' +
'Are you crazy?! Do NOT do this!!!');
}
var wont_work = /<object\b/;
if (str.match(wont_work)) {
JX.$E(
'new JX.HTML("...<object>..."): ' +
'call initializes an HTML object with an embedded <object> tag. IE ' +
'will not do the right thing with this.');
}
// TODO(epriestley): May need to deny <option> more broadly, see
// http://support.microsoft.com/kb/829907 and the whole mess in the
// heavy stack. But I seem to have gotten away without cloning into the
// documentFragment below, so this may be a nonissue.
}
this._content = str;
},
members : {
_content : null,
/**
* Convert the raw HTML string into a DOM node tree.
*
* @task nodes
* @return DocumentFragment A document fragment which contains the nodes
* corresponding to the HTML string you provided.
*/
getFragment : function() {
var wrapper = JX.$N('div');
wrapper.innerHTML = this._content;
var fragment = document.createDocumentFragment();
while (wrapper.firstChild) {
// TODO(epriestley): Do we need to do a bunch of cloning junk here?
// See heavy stack. I'm disconnecting the nodes instead; this seems
// to work but maybe my test case just isn't extensive enough.
fragment.appendChild(wrapper.removeChild(wrapper.firstChild));
}
return fragment;
}
}
});
/**
* Build a new HTML object from a trustworthy string. JX.$H is a shortcut for
* creating new JX.HTML instances.
*
* @task build
* @param string A string which you want to be treated as HTML, because you
* know it is from a trusted source and any data in it has been
* properly escaped.
* @return JX.HTML HTML object, suitable for use with @{JX.$N}.
*
* @group dom
*/
JX.$H = function(str) {
return new JX.HTML(str);
};
/**
* Create a new DOM node with attributes and content.
*
* var link = JX.$N('a');
*
* This creates a new, empty anchor tag without any attributes. The equivalent
* markup would be:
*
* LANG=HTML
* <a />
*
* You can also specify attributes by passing a dictionary:
*
* JX.$N('a', {name: 'anchor'});
*
* This is equivalent to:
*
* LANG=HTML
* <a name="anchor" />
*
* Additionally, you can specify content:
*
* JX.$N(
* 'a',
* {href: 'http://www.javelinjs.com'},
* 'Visit the Javelin Homepage');
*
* This is equivalent to:
*
* LANG=HTML
* <a href="http://www.javelinjs.com">Visit the Javelin Homepage</a>
*
* If you only want to specify content, you can omit the attribute parameter.
* That is, these calls are equivalent:
*
* JX.$N('div', {}, 'Lorem ipsum...'); // No attributes.
* JX.$N('div', 'Lorem ipsum...') // Same as above.
*
* Both are equivalent to:
*
* LANG=HTML
* <div>Lorem ipsum...</div>
*
* Note that the content is treated as plain text, not HTML. This means it is
* safe to use untrusted strings:
*
* JX.$N('div', '<script src="evil.com" />');
*
* This is equivalent to:
*
* LANG=HTML
* <div>&lt;script src="evil.com" /&gt;</div>
*
* That is, the content will be properly escaped and will not create a
* vulnerability. If you want to set HTML content, you can use @{JX.HTML}:
*
* JX.$N('div', JX.$H(some_html));
*
* **This is potentially unsafe**, so make sure you understand what you're
* doing. You should usually avoid passing HTML around in string form. See
* @{JX.HTML} for discussion.
*
* You can create new nodes with a Javelin sigil (and, optionally, metadata) by
* providing "sigil" and "meta" keys in the attribute dictionary.
*
* @param string Tag name, like 'a' or 'div'.
* @param dict|string|@{JX.HTML}? Property dictionary, or content if you don't
* want to specify any properties.
* @param string|@{JX.HTML}? Content string (interpreted as plain text)
* or @{JX.HTML} object (interpreted as HTML,
* which may be dangerous).
* @return Node New node with whatever attributes and
* content were specified.
*
* @group dom
*/
JX.$N = function(tag, attr, content) {
if (typeof content == 'undefined' &&
(typeof attr != 'object' || attr instanceof JX.HTML)) {
content = attr;
attr = {};
}
if (__DEV__) {
if (tag.toLowerCase() != tag) {
JX.$E(
'$N("'+tag+'", ...): '+
'tag name must be in lower case; '+
'use "'+tag.toLowerCase()+'", not "'+tag+'".');
}
}
var node = document.createElement(tag);
if (attr.style) {
JX.copy(node.style, attr.style);
delete attr.style;
}
if (attr.sigil) {
JX.Stratcom.addSigil(node, attr.sigil);
delete attr.sigil;
}
if (attr.meta) {
JX.Stratcom.addData(node, attr.meta);
delete attr.meta;
}
if (__DEV__) {
if (('metadata' in attr) || ('data' in attr)) {
JX.$E(
'$N(' + tag + ', ...): ' +
'use the key "meta" to specify metadata, not "data" or "metadata".');
}
}
JX.copy(node, attr);
if (content) {
JX.DOM.setContent(node, content);
}
return node;
};
/**
* Query and update the DOM. Everything here is static, this is essentially
* a collection of common utility functions.
*
* @task stratcom Attaching Event Listeners
* @task content Changing DOM Content
* @task nodes Updating Nodes
* @task serialize Serializing Forms
* @task test Testing DOM Properties
* @task convenience Convenience Methods
* @task query Finding Nodes in the DOM
* @task view Changing View State
*
* @group dom
*/
JX.install('DOM', {
statics : {
_autoid : 0,
_uniqid : 0,
_metrics : {},
/* -( Changing DOM Content )----------------------------------------------- */
/**
* Set the content of some node. This uses the same content semantics as
* other Javelin content methods, see @{function:JX.$N} for a detailed
* explanation. Previous content will be replaced: you can also
* @{method:prependContent} or @{method:appendContent}.
*
* @param Node Node to set content of.
* @param mixed Content to set.
* @return void
* @task content
*/
setContent : function(node, content) {
if (__DEV__) {
if (!JX.DOM.isNode(node)) {
JX.$E(
'JX.DOM.setContent(<yuck>, ...): '+
'first argument must be a DOM node.');
}
}
while (node.firstChild) {
JX.DOM.remove(node.firstChild);
}
JX.DOM.appendContent(node, content);
},
/**
* Prepend content to some node. This method uses the same content semantics
* as other Javelin methods, see @{function:JX.$N} for an explanation. You
* can also @{method:setContent} or @{method:appendContent}.
*
* @param Node Node to prepend content to.
* @param mixed Content to prepend.
* @return void
* @task content
*/
prependContent : function(node, content) {
if (__DEV__) {
if (!JX.DOM.isNode(node)) {
JX.$E(
'JX.DOM.prependContent(<junk>, ...): '+
'first argument must be a DOM node.');
}
}
this._insertContent(node, content, this._mechanismPrepend, true);
},
/**
* Append content to some node. This method uses the same content semantics
* as other Javelin methods, see @{function:JX.$N} for an explanation. You
* can also @{method:setContent} or @{method:prependContent}.
*
* @param Node Node to append the content of.
* @param mixed Content to append.
* @return void
* @task content
*/
appendContent : function(node, content) {
if (__DEV__) {
if (!JX.DOM.isNode(node)) {
JX.$E(
'JX.DOM.appendContent(<bleh>, ...): '+
'first argument must be a DOM node.');
}
}
this._insertContent(node, content, this._mechanismAppend);
},
/**
* Internal, add content to a node by prepending.
*
* @param Node Node to prepend content to.
* @param Node Node to prepend.
* @return void
* @task content
*/
_mechanismPrepend : function(node, content) {
node.insertBefore(content, node.firstChild);
},
/**
* Internal, add content to a node by appending.
*
* @param Node Node to append content to.
* @param Node Node to append.
* @task content
*/
_mechanismAppend : function(node, content) {
node.appendChild(content);
},
/**
* Internal, add content to a node using some specified mechanism.
*
* @param Node Node to add content to.
* @param mixed Content to add.
* @param function Callback for actually adding the nodes.
* @param bool True if array elements should be passed to the mechanism
* in reverse order, i.e. the mechanism prepends nodes.
* @return void
* @task content
*/
_insertContent : function(parent, content, mechanism, reverse) {
if (JX.isArray(content)) {
if (reverse) {
content = [].concat(content).reverse();
}
for (var ii = 0; ii < content.length; ii++) {
JX.DOM._insertContent(parent, content[ii], mechanism, reverse);
}
} else {
var type = typeof content;
if (content instanceof JX.HTML) {
content = content.getFragment();
} else if (type == 'string' || type == 'number') {
content = document.createTextNode(content);
}
if (__DEV__) {
if (content && !content.nodeType) {
JX.$E(
'JX.DOM._insertContent(<node>, ...): '+
'second argument must be a string, a number, ' +
'a DOM node or a JX.HTML instance');
}
}
content && mechanism(parent, content);
}
},
/* -( Updating Nodes )----------------------------------------------------- */
/**
* Remove a node from its parent, so it is no longer a child of any other
* node.
*
* @param Node Node to remove.
* @return Node The node.
* @task nodes
*/
remove : function(node) {
node.parentNode && JX.DOM.replace(node, null);
return node;
},
/**
* Replace a node with some other piece of content. This method obeys
* Javelin content semantics, see @{function:JX.$N} for an explanation.
* You can also @{method:setContent}, @{method:prependContent}, or
* @{method:appendContent}.
*
* @param Node Node to replace.
* @param mixed Content to replace it with.
* @return Node the original node.
* @task nodes
*/
replace : function(node, replacement) {
if (__DEV__) {
if (!node.parentNode) {
JX.$E(
'JX.DOM.replace(<node>, ...): '+
'node has no parent node, so it can not be replaced.');
}
}
var mechanism;
if (node.nextSibling) {
mechanism = JX.bind(node.nextSibling, function(parent, content) {
parent.insertBefore(content, this);
});
} else {
mechanism = this._mechanismAppend;
}
var parent = node.parentNode;
parent.removeChild(node);
this._insertContent(parent, replacement, mechanism);
return node;
},
/* -( Serializing Froms )-------------------------------------------------- */
/**
* Converts a form into a list of <name, value> pairs.
*
* Note: This function explicity does not match for submit inputs as there
* could be multiple in a form. It's the caller's obligation to add the
* submit input value if desired.
*
* @param Node The form element to convert into a list of pairs.
* @return List A list of <name, value> pairs.
* @task serialize
*/
convertFormToListOfPairs : function(form) {
var elements = form.getElementsByTagName('*');
var data = [];
for (var ii = 0; ii < elements.length; ++ii) {
if (!elements[ii].name) {
continue;
}
if (elements[ii].disabled) {
continue;
}
var type = elements[ii].type;
var tag = elements[ii].tagName;
if ((type in {radio: 1, checkbox: 1} && elements[ii].checked) ||
type in {text: 1, hidden: 1, password: 1, email: 1, tel: 1,
number: 1} ||
tag in {TEXTAREA: 1, SELECT: 1}) {
data.push([elements[ii].name, elements[ii].value]);
}
}
return data;
},
/**
* Converts a form into a dictionary mapping input names to values. This
* will overwrite duplicate inputs in an undefined way.
*
* @param Node The form element to convert into a dictionary.
* @return Dict A dictionary of form values.
* @task serialize
*/
convertFormToDictionary : function(form) {
var data = {};
var pairs = JX.DOM.convertFormToListOfPairs(form);
for (var ii = 0; ii < pairs.length; ii++) {
data[pairs[ii][0]] = pairs[ii][1];
}
return data;
},
/* -( Testing DOM Properties )--------------------------------------------- */
/**
* Test if an object is a valid Node.
*
* @param wild Something which might be a Node.
* @return bool True if the parameter is a DOM node.
* @task test
*/
isNode : function(node) {
return !!(node && node.nodeName && (node !== window));
},
/**
* Test if an object is a node of some specific (or one of several) types.
* For example, this tests if the node is an ##<input />##, ##<select />##,
* or ##<textarea />##.
*
* JX.DOM.isType(node, ['input', 'select', 'textarea']);
*
* @param wild Something which might be a Node.
* @param string|list One or more tags which you want to test for.
* @return bool True if the object is a node, and it's a node of one
* of the provided types.
* @task test
*/
isType : function(node, of_type) {
node = ('' + (node.nodeName || '')).toUpperCase();
of_type = JX.$AX(of_type);
for (var ii = 0; ii < of_type.length; ++ii) {
if (of_type[ii].toUpperCase() == node) {
return true;
}
}
return false;
},
/**
* Listen for events occuring beneath a specific node in the DOM. This is
* similar to @{JX.Stratcom.listen()}, but allows you to specify some node
* which serves as a scope instead of the default scope (the whole document)
* which you get if you install using @{JX.Stratcom.listen()} directly. For
* example, to listen for clicks on nodes with the sigil 'menu-item' below
* the root menu node:
*
* var the_menu = getReferenceToTheMenuNodeSomehow();
* JX.DOM.listen(the_menu, 'click', 'menu-item', function(e) { ... });
*
* @task stratcom
* @param Node The node to listen for events underneath.
* @param string|list One or more event types to listen for.
* @param list? A path to listen on, or a list of paths.
* @param function Callback to invoke when a matching event occurs.
* @return object A reference to the installed listener. You can later
* remove the listener by calling this object's remove()
* method.
*/
listen : function(node, type, path, callback) {
var auto_id = ['autoid:' + JX.DOM._getAutoID(node)];
path = JX.$AX(path || []);
if (!path.length) {
path = auto_id;
} else {
for (var ii = 0; ii < path.length; ii++) {
path[ii] = auto_id.concat(JX.$AX(path[ii]));
}
}
return JX.Stratcom.listen(type, path, callback);
},
/**
* Invoke a custom event on a node. This method is a companion to
* @{method:JX.DOM.listen} and parallels @{method:JX.Stratcom.invoke} in
* the same way that method parallels @{method:JX.Stratcom.listen}.
*
* This method can not be used to invoke native events (like 'click').
*
* @param Node The node to invoke an event on.
* @param string Custom event type.
* @param dict Event data.
* @return JX.Event The event object which was dispatched to listeners.
* The main use of this is to test whether any
* listeners prevented the event.
*/
invoke : function(node, type, data) {
if (__DEV__) {
if (type in JX.__allowedEvents) {
throw new Error(
'JX.DOM.invoke(..., "' + type + '", ...): ' +
'you cannot invoke with the same type as a native event.');
}
}
return JX.Stratcom.dispatch({
target: node,
type: type,
customData: data
});
},
uniqID : function(node) {
if (!node.getAttribute('id')) {
node.setAttribute('id', 'uniqid_'+(++JX.DOM._uniqid));
}
return node.getAttribute('id');
},
alterClass : function(node, className, add) {
if (__DEV__) {
if (add !== false && add !== true) {
JX.$E(
'JX.DOM.alterClass(...): ' +
'expects the third parameter to be Boolean: ' +
add + ' was provided');
}
}
var has = ((' '+node.className+' ').indexOf(' '+className+' ') > -1);
if (add && !has) {
node.className += ' '+className;
} else if (has && !add) {
node.className = node.className.replace(
new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), ' ');
}
},
htmlize : function(str) {
return (''+str)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
},
/**
* Show one or more elements, by removing their "display" style. This
* assumes you have hidden them with @{method:hide}, or explicitly set
* the style to `display: none;`.
*
* @task convenience
* @param ... One or more nodes to remove "display" styles from.
* @return void
*/
show : function() {
+ var ii;
+
if (__DEV__) {
- for (var ii = 0; ii < arguments.length; ++ii) {
+ for (ii = 0; ii < arguments.length; ++ii) {
if (!arguments[ii]) {
JX.$E(
'JX.DOM.show(...): ' +
'one or more arguments were null or empty.');
}
}
}
- for (var ii = 0; ii < arguments.length; ++ii) {
+ for (ii = 0; ii < arguments.length; ++ii) {
arguments[ii].style.display = '';
}
},
/**
* Hide one or more elements, by setting `display: none;` on them. This is
* a convenience method. See also @{method:show}.
*
* @task convenience
* @param ... One or more nodes to set "display: none" on.
* @return void
*/
hide : function() {
+ var ii;
+
if (__DEV__) {
- for (var ii = 0; ii < arguments.length; ++ii) {
+ for (ii = 0; ii < arguments.length; ++ii) {
if (!arguments[ii]) {
JX.$E(
'JX.DOM.hide(...): ' +
'one or more arguments were null or empty.');
}
}
}
- for (var ii = 0; ii < arguments.length; ++ii) {
+ for (ii = 0; ii < arguments.length; ++ii) {
arguments[ii].style.display = 'none';
}
},
textMetrics : function(node, pseudoclass, x) {
if (!this._metrics[pseudoclass]) {
var n = JX.$N(
'var',
{className: pseudoclass});
this._metrics[pseudoclass] = n;
}
var proxy = this._metrics[pseudoclass];
document.body.appendChild(proxy);
proxy.style.width = x ? (x+'px') : '';
JX.DOM.setContent(
proxy,
JX.$H(JX.DOM.htmlize(node.value).replace(/\n/g, '<br />')));
var metrics = JX.Vector.getDim(proxy);
document.body.removeChild(proxy);
return metrics;
},
/**
* Search the document for DOM nodes by providing a root node to look
* beneath, a tag name, and (optionally) a sigil. Nodes which match all
* specified conditions are returned.
*
* @task query
*
* @param Node Root node to search beneath.
* @param string Tag name, like 'a' or 'textarea'.
* @param string Optionally, a sigil which nodes are required to have.
*
* @return list List of matching nodes, which may be empty.
*/
scry : function(root, tagname, sigil) {
if (__DEV__) {
if (!JX.DOM.isNode(root)) {
JX.$E(
'JX.DOM.scry(<yuck>, ...): '+
'first argument must be a DOM node.');
}
}
var nodes = root.getElementsByTagName(tagname);
if (!sigil) {
return JX.$A(nodes);
}
var result = [];
for (var ii = 0; ii < nodes.length; ii++) {
if (JX.Stratcom.hasSigil(nodes[ii], sigil)) {
result.push(nodes[ii]);
}
}
return result;
},
/**
* Select a node uniquely identified by a root, tagname and sigil. This
* is similar to JX.DOM.scry() but expects exactly one result.
*
* @task query
*
* @param Node Root node to search beneath.
* @param string Tag name, like 'a' or 'textarea'.
* @param string Optionally, sigil which selected node must have.
*
* @return Node Node uniquely identified by the criteria.
*/
find : function(root, tagname, sigil) {
if (__DEV__) {
if (!JX.DOM.isNode(root)) {
JX.$E(
'JX.DOM.find(<glop>, "'+tagname+'", "'+sigil+'"): '+
'first argument must be a DOM node.');
}
}
var result = JX.DOM.scry(root, tagname, sigil);
if (__DEV__) {
if (result.length > 1) {
JX.$E(
'JX.DOM.find(<node>, "'+tagname+'", "'+sigil+'"): '+
'matched more than one node.');
}
}
if (!result.length) {
JX.$E('JX.DOM.find(<node>, "' +
tagname + '", "' + sigil + '"): '+ 'matched no nodes.');
}
return result[0];
},
/**
* Focus a node safely. This is just a convenience wrapper that allows you
* to avoid IE's habit of throwing when nearly any focus operation is
* invoked.
*
* @task convenience
* @param Node Node to move cursor focus to, if possible.
* @return void
*/
focus : function(node) {
try { node.focus(); } catch (lol_ie) {}
},
/**
* Scroll to the position of an element in the document.
* @task view
* @param Node Node to move document scroll position to, if possible.
* @return void
*/
scrollTo : function(node) {
window.scrollTo(0, JX.$V(node).y);
},
_getAutoID : function(node) {
if (!node.getAttribute('data-autoid')) {
node.setAttribute('data-autoid', 'autoid_'+(++JX.DOM._autoid));
}
return node.getAttribute('data-autoid');
}
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/Mask.js b/webroot/rsrc/externals/javelin/lib/Mask.js
index 6bb3b192ee..881c52fedc 100644
--- a/webroot/rsrc/externals/javelin/lib/Mask.js
+++ b/webroot/rsrc/externals/javelin/lib/Mask.js
@@ -1,109 +1,109 @@
/**
* @requires javelin-install
* javelin-dom
* @provides javelin-mask
* @javelin
*/
/**
* Show a "mask" over the page for lightboxes or dialogs. This is used by
* Workflow to draw visual attention to modal dialogs.
*
* JX.Mask.show();
* // Show a dialog, lightbox, or other modal UI.
* JX.Mask.hide();
*
* Masks are stackable, if modal UIs need to spawn other modal UIs.
*
* The mask has class `jx-mask`, which you should apply styles to. For example:
*
* .jx-mask {
* opacity: 0.8;
* background: #000000;
* position: fixed;
* top: 0;
* bottom: 0;
* left: 0;
* right: 0;
* z-index: 2;
* }
*
* You can create multiple mask styles and select them with the `mask_type`
* parameter to `show()` (for instance, a light mask for dialogs and a dark
* mask for lightboxing):
*
* JX.Mask.show('jx-light-mask');
* // ...
* JX.Mask.hide();
*
* This will be applied as a class name to the mask element, which you can
* customize in CSS:
*
* .jx-light-mask {
* background: #ffffff;
* }
*
* The mask has sigil `jx-mask`, which can be used to intercept events
* targeting it, like clicks on the mask.
*
* @group control
*/
JX.install('Mask', {
statics : {
_stack : [],
_mask : null,
_currentType : null,
/**
* Show a mask over the document. Multiple calls push masks onto a stack.
*
* @param string Optional class name to apply to the mask, if you have
* multiple masks (e.g., one dark and one light).
* @return void
*/
show : function(mask_type) {
var self = JX.Mask;
mask_type = mask_type || null;
if (!self._stack.length) {
self._mask = JX.$N('div', {className: 'jx-mask', sigil: 'jx-mask'});
document.body.appendChild(self._mask);
}
- self._adjustType(mask_type)
+ self._adjustType(mask_type);
JX.Mask._stack.push(mask_type);
},
/**
* Hide the current mask. The mask stack is popped, which may reveal another
* mask below the current mask.
*
* @return void
*/
hide : function() {
var self = JX.Mask;
var mask_type = self._stack.pop();
self._adjustType(mask_type);
if (!self._stack.length) {
JX.DOM.remove(JX.Mask._mask);
JX.Mask._mask = null;
}
},
_adjustType : function(new_type) {
var self = JX.Mask;
if (self._currentType) {
JX.DOM.alterClass(self._mask, self._currentType, false);
self._currentType = null;
}
if (new_type) {
JX.DOM.alterClass(self._mask, new_type, true);
self._currentType = new_type;
}
}
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/Request.js b/webroot/rsrc/externals/javelin/lib/Request.js
index 8763151906..d7438b6d3f 100644
--- a/webroot/rsrc/externals/javelin/lib/Request.js
+++ b/webroot/rsrc/externals/javelin/lib/Request.js
@@ -1,471 +1,471 @@
/**
* @requires javelin-install
* javelin-stratcom
* javelin-util
* javelin-behavior
* javelin-json
* javelin-dom
* javelin-resource
* @provides javelin-request
* @javelin
*/
/**
* Make basic AJAX XMLHTTPRequests.
*
* @group workflow
*/
JX.install('Request', {
construct : function(uri, handler) {
this.setURI(uri);
if (handler) {
this.listen('done', handler);
}
},
events : ['start', 'open', 'send', 'statechange', 'done', 'error', 'finally',
'uploadprogress'],
members : {
_xhrkey : null,
_transport : null,
_sent : false,
_finished : false,
_block : null,
_data : null,
_getSameOriginTransport : function() {
try {
try {
return new XMLHttpRequest();
} catch (x) {
return new ActiveXObject("Msxml2.XMLHTTP");
}
} catch (x) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
},
_getCORSTransport : function() {
try {
var xport = new XMLHttpRequest();
if ('withCredentials' in xport) {
// XHR supports CORS
} else if (typeof XDomainRequest != 'undefined') {
xport = new XDomainRequest();
}
return xport;
} catch (x) {
return new XDomainRequest();
}
},
getTransport : function() {
if (!this._transport) {
this._transport = this.getCORS() ? this._getCORSTransport() :
this._getSameOriginTransport();
}
return this._transport;
},
send : function() {
if (this._sent || this._finished) {
if (__DEV__) {
if (this._sent) {
JX.$E(
'JX.Request.send(): ' +
'attempting to send a Request that has already been sent.');
}
if (this._finished) {
JX.$E(
'JX.Request.send(): ' +
'attempting to send a Request that has finished or aborted.');
}
}
return;
}
// Fire the "start" event before doing anything. A listener may
// perform pre-processing or validation on this request
this.invoke('start', this);
if (this._finished) {
return;
}
var xport = this.getTransport();
xport.onreadystatechange = JX.bind(this, this._onreadystatechange);
if (xport.upload) {
xport.upload.onprogress = JX.bind(this, this._onuploadprogress);
}
var method = this.getMethod().toUpperCase();
if (__DEV__) {
if (this.getRawData()) {
if (method != 'POST') {
JX.$E(
'JX.Request.send(): ' +
'attempting to send post data over GET. You must use POST.');
}
}
}
var list_of_pairs = this._data || [];
list_of_pairs.push(['__ajax__', true]);
this._block = JX.Stratcom.allocateMetadataBlock();
list_of_pairs.push(['__metablock__', this._block]);
var q = (this.getDataSerializer() ||
JX.Request.defaultDataSerializer)(list_of_pairs);
var uri = this.getURI();
// If we're sending a file, submit the metadata via the URI instead of
// via the request body, because the entire post body will be consumed by
// the file content.
if (method == 'GET' || this.getRawData()) {
uri += ((uri.indexOf('?') === -1) ? '?' : '&') + q;
}
if (this.getTimeout()) {
this._timer = setTimeout(
JX.bind(
this,
this._fail,
JX.Request.ERROR_TIMEOUT),
this.getTimeout());
}
xport.open(method, uri, true);
// Must happen after xport.open so that listeners can modify the transport
// Some transport properties can only be set after the transport is open
this.invoke('open', this);
if (this._finished) {
return;
}
this.invoke('send', this);
if (this._finished) {
return;
}
if (method == 'POST') {
if (this.getRawData()) {
xport.send(this.getRawData());
} else {
xport.setRequestHeader(
'Content-Type',
'application/x-www-form-urlencoded');
xport.send(q);
}
} else {
xport.send(null);
}
this._sent = true;
},
abort : function() {
this._cleanup();
},
_onuploadprogress : function(progress) {
this.invoke('uploadprogress', progress);
},
_onreadystatechange : function() {
var xport = this.getTransport();
var response;
try {
this.invoke('statechange', this);
if (this._finished) {
return;
}
if (xport.readyState != 4) {
return;
}
// XHR requests to 'file:///' domains return 0 for success, which is why
// we treat it as a good result in addition to HTTP 2XX responses.
if (xport.status !== 0 && (xport.status < 200 || xport.status >= 300)) {
this._fail();
return;
}
if (__DEV__) {
var expect_guard = this.getExpectCSRFGuard();
if (!xport.responseText.length) {
JX.$E(
'JX.Request("'+this.getURI()+'", ...): '+
'server returned an empty response.');
}
- if (expect_guard && xport.responseText.indexOf('for (;;);') != 0) {
+ if (expect_guard && xport.responseText.indexOf('for (;;);') !== 0) {
JX.$E(
'JX.Request("'+this.getURI()+'", ...): '+
'server returned an invalid response.');
}
if (expect_guard && xport.responseText == 'for (;;);') {
JX.$E(
'JX.Request("'+this.getURI()+'", ...): '+
'server returned an empty response.');
}
}
response = this._extractResponse(xport);
if (!response) {
JX.$E(
'JX.Request("'+this.getURI()+'", ...): '+
'server returned an invalid response.');
}
} catch (exception) {
if (__DEV__) {
JX.log(
'JX.Request("'+this.getURI()+'", ...): '+
'caught exception processing response: '+exception);
}
this._fail();
return;
}
try {
this._handleResponse(response);
this._cleanup();
} catch (exception) {
// In Firefox+Firebug, at least, something eats these. :/
setTimeout(function() {
throw exception;
}, 0);
}
},
_extractResponse : function(xport) {
var text = xport.responseText;
if (this.getExpectCSRFGuard()) {
text = text.substring('for (;;);'.length);
}
var type = this.getResponseType().toUpperCase();
if (type == 'TEXT') {
return text;
} else if (type == 'JSON' || type == 'JAVELIN') {
return JX.JSON.parse(text);
} else if (type == 'XML') {
var doc;
try {
if (typeof DOMParser != 'undefined') {
var parser = new DOMParser();
doc = parser.parseFromString(text, "text/xml");
} else { // IE
// an XDomainRequest
doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async = false;
doc.loadXML(xport.responseText);
}
return doc.documentElement;
} catch (exception) {
if (__DEV__) {
JX.log(
'JX.Request("'+this.getURI()+'", ...): '+
'caught exception extracting response: '+exception);
}
this._fail();
return null;
}
}
if (__DEV__) {
JX.$E(
'JX.Request("'+this.getURI()+'", ...): '+
'unrecognized response type.');
}
return null;
},
_fail : function(error) {
this._cleanup();
this.invoke('error', error, this);
this.invoke('finally');
},
_done : function(response) {
this._cleanup();
if (response.onload) {
for (var ii = 0; ii < response.onload.length; ii++) {
(new Function(response.onload[ii]))();
}
}
var payload;
if (this.getRaw()) {
payload = response;
} else {
payload = response.payload;
JX.Request._parseResponsePayload(payload);
}
this.invoke('done', payload, this);
this.invoke('finally');
},
_cleanup : function() {
this._finished = true;
clearTimeout(this._timer);
this._timer = null;
// Should not abort the transport request if it has already completed
// Otherwise, we may see an "HTTP request aborted" error in the console
// despite it possibly having succeeded.
if (this._transport && this._transport.readyState != 4) {
this._transport.abort();
}
},
setData : function(dictionary) {
this._data = null;
this.addData(dictionary);
return this;
},
addData : function(dictionary) {
if (!this._data) {
this._data = [];
}
for (var k in dictionary) {
this._data.push([k, dictionary[k]]);
}
return this;
},
setDataWithListOfPairs : function(list_of_pairs) {
this._data = list_of_pairs;
return this;
},
_handleResponse : function(response) {
if (this.getResponseType().toUpperCase() == 'JAVELIN') {
if (response.error) {
this._fail(response.error);
} else {
JX.Stratcom.mergeData(
this._block,
response.javelin_metadata || {});
var when_complete = JX.bind(this, function() {
this._done(response);
JX.initBehaviors(response.javelin_behaviors || {});
});
if (response.javelin_resources) {
JX.Resource.load(response.javelin_resources, when_complete);
} else {
when_complete();
}
}
} else {
this._cleanup();
this.invoke('done', response, this);
this.invoke('finally');
}
}
},
statics : {
ERROR_TIMEOUT : -9000,
defaultDataSerializer : function(list_of_pairs) {
var uri = [];
for (var ii = 0; ii < list_of_pairs.length; ii++) {
var pair = list_of_pairs[ii];
var name = encodeURIComponent(pair[0]);
var value = encodeURIComponent(pair[1]);
uri.push(name + '=' + value);
}
return uri.join('&');
},
/**
* When we receive a JSON blob, parse it to introduce meaningful objects
* where there are magic keys for placeholders.
*
* Objects with the magic key '__html' are translated into JX.HTML objects.
*
* This function destructively modifies its input.
*/
_parseResponsePayload: function(parent, index) {
var recurse = JX.Request._parseResponsePayload;
var obj = (typeof index !== 'undefined') ? parent[index] : parent;
if (JX.isArray(obj)) {
for (var ii = 0; ii < obj.length; ii++) {
recurse(obj, ii);
}
} else if (obj && typeof obj == 'object') {
- if (obj.__html != null) {
+ if (('__html' in obj) && (obj.__html !== null)) {
parent[index] = JX.$H(obj.__html);
} else {
for (var key in obj) {
recurse(obj, key);
}
}
}
}
},
properties : {
URI : null,
dataSerializer : null,
/**
* Configure which HTTP method to use for the request. Permissible values
* are "POST" (default) or "GET".
*
* @param string HTTP method, one of "POST" or "GET".
*/
method : 'POST',
/**
* Set the data parameter of transport.send. Useful if you want to send a
* file or FormData. Not that you cannot send raw data and data at the same
* time.
*
* @param Data, argument to transport.send
*/
rawData: null,
raw : false,
/**
* Configure a timeout, in milliseconds. If the request has not resolved
* (either with success or with an error) within the provided timeframe,
* it will automatically fail with error JX.Request.ERROR_TIMEOUT.
*
* @param int Timeout, in milliseconds (e.g. 3000 = 3 seconds).
*/
timeout : null,
/**
* Whether or not we should expect the CSRF guard in the response.
*
* @param bool
*/
expectCSRFGuard : true,
/**
* Whether it should be a CORS (Cross-Origin Resource Sharing) request to
* a third party domain other than the current site.
*
* @param bool
*/
CORS : false,
/**
* Type of the response.
*
* @param enum 'JAVELIN', 'JSON', 'XML', 'TEXT'
*/
responseType : 'JAVELIN'
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/Resource.js b/webroot/rsrc/externals/javelin/lib/Resource.js
index a5baf58202..7c93804bbf 100644
--- a/webroot/rsrc/externals/javelin/lib/Resource.js
+++ b/webroot/rsrc/externals/javelin/lib/Resource.js
@@ -1,177 +1,176 @@
/**
* @provides javelin-resource
- * @requires javelin-magical-init
- * javelin-stratcom
- * javelin-util
+ * @requires javelin-util
* javelin-uri
+ * javelin-install
*
* @javelin
*/
JX.install('Resource', {
statics: {
_loading: {},
_loaded: {},
_links: [],
_callbacks: [],
/**
* Loads one or many static resources (JavaScript or CSS) and executes a
* callback once these resources have finished loading.
*
* @param string|array static resource or list of resources to be loaded
* @param function callback when resources have finished loading
*/
load: function(list, callback) {
var resources = {},
uri, resource, path, type;
list = JX.$AX(list);
// In the event there are no resources to wait on, call the callback and
// exit. NOTE: it's better to do this check outside this function and not
// call through JX.Resource, but it's not always easy/possible to do so
if (!list.length) {
setTimeout(callback, 0);
return;
}
for (var ii = 0; ii < list.length; ii++) {
uri = new JX.URI(list[ii]);
resource = uri.toString();
path = uri.getPath();
resources[resource] = true;
if (JX.Resource._loaded[resource]) {
setTimeout(JX.bind(JX.Resource, JX.Resource._complete, resource), 0);
} else if (!JX.Resource._loading[resource]) {
JX.Resource._loading[resource] = true;
if (path.indexOf('.css') == path.length - 4) {
JX.Resource._loadCSS(resource);
} else {
JX.Resource._loadJS(resource);
}
}
}
JX.Resource._callbacks.push({
resources: resources,
callback: callback
});
},
_loadJS: function(uri) {
var script = document.createElement('script');
var load_callback = function() {
JX.Resource._complete(uri);
};
var error_callback = function() {
JX.$E('Resource: JS file download failure: ' + uri);
};
JX.copy(script, {
type: 'text/javascript',
src: uri
});
script.onload = load_callback;
script.onerror = error_callback;
script.onreadystatechange = function() {
var state = this.readyState;
if (state == 'complete' || state == 'loaded') {
load_callback();
}
};
document.getElementsByTagName('head')[0].appendChild(script);
},
_loadCSS: function(uri) {
var link = JX.copy(document.createElement('link'), {
type: 'text/css',
rel: 'stylesheet',
href: uri,
'data-href': uri // don't trust href
});
document.getElementsByTagName('head')[0].appendChild(link);
JX.Resource._links.push(link);
if (!JX.Resource._timer) {
JX.Resource._timer = setInterval(JX.Resource._poll, 20);
}
},
_poll: function() {
var sheets = document.styleSheets,
ii = sheets.length,
links = JX.Resource._links;
// Cross Origin CSS loading
// http://yearofmoo.com/2011/03/cross-browser-stylesheet-preloading/
while (ii--) {
var link = sheets[ii],
owner = link.ownerNode || link.owningElement,
jj = links.length;
if (owner) {
while (jj--) {
if (owner == links[jj]) {
JX.Resource._complete(links[jj]['data-href']);
links.splice(jj, 1);
}
}
}
}
if (!links.length) {
clearInterval(JX.Resource._timer);
JX.Resource._timer = null;
}
},
_complete: function(uri) {
var list = JX.Resource._callbacks,
current, ii;
delete JX.Resource._loading[uri];
JX.Resource._loaded[uri] = true;
for (ii = 0; ii < list.length; ii++) {
current = list[ii];
delete current.resources[uri];
if (!JX.Resource._hasResources(current.resources)) {
current.callback();
list.splice(ii--, 1);
}
}
},
_hasResources: function(resources) {
for (var hasResources in resources) {
return true;
}
return false;
}
},
initialize: function() {
var list = JX.$A(document.getElementsByTagName('link')),
ii = list.length,
node;
while ((node = list[--ii])) {
if (node.type == 'text/css' && node.href) {
JX.Resource._loaded[(new JX.URI(node.href)).toString()] = true;
}
}
list = JX.$A(document.getElementsByTagName('script'));
ii = list.length;
while ((node = list[--ii])) {
if (node.type == 'text/javascript' && node.src) {
JX.Resource._loaded[(new JX.URI(node.src)).toString()] = true;
}
}
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/URI.js b/webroot/rsrc/externals/javelin/lib/URI.js
index 35e614fc7a..e22982cc6b 100644
--- a/webroot/rsrc/externals/javelin/lib/URI.js
+++ b/webroot/rsrc/externals/javelin/lib/URI.js
@@ -1,246 +1,246 @@
/**
* @provides javelin-uri
* @requires javelin-install
* javelin-util
* javelin-stratcom
*
* @javelin-installs JX.$U
*
* @javelin
*/
/**
* Handy convenience function that returns a @{class:JX.URI} instance. This
* allows you to write things like:
*
* JX.$U('http://zombo.com/').getDomain();
*
* @param string Unparsed URI.
* @return @{class:JX.URI} JX.URI instance.
*
* @group uri
*/
JX.$U = function(uri) {
return new JX.URI(uri);
};
/**
* Convert a string URI into a maleable object.
*
* var uri = new JX.URI('http://www.example.com/asdf.php?a=b&c=d#anchor123');
* uri.getProtocol(); // http
* uri.getDomain(); // www.example.com
* uri.getPath(); // /asdf.php
* uri.getQueryParams(); // {a: 'b', c: 'd'}
* uri.getFragment(); // anchor123
*
* ...and back into a string:
*
* uri.setFragment('clowntown');
* uri.toString() // http://www.example.com/asdf.php?a=b&c=d#clowntown
*
* @group uri
*/
JX.install('URI', {
statics : {
_uriPattern : /(?:([^:\/?#]+):)?(?:\/\/([^:\/?#]*)(?::(\d*))?)?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/,
/**
* Convert a Javascript object into an HTTP query string.
*
* @param Object Map of query keys to values.
* @return String HTTP query string, like 'cow=quack&duck=moo'.
*/
_defaultQuerySerializer : function(obj) {
var kv_pairs = [];
for (var key in obj) {
- if (obj[key] != null) {
+ if (obj[key] !== null) {
var value = encodeURIComponent(obj[key]);
kv_pairs.push(encodeURIComponent(key) + (value ? '=' + value : ''));
}
}
return kv_pairs.join('&');
},
_decode : function(str) {
return decodeURIComponent(str.replace(/\+/g, ' '));
}
},
/**
* Construct a URI
*
* Accepts either absolute or relative URIs. Relative URIs may have protocol
* and domain properties set to undefined
*
* @param string absolute or relative URI
*/
construct : function(uri) {
// need to set the default value here rather than in the properties map,
// or else we get some crazy global state breakage
this.setQueryParams({});
if (uri) {
// parse the url
var result = JX.URI._uriPattern.exec(uri);
// fallback to undefined because IE has weird behavior otherwise
this.setProtocol(result[1] || undefined);
this.setDomain(result[2] || undefined);
this.setPort(result[3] || undefined);
var path = result[4];
var query = result[5];
this.setFragment(result[6] || undefined);
// parse the path
this.setPath(path.charAt(0) == '/' ? path : '/' + path);
// parse the query data
if (query && query.length) {
var dict = {};
var parts = query.split('&');
for (var ii = 0; ii < parts.length; ii++) {
var part = parts[ii];
if (!part.length) {
continue;
}
var pieces = part.split('=');
var name = pieces[0];
if (!name.length) {
continue;
}
var value = pieces.slice(1).join('=') || '';
dict[JX.URI._decode(name)] = JX.URI._decode(value);
}
this.setQueryParams(dict);
}
}
},
properties : {
protocol: undefined,
port: undefined,
path: undefined,
queryParams: undefined,
fragment: undefined,
querySerializer: undefined
},
members : {
_domain: undefined,
/**
* Append and override query data values
* Remove a query key by setting it undefined
*
* @param map
* @return @{JX.URI} self
*/
addQueryParams : function(map) {
JX.copy(this.getQueryParams(), map);
return this;
},
/**
* Set a specific query parameter
* Remove a query key by setting it undefined
*
* @param string
* @param wild
* @return @{JX.URI} self
*/
setQueryParam : function(key, value) {
var map = {};
map[key] = value;
return this.addQueryParams(map);
},
/**
* Set the domain
*
* This function checks the domain name to ensure that it is safe for
* browser consumption.
*/
setDomain : function(domain) {
var re = new RegExp(
// For the bottom 128 code points, we use a strict whitelist of
// characters that are allowed by all browsers: -.0-9:A-Z[]_a-z
'[\\x00-\\x2c\\x2f\\x3b-\\x40\\x5c\\x5e\\x60\\x7b-\\x7f' +
// In IE, these chararacters cause problems when entity-encoded.
'\\uFDD0-\\uFDEF\\uFFF0-\\uFFFF' +
// In Safari, these characters terminate the hostname.
'\\u2047\\u2048\\uFE56\\uFE5F\\uFF03\\uFF0F\\uFF1F]');
if (re.test(domain)) {
JX.$E('JX.URI.setDomain(...): invalid domain specified.');
}
this._domain = domain;
return this;
},
getDomain : function() {
return this._domain;
},
toString : function() {
if (__DEV__) {
if (this.getPath() && this.getPath().charAt(0) != '/') {
JX.$E(
'JX.URI.toString(): ' +
'Path does not begin with a "/" which means this URI will likely' +
'be malformed. Ensure any string passed to .setPath() leads "/"');
}
}
var str = '';
if (this.getProtocol()) {
str += this.getProtocol() + '://';
}
str += this.getDomain() || '';
if (this.getPort()) {
str += ':' + this.getPort();
}
// If there is a domain or a protocol, we need to provide '/' for the
// path. If we don't have either and also don't have a path, we can omit
// it to produce a partial URI without path information which begins
// with "?", "#", or is empty.
str += this.getPath() || (str ? '/' : '');
str += this._getQueryString();
if (this.getFragment()) {
str += '#' + this.getFragment();
}
return str;
},
_getQueryString : function() {
var str = (
this.getQuerySerializer() || JX.URI._defaultQuerySerializer
)(this.getQueryParams());
return str ? '?' + str : '';
},
/**
* Redirect the browser to another page by changing the window location. If
* the URI is empty, reloads the current page.
*
* You can install a Stratcom listener for the 'go' event if you need to log
* or prevent redirects.
*
* @return void
*/
go : function() {
var uri = this.toString();
if (JX.Stratcom.invoke('go', null, {uri: uri}).getPrevented()) {
return;
}
if (!uri) {
// window.location.reload clears cache in Firefox.
uri = window.location.pathname + (window.location.query || '');
}
window.location = uri;
}
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/Vector.js b/webroot/rsrc/externals/javelin/lib/Vector.js
index beedbb8278..20361a15e5 100644
--- a/webroot/rsrc/externals/javelin/lib/Vector.js
+++ b/webroot/rsrc/externals/javelin/lib/Vector.js
@@ -1,357 +1,353 @@
/**
* @requires javelin-install
* javelin-event
* @provides javelin-vector
*
* @javelin-installs JX.$V
*
* @javelin
*/
/**
* Convenience function that returns a @{class:JX.Vector} instance. This allows
* you to concisely write things like:
*
* JX.$V(x, y).add(10, 10); // Explicit coordinates.
* JX.$V(node).add(50, 50).setDim(node); // Position of a node.
*
* @param number|Node If a node, returns the node's position vector.
* If numeric, the x-coordinate for the new vector.
* @param number? The y-coordinate for the new vector.
* @return @{class:JX.Vector} New vector.
*
* @group dom
*/
JX.$V = function(x, y) {
return new JX.Vector(x, y);
};
/**
* Query and update positions and dimensions of nodes (and other things) within
* within a document. Each vector has two elements, 'x' and 'y', which usually
* represent width/height ('dimension vector') or left/top ('position vector').
*
* Vectors are used to manage the sizes and positions of elements, events,
* the document, and the viewport (the visible section of the document, i.e.
* how much of the page the user can actually see in their browser window).
* Unlike most Javelin classes, @{class:JX.Vector} exposes two bare properties,
* 'x' and 'y'. You can read and manipulate these directly:
*
* // Give the user information about elements when they click on them.
* JX.Stratcom.listen(
* 'click',
* null,
* function(e) {
* var p = new JX.Vector(e);
* var d = JX.Vector.getDim(e.getTarget());
*
* alert('You clicked at <' + p.x + ',' + p.y + '> and the element ' +
* 'you clicked is ' + d.x + 'px wide and ' + d.y + 'px high.');
* });
*
* You can also update positions and dimensions using vectors:
*
* // When the user clicks on something, make it 10px wider and 10px taller.
* JX.Stratcom.listen(
* 'click',
* null,
* function(e) {
* var target = e.getTarget();
* JX.$V(target).add(10, 10).setDim(target);
* });
*
* Additionally, vectors can be used to query document and viewport information:
*
* var v = JX.Vector.getViewport(); // Viewport (window) width and height.
* var d = JX.Vector.getDocument(); // Document width and height.
* var visible_area = parseInt(100 * (v.x * v.y) / (d.x * d.y), 10);
* alert('You can currently see ' + visible_area + ' % of the document.');
*
* The function @{function:JX.$V} provides convenience construction of common
* vectors.
*
* @task query Querying Positions and Dimensions
* @task update Changing Positions and Dimensions
* @task manip Manipulating Vectors
*
* @group dom
*/
JX.install('Vector', {
/**
* Construct a vector, either from explicit coordinates or from a node
* or event. You can pass two Numbers to construct an explicit vector:
*
* var p = new JX.Vector(35, 42);
*
* Otherwise, you can pass a @{class:JX.Event} or a Node to implicitly
* construct a vector:
*
* var q = new JX.Vector(some_event);
* var r = new JX.Vector(some_node);
*
* These are just like calling JX.Vector.getPos() on the @{class:JX.Event} or
* Node.
*
* For convenience, @{function:JX.$V} constructs a new vector so you don't
* need to use the 'new' keyword. That is, these are equivalent:
*
* var s = new JX.Vector(x, y);
* var t = JX.$V(x, y);
*
* Methods like @{method:getScroll}, @{method:getViewport} and
* @{method:getDocument} also create new vectors.
*
* Once you have a vector, you can manipulate it with add():
*
* var u = JX.$V(35, 42);
* var v = u.add(5, -12); // v = <40, 30>
*
* @param wild 'x' component of the vector, or a @{class:JX.Event}, or a
* Node.
* @param Number? If providing an 'x' component, the 'y' component of the
* vector.
* @return @{class:JX.Vector} Specified vector.
* @task query
*/
construct : function(x, y) {
if (typeof y == 'undefined') {
return JX.Vector.getPos(x);
}
this.x = (x === null) ? null : parseFloat(x);
this.y = (y === null) ? null : parseFloat(y);
},
members : {
x : null,
y : null,
/**
* Move a node around by setting the position of a Node to the vector's
* coordinates. For instance, if you want to move an element to the top left
* corner of the document, you could do this (assuming it has 'position:
* absolute'):
*
* JX.$V(0, 0).setPos(node);
*
* @param Node Node to move.
* @return this
* @task update
*/
setPos : function(node) {
node.style.left = (this.x === null) ? '' : (parseInt(this.x, 10) + 'px');
node.style.top = (this.y === null) ? '' : (parseInt(this.y, 10) + 'px');
return this;
},
/**
* Change the size of a node by setting its dimensions to the vector's
* coordinates. For instance, if you want to change an element to be 100px
* by 100px:
*
* JX.$V(100, 100).setDim(node);
*
* Or if you want to expand a node's dimensions by 50px:
*
* JX.$V(node).add(50, 50).setDim(node);
*
* @param Node Node to resize.
* @return this
* @task update
*/
setDim : function(node) {
node.style.width =
- (this.x === null)
- ? ''
- : (parseInt(this.x, 10) + 'px');
+ (this.x === null) ? '' : (parseInt(this.x, 10) + 'px');
node.style.height =
- (this.y === null)
- ? ''
- : (parseInt(this.y, 10) + 'px');
+ (this.y === null) ? '' : (parseInt(this.y, 10) + 'px');
return this;
},
/**
* Change a vector's x and y coordinates by adding numbers to them, or
* adding the coordinates of another vector. For example:
*
* var u = JX.$V(3, 4).add(100, 200); // u = <103, 204>
*
* You can also add another vector:
*
* var q = JX.$V(777, 999);
* var r = JX.$V(1000, 2000);
* var s = q.add(r); // s = <1777, 2999>
*
* Note that this method returns a new vector. It does not modify the
* 'this' vector.
*
* @param wild Value to add to the vector's x component, or another
* vector.
* @param Number? Value to add to the vector's y component.
* @return @{class:JX.Vector} New vector, with summed components.
* @task manip
*/
add : function(x, y) {
if (x instanceof JX.Vector) {
y = x.y;
x = x.x;
}
return new JX.Vector(this.x + parseFloat(x), this.y + parseFloat(y));
}
},
statics : {
_viewport: null,
/**
* Determine where in a document an element is (or where an event, like
* a click, occurred) by building a new vector containing the position of a
* Node or @{class:JX.Event}. The 'x' component of the vector will
* correspond to the pixel offset of the argument relative to the left edge
* of the document, and the 'y' component will correspond to the pixel
* offset of the argument relative to the top edge of the document. Note
* that all vectors are generated in document coordinates, so the scroll
* position does not affect them.
*
* See also @{method:getDim}, used to determine an element's dimensions.
*
* @param Node|@{class:JX.Event} Node or event to determine the position
* of.
* @return @{class:JX.Vector} New vector with the argument's position.
* @task query
*/
getPos : function(node) {
JX.Event && (node instanceof JX.Event) && (node = node.getRawEvent());
if (('pageX' in node) || ('clientX' in node)) {
var c = JX.Vector._viewport;
return new JX.Vector(
node.pageX || (node.clientX + c.scrollLeft),
node.pageY || (node.clientY + c.scrollTop)
);
}
var x = 0;
var y = 0;
do {
var offsetParent = node.offsetParent;
var scrollLeft = 0;
var scrollTop = 0;
if (offsetParent && offsetParent != document.body) {
scrollLeft = offsetParent.scrollLeft;
scrollTop = offsetParent.scrollTop;
}
x += (node.offsetLeft - scrollLeft);
y += (node.offsetTop - scrollTop);
node = offsetParent;
} while (node && node != document.body);
return new JX.Vector(x, y);
},
/**
* Determine the width and height of a node by building a new vector with
* dimension information. The 'x' component of the vector will correspond
* to the element's width in pixels, and the 'y' component will correspond
* to its height in pixels.
*
* See also @{method:getPos}, used to determine an element's position.
*
* @param Node Node to determine the display size of.
* @return @{JX.$V} New vector with the node's dimensions.
* @task query
*/
getDim : function(node) {
return new JX.Vector(node.offsetWidth, node.offsetHeight);
},
/**
* Determine the current scroll position by building a new vector where
* the 'x' component corresponds to how many pixels the user has scrolled
* from the left edge of the document, and the 'y' component corresponds to
* how many pixels the user has scrolled from the top edge of the document.
*
* See also @{method:getViewport}, used to determine the size of the
* viewport.
*
* @return @{JX.$V} New vector with the document scroll position.
* @task query
*/
getScroll : function() {
// We can't use JX.Vector._viewport here because there's diversity between
// browsers with respect to where position/dimension and scroll position
// information is stored.
var b = document.body;
var e = document.documentElement;
return new JX.Vector(
window.pageXOffset || b.scrollLeft || e.scrollLeft,
window.pageYOffset || b.scrollTop || e.scrollTop
);
},
/**
* Determine the size of the viewport (basically, the browser window) by
* building a new vector where the 'x' component corresponds to the width
* of the viewport in pixels and the 'y' component corresponds to the height
* of the viewport in pixels.
*
* See also @{method:getScroll}, used to determine the position of the
* viewport, and @{method:getDocument}, used to determine the size of the
* entire document.
*
* @return @{class:JX.Vector} New vector with the viewport dimensions.
* @task query
*/
getViewport : function() {
var c = JX.Vector._viewport;
return new JX.Vector(
window.innerWidth || c.clientWidth || 0,
window.innerHeight || c.clientHeight || 0
);
},
/**
* Determine the size of the document, including any area outside the
* current viewport which the user would need to scroll in order to see, by
* building a new vector where the 'x' component corresponds to the document
* width in pixels and the 'y' component corresponds to the document height
* in pixels.
*
* @return @{class:JX.Vector} New vector with the document dimensions.
* @task query
*/
getDocument : function() {
var c = JX.Vector._viewport;
return new JX.Vector(c.scrollWidth || 0, c.scrollHeight || 0);
}
},
/**
* On initialization, the browser-dependent viewport root is determined and
* stored.
*
* In ##__DEV__##, @{class:JX.Vector} installs a toString() method so
* vectors print in a debuggable way:
*
* <23, 92>
*
* This string representation of vectors is not available in a production
* context.
*
* @return void
*/
initialize : function() {
JX.Vector._viewport = document.documentElement || document.body;
if (__DEV__) {
JX.Vector.prototype.toString = function() {
return '<' + this.x + ', ' + this.y + '>';
};
}
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/Workflow.js b/webroot/rsrc/externals/javelin/lib/Workflow.js
index 2238be9197..7e594e3944 100644
--- a/webroot/rsrc/externals/javelin/lib/Workflow.js
+++ b/webroot/rsrc/externals/javelin/lib/Workflow.js
@@ -1,290 +1,290 @@
/**
* @requires javelin-stratcom
* javelin-request
* javelin-dom
* javelin-vector
* javelin-install
* javelin-util
* javelin-mask
* javelin-uri
* @provides javelin-workflow
* @javelin
*/
/**
* @group workflow
*/
JX.install('Workflow', {
construct : function(uri, data) {
if (__DEV__) {
if (!uri || uri == '#') {
JX.$E(
'new JX.Workflow(<?>, ...): '+
'bogus URI provided when creating workflow.');
}
}
this.setURI(uri);
this.setData(data || {});
},
events : ['error', 'finally', 'submit'],
statics : {
_stack : [],
newFromForm : function(form, data) {
var pairs = JX.DOM.convertFormToListOfPairs(form);
for (var k in data) {
pairs.push([k, data[k]]);
}
// Disable form elements during the request
var inputs = [].concat(
JX.DOM.scry(form, 'input'),
JX.DOM.scry(form, 'button'),
JX.DOM.scry(form, 'textarea'));
for (var ii = 0; ii < inputs.length; ii++) {
if (inputs[ii].disabled) {
delete inputs[ii];
} else {
inputs[ii].disabled = true;
}
}
var workflow = new JX.Workflow(form.getAttribute('action'), {});
workflow.setDataWithListOfPairs(pairs);
workflow.setMethod(form.getAttribute('method'));
workflow.listen('finally', function() {
// Re-enable form elements
for (var ii = 0; ii < inputs.length; ii++) {
inputs[ii] && (inputs[ii].disabled = false);
}
});
return workflow;
},
newFromLink : function(link) {
var workflow = new JX.Workflow(link.href);
return workflow;
},
_push : function(workflow) {
JX.Mask.show();
JX.Workflow._stack.push(workflow);
},
_pop : function() {
var dialog = JX.Workflow._stack.pop();
(dialog.getCloseHandler() || JX.bag)();
dialog._destroy();
JX.Mask.hide();
},
disable : function() {
JX.Workflow._disabled = true;
},
_onbutton : function(event) {
if (JX.Stratcom.pass()) {
return;
}
if (JX.Workflow._disabled) {
return;
}
// Get the button (which is sometimes actually another tag, like an <a />)
// which triggered the event. In particular, this makes sure we get the
// right node if there is a <button> with an <img /> inside it or
// or something similar.
var t = event.getNode('jx-workflow-button') ||
event.getNode('tag:button');
if (t.name == '__cancel__' || t.name == '__close__') {
JX.Workflow._pop();
} else {
var form = event.getNode('jx-dialog');
var data = JX.DOM.convertFormToListOfPairs(form);
data.push([t.name, t.value || true]);
var active = JX.Workflow._getActiveWorkflow();
var e = active.invoke('submit', {form: form, data: data});
if (!e.getStopped()) {
active._destroy();
active
.setURI(form.getAttribute('action') || active.getURI())
.setDataWithListOfPairs(data)
.start();
}
}
event.prevent();
},
_getActiveWorkflow : function() {
var stack = JX.Workflow._stack;
return stack[stack.length - 1];
}
},
members : {
_root : null,
_pushed : false,
_data : null,
_onload : function(r) {
// It is permissible to send back a falsey redirect to force a page
// reload, so we need to take this branch if the key is present.
if (r && (typeof r.redirect != 'undefined')) {
JX.$U(r.redirect).go();
} else if (r && r.dialog) {
this._push();
this._root = JX.$N(
'div',
{className: 'jx-client-dialog'},
JX.$H(r.dialog));
JX.DOM.listen(
this._root,
'click',
[['jx-workflow-button'], ['tag:button']],
JX.Workflow._onbutton);
document.body.appendChild(this._root);
var d = JX.Vector.getDim(this._root);
var v = JX.Vector.getViewport();
var s = JX.Vector.getScroll();
JX.$V((v.x - d.x) / 2, s.y + 100).setPos(this._root);
try {
JX.DOM.focus(JX.DOM.find(this._root, 'button', '__default__'));
var inputs = JX.DOM.scry(this._root, 'input')
.concat(JX.DOM.scry(this._root, 'textarea'));
var miny = Number.POSITIVE_INFINITY;
var target = null;
for (var ii = 0; ii < inputs.length; ++ii) {
if (inputs[ii].type != 'hidden') {
// Find the topleft-most displayed element.
var p = JX.$V(inputs[ii]);
if (p.y < miny) {
miny = p.y;
target = inputs[ii];
}
}
}
target && JX.DOM.focus(target);
} catch (_ignored) {}
} else if (this.getHandler()) {
this.getHandler()(r);
this._pop();
} else if (r) {
if (__DEV__) {
JX.$E('Response to workflow request went unhandled.');
}
}
},
_push : function() {
if (!this._pushed) {
this._pushed = true;
JX.Workflow._push(this);
}
},
_pop : function() {
if (this._pushed) {
this._pushed = false;
JX.Workflow._pop();
}
},
_destroy : function() {
if (this._root) {
JX.DOM.remove(this._root);
this._root = null;
}
},
start : function() {
var uri = this.getURI();
var method = this.getMethod();
var r = new JX.Request(uri, JX.bind(this, this._onload));
var list_of_pairs = this._data;
list_of_pairs.push(['__wflow__', true]);
r.setDataWithListOfPairs(list_of_pairs);
r.setDataSerializer(this.getDataSerializer());
if (method) {
r.setMethod(method);
}
r.listen('finally', JX.bind(this, this.invoke, 'finally'));
r.listen('error', JX.bind(this, function(error) {
var e = this.invoke('error', error);
if (e.getStopped()) {
return;
}
// TODO: Default error behavior? On Facebook Lite, we just shipped the
// user to "/error/". We could emit a blanket 'workflow-failed' type
// event instead.
}));
r.send();
},
setData : function(dictionary) {
this._data = [];
for (var k in dictionary) {
this._data.push([k, dictionary[k]]);
}
return this;
},
setDataWithListOfPairs : function(list_of_pairs) {
this._data = list_of_pairs;
return this;
}
},
properties : {
handler : null,
closeHandler : null,
dataSerializer : null,
method : null,
URI : null
},
initialize : function() {
function close_dialog_when_user_presses_escape(e) {
if (e.getSpecialKey() != 'esc') {
// Some key other than escape.
return;
}
if (JX.Workflow._disabled) {
// Workflows are disabled on this page.
return;
}
if (JX.Stratcom.pass()) {
// Something else swallowed the event.
return;
}
var active = JX.Workflow._getActiveWorkflow();
if (!active) {
// No active workflow.
return;
}
// Note: the cancel button is actually an <a /> tag.
var buttons = JX.DOM.scry(active._root, 'a', 'jx-workflow-button');
if (!buttons.length) {
// No buttons in the dialog.
return;
}
var cancel = null;
for (var ii = 0; ii < buttons.length; ii++) {
if (buttons[ii].name == '__cancel__') {
cancel = buttons[ii];
break;
}
}
if (!cancel) {
// No 'Cancel' button.
return;
}
JX.Workflow._pop();
e.prevent();
- };
+ }
JX.Stratcom.listen('keydown', null, close_dialog_when_user_presses_escape);
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/__tests__/URI.js b/webroot/rsrc/externals/javelin/lib/__tests__/URI.js
index 56639a161f..62387c3b9e 100644
--- a/webroot/rsrc/externals/javelin/lib/__tests__/URI.js
+++ b/webroot/rsrc/externals/javelin/lib/__tests__/URI.js
@@ -1,303 +1,303 @@
/**
* @requires javelin-uri javelin-php-serializer
*/
describe('Javelin URI', function() {
it('should understand parts of a uri', function() {
var uri = JX.$U('http://www.facebook.com:123/home.php?key=value#fragment');
expect(uri.getProtocol()).toEqual('http');
expect(uri.getDomain()).toEqual('www.facebook.com');
expect(uri.getPort()).toEqual('123');
expect(uri.getPath()).toEqual('/home.php');
expect(uri.getQueryParams()).toEqual({'key' : 'value'});
expect(uri.getFragment()).toEqual('fragment');
});
it('can accept null as uri string', function() {
var uri = JX.$U(null);
expect(uri.getProtocol()).toEqual(undefined);
expect(uri.getDomain()).toEqual(undefined);
expect(uri.getPath()).toEqual(undefined);
expect(uri.getQueryParams()).toEqual({});
expect(uri.getFragment()).toEqual(undefined);
expect(uri.toString()).toEqual('');
});
it('can accept empty string as uri string', function() {
var uri = JX.$U('');
expect(uri.getProtocol()).toEqual(undefined);
expect(uri.getDomain()).toEqual(undefined);
expect(uri.getPath()).toEqual(undefined);
expect(uri.getQueryParams()).toEqual({});
expect(uri.getFragment()).toEqual(undefined);
expect(uri.toString()).toEqual('');
});
it('should understand relative uri', function() {
var uri = JX.$U('/home.php?key=value#fragment');
expect(uri.getProtocol()).toEqual(undefined);
expect(uri.getDomain()).toEqual(undefined);
expect(uri.getPath()).toEqual('/home.php');
expect(uri.getQueryParams()).toEqual({'key' : 'value'});
expect(uri.getFragment()).toEqual('fragment');
});
function charRange(from, to) {
res = '';
for (var i = from.charCodeAt(0); i <= to.charCodeAt(0); i++) {
res += String.fromCharCode(i);
}
return res;
}
it('should reject unsafe domains', function() {
var unsafe_chars =
'\x00;\\%\u2047\u2048\ufe56\ufe5f\uff03\uff0f\uff1f' +
charRange('\ufdd0', '\ufdef') + charRange('\ufff0', '\uffff');
for (var i = 0; i < unsafe_chars.length; i++) {
expect(function() {
JX.$U('http://foo' + unsafe_chars.charAt(i) + 'bar');
}).toThrow();
}
});
it('should allow safe domains', function() {
var safe_chars =
'-._' + charRange('a', 'z') + charRange('A', 'Z') + charRange('0', '9') +
'\u2046\u2049\ufdcf\ufdf0\uffef';
for (var i = 0; i < safe_chars.length; i++) {
var domain = 'foo' + safe_chars.charAt(i) + 'bar';
var uri = JX.$U('http://' + domain);
expect(uri.getDomain()).toEqual(domain);
}
});
it('should set slash as the default path', function() {
var uri = JX.$U('http://www.facebook.com');
expect(uri.getPath()).toEqual('/');
});
it('should set empty map as the default query data', function() {
var uri = JX.$U('http://www.facebook.com/');
expect(uri.getQueryParams()).toEqual({});
});
it('should set undefined as the default fragment', function() {
var uri = JX.$U('http://www.facebook.com/');
expect(uri.getFragment()).toEqual(undefined);
});
it('should understand uri with no path', function() {
var uri = JX.$U('http://www.facebook.com?key=value');
expect(uri.getPath()).toEqual('/');
expect(uri.getQueryParams()).toEqual({'key' : 'value'});
});
it('should understand multiple query keys', function() {
var uri = JX.$U('/?clown=town&herp=derp');
expect(uri.getQueryParams()).toEqual({
'clown' : 'town',
'herp' : 'derp'
});
});
it('does not set keys for nonexistant data', function() {
var uri = JX.$U('/?clown=town');
expect(uri.getQueryParams().herp).toEqual(undefined);
});
it('does not parse different types of query data', function() {
var uri = JX.$U('/?str=string&int=123&bool=true&badbool=false&raw');
expect(uri.getQueryParams()).toEqual({
'str' : 'string',
'int' : '123',
'bool' : 'true',
'badbool' : 'false',
'raw' : ''
});
});
it('should act as string', function() {
var string = 'http://www.facebook.com/home.php?key=value';
var uri = JX.$U(string);
expect(uri.toString()).toEqual(string);
expect('' + uri).toEqual(string);
});
it('can remove path', function() {
var uri = JX.$U('http://www.facebook.com/home.php?key=value');
uri.setPath(undefined);
expect(uri.getPath()).toEqual(undefined);
expect(uri.toString()).toEqual('http://www.facebook.com/?key=value');
});
it('can remove queryData by undefining it', function() {
var uri = JX.$U('http://www.facebook.com/home.php?key=value');
uri.setQueryParams(undefined);
expect(uri.getQueryParams()).toEqual(undefined);
expect(uri.toString()).toEqual('http://www.facebook.com/home.php');
});
it('can remove queryData by replacing it', function() {
var uri = JX.$U('http://www.facebook.com/home.php?key=value');
uri.setQueryParams({});
expect(uri.getQueryParams()).toEqual({});
expect(uri.toString()).toEqual('http://www.facebook.com/home.php');
});
it('can amend to removed queryData', function() {
var uri = JX.$U('http://www.facebook.com/home.php?key=value');
uri.setQueryParams({});
expect(uri.getQueryParams()).toEqual({});
uri.addQueryParams({'herp' : 'derp'});
expect(uri.getQueryParams()).toEqual({'herp' : 'derp'});
expect(uri.toString()).toEqual(
'http://www.facebook.com/home.php?herp=derp');
});
it('should properly decode entities', function() {
var uri = JX.$U('/?from=clown+town&to=cloud%20city&pass=cloud%2Bcountry');
expect(uri.getQueryParams()).toEqual({
'from' : 'clown town',
'to' : 'cloud city',
'pass' : 'cloud+country'
});
expect(uri.toString()).toEqual(
'/?from=clown%20town&to=cloud%20city&pass=cloud%2Bcountry');
});
it('can add query data', function() {
var uri = JX.$U('http://www.facebook.com/');
uri.addQueryParams({'key' : 'value'});
expect(uri.getQueryParams()).toEqual({'key' : 'value'});
expect(uri.toString()).toEqual('http://www.facebook.com/?key=value');
uri.setQueryParam('key', 'lock');
expect(uri.getQueryParams()).toEqual({'key' : 'lock'});
expect(uri.toString()).toEqual('http://www.facebook.com/?key=lock');
});
it('can add different types of query data', function() {
var uri = new JX.URI();
uri.setQueryParams({
'str' : 'string',
'int' : 123,
'bool' : true,
'badbool' : false,
'raw' : ''
});
expect(uri.toString()).toEqual(
'?str=string&int=123&bool=true&badbool=false&raw');
});
it('should properly encode entities in added query data', function() {
var uri = new JX.URI();
uri.addQueryParams({'key' : 'two words'});
expect(uri.getQueryParams()).toEqual({'key' : 'two words'});
expect(uri.toString()).toEqual('?key=two%20words');
});
it('can add multiple query data', function() {
var uri = JX.$U('http://www.facebook.com/');
uri.addQueryParams({
'clown' : 'town',
'herp' : 'derp'
});
expect(uri.getQueryParams()).toEqual({
'clown' : 'town',
'herp' : 'derp'
});
expect(uri.toString()).toEqual(
'http://www.facebook.com/?clown=town&herp=derp');
});
it('can append to existing query data', function() {
var uri = JX.$U('/?key=value');
uri.addQueryParams({'clown' : 'town'});
expect(uri.getQueryParams()).toEqual({
'key' : 'value',
'clown' : 'town'
});
expect(uri.toString()).toEqual('/?key=value&clown=town');
});
it('can merge with existing query data', function() {
var uri = JX.$U('/?key=value&clown=town');
uri.addQueryParams({
'clown' : 'ville',
'herp' : 'derp'
});
expect(uri.getQueryParams()).toEqual({
'key' : 'value',
'clown' : 'ville',
'herp' : 'derp'
});
expect(uri.toString()).toEqual('/?key=value&clown=ville&herp=derp');
});
it('can replace query data', function() {
var uri = JX.$U('/?key=value&clown=town');
uri.setQueryParams({'herp' : 'derp'});
expect(uri.getQueryParams()).toEqual({'herp' : 'derp'});
expect(uri.toString()).toEqual('/?herp=derp');
});
it('can remove query data', function() {
var uri = JX.$U('/?key=value&clown=town');
uri.addQueryParams({'key' : null});
expect(uri.getQueryParams()).toEqual({
'clown' : 'town',
'key' : null
});
expect(uri.toString()).toEqual('/?clown=town');
});
it('can remove multiple query data', function() {
var uri = JX.$U('/?key=value&clown=town&herp=derp');
uri.addQueryParams({'key' : null, 'herp' : undefined});
expect(uri.getQueryParams()).toEqual({
'clown' : 'town',
'key' : null,
'herp' : undefined
});
expect(uri.toString()).toEqual('/?clown=town');
});
- it('can remove non existant query data', function() {
+ it('can remove non existent query data', function() {
var uri = JX.$U('/?key=value');
uri.addQueryParams({'magic' : null});
expect(uri.getQueryParams()).toEqual({
'key' : 'value',
'magic' : null
});
expect(uri.toString()).toEqual('/?key=value');
});
it('can build uri from scratch', function() {
var uri = new JX.URI();
uri.setProtocol('http');
uri.setDomain('www.facebook.com');
uri.setPath('/home.php');
uri.setQueryParams({'key' : 'value'});
uri.setFragment('fragment');
expect(uri.toString()).toEqual(
'http://www.facebook.com/home.php?key=value#fragment');
});
it('no global state interference', function() {
var uri1 = JX.$U('/?key=value');
var uri2 = JX.$U();
expect(uri2.getQueryParams()).not.toEqual({'key' : 'value'});
});
it('should not loop indefinitely when parsing empty params', function() {
expect(JX.$U('/?&key=value').getQueryParams()).toEqual({'key' : 'value'});
expect(JX.$U('/?&&&key=value').getQueryParams()).toEqual({'key' : 'value'});
expect(JX.$U('/?&&').getQueryParams()).toEqual({});
});
it('should parse values with =', function() {
expect(JX.$U('/?x=1=1').getQueryParams()).toEqual({'x' : '1=1'});
});
});
diff --git a/webroot/rsrc/externals/javelin/lib/behavior.js b/webroot/rsrc/externals/javelin/lib/behavior.js
index 9568fe2f90..8741b9c423 100644
--- a/webroot/rsrc/externals/javelin/lib/behavior.js
+++ b/webroot/rsrc/externals/javelin/lib/behavior.js
@@ -1,110 +1,111 @@
/**
* @provides javelin-behavior
* @requires javelin-magical-init
+ * javelin-util
*
* @javelin-installs JX.behavior
* @javelin-installs JX.initBehaviors
*
* @javelin
*/
/**
* Define a Javelin behavior, which holds glue code in a structured way. See
* @{article:Concepts: Behaviors} for a detailed description of Javelin
* behaviors.
*
* To define a behavior, provide a name and a function:
*
* JX.behavior('win-a-hog', function(config, statics) {
* alert("YOU WON A HOG NAMED " + config.hogName + "!");
* });
*
* @param string Behavior name.
* @param function Behavior callback/definition.
* @return void
* @group behavior
*/
JX.behavior = function(name, control_function) {
if (__DEV__) {
if (JX.behavior._behaviors.hasOwnProperty(name)) {
JX.$E(
'JX.behavior("' + name + '", ...): '+
'behavior is already registered.');
}
if (!control_function) {
JX.$E(
'JX.behavior("' + name + '", <nothing>): '+
'initialization function is required.');
}
if (typeof control_function != 'function') {
JX.$E(
'JX.behavior("' + name + '", <garbage>): ' +
'initialization function is not a function.');
}
// IE does not enumerate over these properties
var enumerables = {
toString: true,
hasOwnProperty: true,
valueOf: true,
isPrototypeOf: true,
propertyIsEnumerable: true,
toLocaleString: true,
constructor: true
};
if (enumerables[name]) {
JX.$E(
'JX.behavior("' + name + '", <garbage>): ' +
'do not use this property as a behavior.'
);
}
}
JX.behavior._behaviors[name] = control_function;
JX.behavior._statics[name] = {};
};
/**
* Execute previously defined Javelin behaviors, running the glue code they
* contain to glue stuff together. See @{article:Concepts: Behaviors} for more
* information on Javelin behaviors.
*
* Normally, you do not call this function yourself; instead, your server-side
* library builds it for you.
*
* @param dict Map of behaviors to invoke: keys are behavior names, and values
* are lists of configuration dictionaries. The behavior will be
* invoked once for each configuration dictionary.
* @return void
* @group behavior
*/
JX.initBehaviors = function(map) {
var missing_behaviors = [];
for (var name in map) {
if (!(name in JX.behavior._behaviors)) {
missing_behaviors.push(name);
continue;
}
var configs = map[name];
if (!configs.length) {
if (JX.behavior._initialized.hasOwnProperty(name)) {
continue;
}
configs = [null];
}
for (var ii = 0; ii < configs.length; ii++) {
JX.behavior._behaviors[name](configs[ii], JX.behavior._statics[name]);
}
JX.behavior._initialized[name] = true;
}
if (missing_behaviors.length) {
JX.$E(
'JX.initBehavior(map): behavior(s) not registered: ' +
missing_behaviors.join(', ')
);
}
};
JX.behavior._behaviors = {};
JX.behavior._statics = {};
JX.behavior._initialized = {};
JX.flushHoldingQueue('behavior', JX.behavior);
diff --git a/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js b/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
index 04b90e26a8..bfcac0aaaa 100644
--- a/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
+++ b/webroot/rsrc/externals/javelin/lib/control/tokenizer/Tokenizer.js
@@ -1,405 +1,405 @@
/**
* @requires javelin-dom
* javelin-util
* javelin-stratcom
* javelin-install
* @provides javelin-tokenizer
* @javelin
*/
/**
* A tokenizer is a UI component similar to a text input, except that it
* allows the user to input a list of items ("tokens"), generally from a fixed
* set of results. A familiar example of this UI is the "To:" field of most
* email clients, where the control autocompletes addresses from the user's
* address book.
*
* @{JX.Tokenizer} is built on top of @{JX.Typeahead}, and primarily adds the
* ability to choose multiple items.
*
* To build a @{JX.Tokenizer}, you need to do four things:
*
* 1. Construct it, padding a DOM node for it to attach to. See the constructor
* for more information.
* 2. Build a {@JX.Typeahead} and configure it with setTypeahead().
* 3. Configure any special options you want.
* 4. Call start().
*
* If you do this correctly, the input should suggest items and enter them as
* tokens as the user types.
*
* When the tokenizer is focused, the CSS class `jx-tokenizer-container-focused`
* is added to the container node.
*
* @group control
*/
JX.install('Tokenizer', {
construct : function(containerNode) {
this._containerNode = containerNode;
},
events : [
/**
* Emitted when the value of the tokenizer changes, similar to an 'onchange'
* from a <select />.
*/
'change'],
properties : {
limit : null
},
members : {
_containerNode : null,
_root : null,
_focus : null,
_orig : null,
_typeahead : null,
_tokenid : 0,
_tokens : null,
_tokenMap : null,
_initialValue : null,
_seq : 0,
_lastvalue : null,
_placeholder : null,
start : function() {
if (__DEV__) {
if (!this._typeahead) {
throw new Error(
'JX.Tokenizer.start(): ' +
'No typeahead configured! Use setTypeahead() to provide a ' +
'typeahead.');
}
}
this._orig = JX.DOM.find(this._containerNode, 'input', 'tokenizer-input');
this._tokens = [];
this._tokenMap = {};
var focus = this.buildInput(this._orig.value);
this._focus = focus;
var input_container = JX.DOM.scry(
this._containerNode,
'div',
'tokenizer-input-container'
);
input_container = input_container[0] || this._containerNode;
JX.DOM.listen(
focus,
['click', 'focus', 'blur', 'keydown', 'keypress'],
null,
JX.bind(this, this.handleEvent));
JX.DOM.listen(
input_container,
'click',
null,
JX.bind(
this,
function(e) {
if (e.getNode('remove')) {
this._remove(e.getNodeData('token').key, true);
} else if (e.getTarget() == this._root) {
this.focus();
}
}));
var root = JX.$N('div');
root.id = this._orig.id;
JX.DOM.alterClass(root, 'jx-tokenizer', true);
root.style.cursor = 'text';
this._root = root;
root.appendChild(focus);
var typeahead = this._typeahead;
typeahead.setInputNode(this._focus);
typeahead.start();
setTimeout(JX.bind(this, function() {
var container = this._orig.parentNode;
JX.DOM.setContent(container, root);
var map = this._initialValue || {};
for (var k in map) {
this.addToken(k, map[k]);
}
JX.DOM.appendContent(
root,
JX.$N('div', {style: {clear: 'both'}})
);
this._redraw();
}), 0);
},
setInitialValue : function(map) {
this._initialValue = map;
return this;
},
setTypeahead : function(typeahead) {
typeahead.setAllowNullSelection(false);
typeahead.removeListener();
typeahead.listen(
'choose',
JX.bind(this, function(result) {
JX.Stratcom.context().prevent();
if (this.addToken(result.rel, result.name)) {
if (this.shouldHideResultsOnChoose()) {
this._typeahead.hide();
}
this._typeahead.clear();
this._redraw();
this.focus();
}
})
);
typeahead.listen(
'query',
JX.bind(
this,
function(query) {
// TODO: We should emit a 'query' event here to allow the caller to
// generate tokens on the fly, e.g. email addresses or other freeform
// or algorithmic tokens.
// Then do this if something handles the event.
// this._focus.value = '';
// this._redraw();
// this.focus();
if (query.length) {
// Prevent this event if there's any text, so that we don't submit
// the form (either we created a token or we failed to create a
// token; in either case we shouldn't submit). If the query is
// empty, allow the event so that the form submission takes place.
JX.Stratcom.context().prevent();
}
}));
this._typeahead = typeahead;
return this;
},
shouldHideResultsOnChoose : function() {
return true;
},
handleEvent : function(e) {
this._typeahead.handleEvent(e);
if (e.getPrevented()) {
return;
}
if (e.getType() == 'click') {
if (e.getTarget() == this._root) {
this.focus();
e.prevent();
return;
}
} else if (e.getType() == 'keydown') {
this._onkeydown(e);
} else if (e.getType() == 'blur') {
this._didblur();
// Explicitly update the placeholder since we just wiped the field
// value.
this._typeahead.updatePlaceholder();
} else if (e.getType() == 'focus') {
this._didfocus();
}
},
refresh : function() {
this._redraw(true);
return this;
},
_redraw : function(force) {
// If there are tokens in the tokenizer, never show a placeholder.
// Otherwise, show one if one is configured.
if (JX.keys(this._tokenMap).length) {
this._typeahead.setPlaceholder(null);
} else {
this._typeahead.setPlaceholder(this._placeholder);
}
var focus = this._focus;
if (focus.value === this._lastvalue && !force) {
return;
}
this._lastvalue = focus.value;
var root = this._root;
var metrics = JX.DOM.textMetrics(
this._focus,
'jx-tokenizer-metrics');
metrics.y = null;
metrics.x += 24;
metrics.setDim(focus);
// This is a pretty ugly hack to force a redraw after copy/paste in
// Firefox. If we don't do this, it doesn't redraw the input so pasting
// in an email address doesn't give you a very good behavior.
focus.value = focus.value;
},
setPlaceholder : function(string) {
this._placeholder = string;
return this;
},
addToken : function(key, value) {
if (key in this._tokenMap) {
return false;
}
var focus = this._focus;
var root = this._root;
var token = this.buildToken(key, value);
this._tokenMap[key] = {
value : value,
key : key,
node : token
};
this._tokens.push(key);
root.insertBefore(token, focus);
this.invoke('change', this);
return true;
},
removeToken : function(key) {
return this._remove(key, false);
},
buildInput: function(value) {
return JX.$N('input', {
className: 'jx-tokenizer-input',
type: 'text',
autocomplete: 'off',
value: value
});
},
/**
* Generate a token based on a key and value. The "token" and "remove"
* sigils are observed by a listener in start().
*/
buildToken: function(key, value) {
var input = JX.$N('input', {
type: 'hidden',
value: key,
name: this._orig.name + '[' + (this._seq++) + ']'
});
var remove = JX.$N('a', {
className: 'jx-tokenizer-x',
sigil: 'remove'
}, '\u00d7'); // U+00D7 multiplication sign
return JX.$N('a', {
className: 'jx-tokenizer-token',
sigil: 'token',
meta: {key: key}
}, [value, input, remove]);
},
getTokens : function() {
var result = {};
for (var key in this._tokenMap) {
result[key] = this._tokenMap[key].value;
}
return result;
},
_onkeydown : function(e) {
var focus = this._focus;
var root = this._root;
var raw = e.getRawEvent();
if (raw.ctrlKey || raw.metaKey || raw.altKey) {
return;
}
switch (e.getSpecialKey()) {
case 'tab':
var completed = this._typeahead.submit();
if (!completed) {
this._focus.value = '';
}
break;
case 'delete':
if (!this._focus.value.length) {
var tok;
- while (tok = this._tokens.pop()) {
+ while ((tok = this._tokens.pop())) {
if (this._remove(tok, true)) {
break;
}
}
}
break;
case 'return':
// Don't subject this to token limits.
break;
default:
if (this.getLimit() &&
JX.keys(this._tokenMap).length == this.getLimit()) {
e.prevent();
}
setTimeout(JX.bind(this, this._redraw), 0);
break;
}
},
_remove : function(index, focus) {
if (!this._tokenMap[index]) {
return false;
}
JX.DOM.remove(this._tokenMap[index].node);
delete this._tokenMap[index];
this._redraw(true);
focus && this.focus();
this.invoke('change', this);
return true;
},
focus : function() {
var focus = this._focus;
JX.DOM.show(focus);
setTimeout(function() { JX.DOM.focus(focus); }, 0);
},
_didfocus : function() {
JX.DOM.alterClass(
this._containerNode,
'jx-tokenizer-container-focused',
true);
},
_didblur : function() {
JX.DOM.alterClass(
this._containerNode,
'jx-tokenizer-container-focused',
false);
this._focus.value = '';
this._redraw();
}
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js b/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js
index 13284ea693..9d11c6aabf 100644
--- a/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js
+++ b/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js
@@ -1,87 +1,86 @@
/**
* @requires javelin-install
* javelin-util
- * javelin-stratcom
* javelin-request
* javelin-typeahead-source
* @provides javelin-typeahead-ondemand-source
* @javelin
*/
/**
* @group control
*/
JX.install('TypeaheadOnDemandSource', {
extend : 'TypeaheadSource',
construct : function(uri) {
JX.TypeaheadSource.call(this);
this.uri = uri;
this.haveData = {
'' : true
};
},
properties : {
/**
* Configures how many milliseconds we wait after the user stops typing to
* send a request to the server. Setting a value of 250 means "wait 250
* milliseconds after the user stops typing to request typeahead data".
* Higher values reduce server load but make the typeahead less responsive.
*/
queryDelay : 125,
/**
* Auxiliary data to pass along when sending the query for server results.
*/
auxiliaryData : {}
},
members : {
uri : null,
lastChange : null,
haveData : null,
didChange : function(value) {
this.lastChange = JX.now();
value = this.normalize(value);
if (this.haveData[value]) {
this.matchResults(value);
} else {
this.waitForResults();
setTimeout(
JX.bind(this, this.sendRequest, this.lastChange, value),
this.getQueryDelay()
);
}
},
sendRequest : function(when, value) {
if (when != this.lastChange) {
return;
}
var r = new JX.Request(
this.uri,
JX.bind(this, this.ondata, this.lastChange, value));
r.setMethod('GET');
r.setData(JX.copy(this.getAuxiliaryData(), {q : value}));
r.send();
},
ondata : function(when, value, results) {
if (results) {
for (var ii = 0; ii < results.length; ii++) {
this.addResult(results[ii]);
}
}
this.haveData[value] = true;
if (when != this.lastChange) {
return;
}
this.matchResults(value);
}
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js b/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js
index 866b974eac..ace130610a 100644
--- a/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js
+++ b/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js
@@ -1,62 +1,61 @@
/**
* @requires javelin-install
* javelin-util
- * javelin-stratcom
* javelin-request
* javelin-typeahead-source
* @provides javelin-typeahead-preloaded-source
* @javelin
*/
/**
* Simple datasource that loads all possible results from a single call to a
* URI. This is appropriate if the total data size is small (up to perhaps a
* few thousand items). If you have more items so you can't ship them down to
* the client in one repsonse, use @{JX.TypeaheadOnDemandSource}.
*
* @group control
*/
JX.install('TypeaheadPreloadedSource', {
extend : 'TypeaheadSource',
construct : function(uri) {
JX.TypeaheadSource.call(this);
this.uri = uri;
},
members : {
ready : false,
uri : null,
lastValue : null,
didChange : function(value) {
if (this.ready) {
this.matchResults(value);
} else {
this.lastValue = value;
this.waitForResults();
}
},
didStart : function() {
var r = new JX.Request(this.uri, JX.bind(this, this.ondata));
r.setMethod('GET');
r.send();
},
ondata : function(results) {
for (var ii = 0; ii < results.length; ++ii) {
this.addResult(results[ii]);
}
if (this.lastValue !== null) {
this.matchResults(this.lastValue);
}
this.ready = true;
}
}
});
diff --git a/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js b/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js
index 70f9ccbd6b..95e4b52f15 100644
--- a/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js
+++ b/webroot/rsrc/externals/javelin/lib/control/typeahead/source/TypeaheadSource.js
@@ -1,349 +1,350 @@
/**
* @requires javelin-install
* javelin-util
* javelin-dom
* javelin-typeahead-normalizer
* @provides javelin-typeahead-source
* @javelin
*/
/**
* @group control
*/
JX.install('TypeaheadSource', {
construct : function() {
this._raw = {};
this._lookup = {};
this.setNormalizer(JX.TypeaheadNormalizer.normalize);
this._excludeIDs = {};
},
events : ['waiting', 'resultsready', 'complete'],
properties : {
/**
* Allows you to specify a function which will be used to normalize strings.
* Strings are normalized before being tokenized, and before being sent to
* the server. The purpose of normalization is to strip out irrelevant data,
* like uppercase/lowercase, extra spaces, or punctuation. By default,
* the @{JX.TypeaheadNormalizer} is used to normalize strings, but you may
* want to provide a different normalizer, particiularly if there are
* special characters with semantic meaning in your object names.
*
* @param function
*/
normalizer : null,
/**
* If a typeahead query should be processed before being normalized and
* tokenized, specify a queryExtractor.
*
* @param function
*/
queryExtractor : null,
/**
* Transformers convert data from a wire format to a runtime format. The
* transformation mechanism allows you to choose an efficient wire format
* and then expand it on the client side, rather than duplicating data
* over the wire. The transformation is applied to objects passed to
* addResult(). It should accept whatever sort of object you ship over the
* wire, and produce a dictionary with these keys:
*
* - **id**: a unique id for each object.
* - **name**: the string used for matching against user input.
* - **uri**: the URI corresponding with the object (must be present
* but need not be meaningful)
*
* You can also give:
* - **display**: the text or nodes to show in the DOM. Usually just the
* same as ##name##.
* - **tokenizable**: if you want to tokenize something other than the
* ##name##, for the typeahead to complete on, specify it here. A
* selected entry from the typeahead will still insert the ##name##
* into the input, but the ##tokenizable## field lets you complete on
* non-name things.
*
* The default transformer expects a three element list with elements
* [name, uri, id]. It assigns the first element to both ##name## and
* ##display##.
*
* @param function
*/
transformer : null,
/**
* Configures the maximum number of suggestions shown in the typeahead
* dropdown.
*
* @param int
*/
maximumResultCount : 5,
/**
* Optional function which is used to sort results. Inputs are the input
* string, the list of matches, and a default comparator. The function
* should sort the list for display. This is the minimum useful
* implementation:
*
* function(value, list, comparator) {
* list.sort(comparator);
* }
*
* Alternatively, you may pursue more creative implementations.
*
* The `value` is a raw string; you can bind the datasource into the
* function and use normalize() or tokenize() to parse it.
*
* The `list` is a list of objects returned from the transformer function,
* see the `transformer` property. These are the objects in the list which
* match the value.
*
* The `comparator` is a sort callback which implements sensible default
* sorting rules (e.g., alphabetic order), which you can use as a fallback
* if you just want to tweak the results (e.g., put some items at the top).
*
* The function is called after the user types some text, immediately before
* the possible completion results are displayed to the user.
*
* @param function
*/
sortHandler : null
},
members : {
_raw : null,
_lookup : null,
_excludeIDs : null,
_changeListener : null,
_startListener : null,
bindToTypeahead : function(typeahead) {
this._changeListener = typeahead.listen(
'change',
JX.bind(this, this.didChange)
);
this._startListener = typeahead.listen(
'start',
JX.bind(this, this.didStart)
);
},
unbindFromTypeahead : function() {
this._changeListener.remove();
this._startListener.remove();
},
didChange : function(value) {
return;
},
didStart : function() {
return;
},
clearCache : function() {
this._raw = {};
this._lookup = {};
},
addExcludeID : function(id) {
if (id) {
this._excludeIDs[id] = true;
}
},
removeExcludeID : function (id) {
if (id) {
delete this._excludeIDs[id];
}
},
addResult : function(obj) {
obj = (this.getTransformer() || this._defaultTransformer)(obj);
if (obj.id in this._raw) {
// We're already aware of this result. This will happen if someone
// searches for "zeb" and then for "zebra" with a
// TypeaheadRequestSource, for example, or the datasource just doesn't
// dedupe things properly. Whatever the case, just ignore it.
return;
}
if (__DEV__) {
for (var k in {name : 1, id : 1, display : 1, uri : 1}) {
if (!(k in obj)) {
throw new Error(
"JX.TypeaheadSource.addResult(): " +
"result must have properties 'name', 'id', 'uri' and 'display'.");
}
}
}
this._raw[obj.id] = obj;
var t = this.tokenize(obj.tokenizable || obj.name);
for (var jj = 0; jj < t.length; ++jj) {
this._lookup[t[jj]] = this._lookup[t[jj]] || [];
this._lookup[t[jj]].push(obj.id);
}
},
waitForResults : function() {
this.invoke('waiting');
return this;
},
/**
* Get the raw state of a result by its ID. A number of other events and
* mechanisms give a list of result IDs and limited additional data; if you
* need to act on the full result data you can look it up here.
*
* @param scalar Result ID.
* @return dict Corresponding raw result.
*/
getResult : function(id) {
return this._raw[id];
},
matchResults : function(value) {
// This table keeps track of the number of tokens each potential match
// has actually matched. When we're done, the real matches are those
// which have matched every token (so the value is equal to the token
// list length).
var match_count = {};
// This keeps track of distinct matches. If the user searches for
// something like "Chris C" against "Chris Cox", the "C" will match
// both fragments. We need to make sure we only count distinct matches.
var match_fragments = {};
var matched = {};
var seen = {};
var query_extractor = this.getQueryExtractor();
if (query_extractor) {
value = query_extractor(value);
}
var t = this.tokenize(value);
// Sort tokens by longest-first. We match each name fragment with at
// most one token.
t.sort(function(u, v) { return v.length - u.length; });
for (var ii = 0; ii < t.length; ++ii) {
// Do something reasonable if the user types the same token twice; this
// is sort of stupid so maybe kill it?
if (t[ii] in seen) {
t.splice(ii--, 1);
continue;
}
seen[t[ii]] = true;
var fragment = t[ii];
for (var name_fragment in this._lookup) {
if (name_fragment.substr(0, fragment.length) === fragment) {
if (!(name_fragment in matched)) {
matched[name_fragment] = true;
} else {
continue;
}
var l = this._lookup[name_fragment];
for (var jj = 0; jj < l.length; ++jj) {
var match_id = l[jj];
if (!match_fragments[match_id]) {
match_fragments[match_id] = {};
}
if (!(fragment in match_fragments[match_id])) {
match_fragments[match_id][fragment] = true;
match_count[match_id] = (match_count[match_id] || 0) + 1;
}
}
}
}
}
var hits = [];
for (var k in match_count) {
if (match_count[k] == t.length && !this._excludeIDs[k]) {
hits.push(k);
}
}
this.sortHits(value, hits);
var nodes = this.renderNodes(value, hits);
this.invoke('resultsready', nodes);
this.invoke('complete');
},
sortHits : function(value, hits) {
var objs = [];
- for (var ii = 0; ii < hits.length; ii++) {
+ var ii;
+ for (ii = 0; ii < hits.length; ii++) {
objs.push(this._raw[hits[ii]]);
}
var default_comparator = function(u, v) {
var key_u = u.sort || u.name;
var key_v = v.sort || v.name;
return key_u.localeCompare(key_v);
};
var handler = this.getSortHandler() || function(value, list, cmp) {
list.sort(cmp);
};
handler(value, objs, default_comparator);
hits.splice(0, hits.length);
- for (var ii = 0; ii < objs.length; ii++) {
+ for (ii = 0; ii < objs.length; ii++) {
hits.push(objs[ii].id);
}
},
renderNodes : function(value, hits) {
var n = Math.min(this.getMaximumResultCount(), hits.length);
var nodes = [];
for (var kk = 0; kk < n; kk++) {
nodes.push(this.createNode(this._raw[hits[kk]]));
}
return nodes;
},
createNode : function(data) {
return JX.$N(
'a',
{
sigil: 'typeahead-result',
href: data.uri,
name: data.name,
rel: data.id,
className: 'jx-result'
},
data.display
);
},
normalize : function(str) {
return this.getNormalizer()(str);
},
tokenize : function(str) {
str = this.normalize(str);
if (!str.length) {
return [];
}
return str.split(/\s/g);
},
_defaultTransformer : function(object) {
return {
name : object[0],
display : object[0],
uri : object[1],
id : object[2]
};
}
}
});
diff --git a/webroot/rsrc/externals/raphael/g.raphael.js b/webroot/rsrc/externals/raphael/g.raphael.js
index 676f60860a..70936409ad 100644
--- a/webroot/rsrc/externals/raphael/g.raphael.js
+++ b/webroot/rsrc/externals/raphael/g.raphael.js
@@ -1,11 +1,12 @@
/**
* @provides raphael-g
* @do-not-minify
+ * @nolint
*/
/*!
* g.Raphael 0.5 - Charting library, based on Raphaël
*
* Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
*/
Raphael.el.popup=function(d,k,h,g){var c=this.paper||this[0].paper,f,j,b,e,a;if(!c){return}switch(this.type){case"text":case"circle":case"ellipse":b=true;break;default:b=false}d=d==null?"up":d;k=k||5;f=this.getBBox();h=typeof h=="number"?h:(b?f.x+f.width/2:f.x);g=typeof g=="number"?g:(b?f.y+f.height/2:f.y);e=Math.max(f.width/2-k,0);a=Math.max(f.height/2-k,0);this.translate(h-f.x-(b?f.width/2:0),g-f.y-(b?f.height/2:0));f=this.getBBox();var i={up:["M",h,g,"l",-k,-k,-e,0,"a",k,k,0,0,1,-k,-k,"l",0,-f.height,"a",k,k,0,0,1,k,-k,"l",k*2+e*2,0,"a",k,k,0,0,1,k,k,"l",0,f.height,"a",k,k,0,0,1,-k,k,"l",-e,0,"z"].join(","),down:["M",h,g,"l",k,k,e,0,"a",k,k,0,0,1,k,k,"l",0,f.height,"a",k,k,0,0,1,-k,k,"l",-(k*2+e*2),0,"a",k,k,0,0,1,-k,-k,"l",0,-f.height,"a",k,k,0,0,1,k,-k,"l",e,0,"z"].join(","),left:["M",h,g,"l",-k,k,0,a,"a",k,k,0,0,1,-k,k,"l",-f.width,0,"a",k,k,0,0,1,-k,-k,"l",0,-(k*2+a*2),"a",k,k,0,0,1,k,-k,"l",f.width,0,"a",k,k,0,0,1,k,k,"l",0,a,"z"].join(","),right:["M",h,g,"l",k,-k,0,-a,"a",k,k,0,0,1,k,-k,"l",f.width,0,"a",k,k,0,0,1,k,k,"l",0,k*2+a*2,"a",k,k,0,0,1,-k,k,"l",-f.width,0,"a",k,k,0,0,1,-k,-k,"l",0,-a,"z"].join(",")};j={up:{x:-!b*(f.width/2),y:-k*2-(b?f.height/2:f.height)},down:{x:-!b*(f.width/2),y:k*2+(b?f.height/2:f.height)},left:{x:-k*2-(b?f.width/2:f.width),y:-!b*(f.height/2)},right:{x:k*2+(b?f.width/2:f.width),y:-!b*(f.height/2)}}[d];this.translate(j.x,j.y);return c.path(i[d]).attr({fill:"#000",stroke:"none"}).insertBefore(this.node?this:this[0])};Raphael.el.tag=function(f,b,l,k){var i=3,e=this.paper||this[0].paper;if(!e){return}var c=e.path().attr({fill:"#000",stroke:"#000"}),j=this.getBBox(),m,h,a,g;switch(this.type){case"text":case"circle":case"ellipse":a=true;break;default:a=false}f=f||0;l=typeof l=="number"?l:(a?j.x+j.width/2:j.x);k=typeof k=="number"?k:(a?j.y+j.height/2:j.y);b=b==null?5:b;h=0.5522*b;if(j.height>=b*2){c.attr({path:["M",l,k+b,"a",b,b,0,1,1,0,-b*2,b,b,0,1,1,0,b*2,"m",0,-b*2-i,"a",b+i,b+i,0,1,0,0,(b+i)*2,"L",l+b+i,k+j.height/2+i,"l",j.width+2*i,0,0,-j.height-2*i,-j.width-2*i,0,"L",l,k-b-i].join(",")})}else{m=Math.sqrt(Math.pow(b+i,2)-Math.pow(j.height/2+i,2));c.attr({path:["M",l,k+b,"c",-h,0,-b,h-b,-b,-b,0,-h,b-h,-b,b,-b,h,0,b,b-h,b,b,0,h,h-b,b,-b,b,"M",l+m,k-j.height/2-i,"a",b+i,b+i,0,1,0,0,j.height+2*i,"l",b+i-m+j.width+2*i,0,0,-j.height-2*i,"L",l+m,k-j.height/2-i].join(",")})}f=360-f;c.rotate(f,l,k);if(this.attrs){this.attr(this.attrs.x?"x":"cx",l+b+i+(!a?this.type=="text"?j.width:0:j.width/2)).attr("y",a?k:k-j.height/2);this.rotate(f,l,k);f>90&&f<270&&this.attr(this.attrs.x?"x":"cx",l-b-i-(!a?j.width:j.width/2)).rotate(180,l,k)}else{if(f>90&&f<270){this.translate(l-j.x-j.width-b-i,k-j.y-j.height/2);this.rotate(f-180,j.x+j.width+b+i,j.y+j.height/2)}else{this.translate(l-j.x+b+i,k-j.y-j.height/2);this.rotate(f,j.x-b-i,j.y+j.height/2)}}return c.insertBefore(this.node?this:this[0])};Raphael.el.drop=function(d,g,f){var e=this.getBBox(),c=this.paper||this[0].paper,a,j,b,i,h;if(!c){return}switch(this.type){case"text":case"circle":case"ellipse":a=true;break;default:a=false}d=d||0;g=typeof g=="number"?g:(a?e.x+e.width/2:e.x);f=typeof f=="number"?f:(a?e.y+e.height/2:e.y);j=Math.max(e.width,e.height)+Math.min(e.width,e.height);b=c.path(["M",g,f,"l",j,0,"A",j*0.4,j*0.4,0,1,0,g+j*0.7,f-j*0.7,"z"]).attr({fill:"#000",stroke:"none"}).rotate(22.5-d,g,f);d=(d+90)*Math.PI/180;i=(g+j*Math.sin(d))-(a?0:e.width/2);h=(f+j*Math.cos(d))-(a?0:e.height/2);this.attrs?this.attr(this.attrs.x?"x":"cx",i).attr(this.attrs.y?"y":"cy",h):this.translate(i-e.x,h-e.y);return b.insertBefore(this.node?this:this[0])};Raphael.el.flag=function(e,k,j){var g=3,c=this.paper||this[0].paper;if(!c){return}var b=c.path().attr({fill:"#000",stroke:"#000"}),i=this.getBBox(),f=i.height/2,a;switch(this.type){case"text":case"circle":case"ellipse":a=true;break;default:a=false}e=e||0;k=typeof k=="number"?k:(a?i.x+i.width/2:i.x);j=typeof j=="number"?j:(a?i.y+i.height/2:i.y);b.attr({path:["M",k,j,"l",f+g,-f-g,i.width+2*g,0,0,i.height+2*g,-i.width-2*g,0,"z"].join(",")});e=360-e;b.rotate(e,k,j);if(this.attrs){this.attr(this.attrs.x?"x":"cx",k+f+g+(!a?this.type=="text"?i.width:0:i.width/2)).attr("y",a?j:j-i.height/2);this.rotate(e,k,j);e>90&&e<270&&this.attr(this.attrs.x?"x":"cx",k-f-g-(!a?i.width:i.width/2)).rotate(180,k,j)}else{if(e>90&&e<270){this.translate(k-i.x-i.width-f-g,j-i.y-i.height/2);this.rotate(e-180,i.x+i.width+f+g,i.y+i.height/2)}else{this.translate(k-i.x+f+g,j-i.y-i.height/2);this.rotate(e,i.x-f-g,i.y+i.height/2)}}return b.insertBefore(this.node?this:this[0])};Raphael.el.label=function(){var c=this.getBBox(),b=this.paper||this[0].paper,a=Math.min(20,c.width+10,c.height+10)/2;if(!b){return}return b.rect(c.x-a/2,c.y-a/2,c.width+a,c.height+a,a).attr({stroke:"none",fill:"#000"}).insertBefore(this.node?this:this[0])};Raphael.el.blob=function(z,j,i){var g=this.getBBox(),B=Math.PI/180,n=this.paper||this[0].paper,r,A,q;if(!n){return}switch(this.type){case"text":case"circle":case"ellipse":A=true;break;default:A=false}r=n.path().attr({fill:"#000",stroke:"none"});z=(+z+1?z:45)+90;q=Math.min(g.height,g.width);j=typeof j=="number"?j:(A?g.x+g.width/2:g.x);i=typeof i=="number"?i:(A?g.y+g.height/2:g.y);var m=Math.max(g.width+q,q*25/12),t=Math.max(g.height+q,q*25/12),u=j+q*Math.sin((z-22.5)*B),b=i+q*Math.cos((z-22.5)*B),v=j+q*Math.sin((z+22.5)*B),d=i+q*Math.cos((z+22.5)*B),o=(v-u)/2,l=(d-b)/2,f=m/2,e=t/2,s=-Math.sqrt(Math.abs(f*f*e*e-f*f*l*l-e*e*o*o)/(f*f*l*l+e*e*o*o)),c=s*f*l/e+(v+u)/2,a=s*-e*o/f+(d+b)/2;r.attr({x:c,y:a,path:["M",j,i,"L",v,d,"A",f,e,0,1,1,u,b,"z"].join(",")});this.translate(c-g.x-g.width/2,a-g.y-g.height/2);return r.insertBefore(this.node?this:this[0])};Raphael.fn.label=function(a,d,b){var c=this.set();b=this.text(a,d,b).attr(Raphael.g.txtattr);return c.push(b.label(),b)};Raphael.fn.popup=function(a,f,d,b,c){var e=this.set();d=this.text(a,f,d).attr(Raphael.g.txtattr);return e.push(d.popup(b,c),d)};Raphael.fn.tag=function(a,f,d,c,b){var e=this.set();d=this.text(a,f,d).attr(Raphael.g.txtattr);return e.push(d.tag(c,b),d)};Raphael.fn.flag=function(a,e,c,b){var d=this.set();c=this.text(a,e,c).attr(Raphael.g.txtattr);return d.push(c.flag(b),c)};Raphael.fn.drop=function(a,e,c,b){var d=this.set();c=this.text(a,e,c).attr(Raphael.g.txtattr);return d.push(c.drop(b),c)};Raphael.fn.blob=function(a,e,c,b){var d=this.set();c=this.text(a,e,c).attr(Raphael.g.txtattr);return d.push(c.blob(b),c)};Raphael.el.lighter=function(b){b=b||2;var a=[this.attrs.fill,this.attrs.stroke];this.fs=this.fs||[a[0],a[1]];a[0]=Raphael.rgb2hsb(Raphael.getRGB(a[0]).hex);a[1]=Raphael.rgb2hsb(Raphael.getRGB(a[1]).hex);a[0].b=Math.min(a[0].b*b,1);a[0].s=a[0].s/b;a[1].b=Math.min(a[1].b*b,1);a[1].s=a[1].s/b;this.attr({fill:"hsb("+[a[0].h,a[0].s,a[0].b]+")",stroke:"hsb("+[a[1].h,a[1].s,a[1].b]+")"});return this};Raphael.el.darker=function(b){b=b||2;var a=[this.attrs.fill,this.attrs.stroke];this.fs=this.fs||[a[0],a[1]];a[0]=Raphael.rgb2hsb(Raphael.getRGB(a[0]).hex);a[1]=Raphael.rgb2hsb(Raphael.getRGB(a[1]).hex);a[0].s=Math.min(a[0].s*b,1);a[0].b=a[0].b/b;a[1].s=Math.min(a[1].s*b,1);a[1].b=a[1].b/b;this.attr({fill:"hsb("+[a[0].h,a[0].s,a[0].b]+")",stroke:"hsb("+[a[1].h,a[1].s,a[1].b]+")"});return this};Raphael.el.resetBrightness=function(){if(this.fs){this.attr({fill:this.fs[0],stroke:this.fs[1]});delete this.fs}return this};(function(){var c=["lighter","darker","resetBrightness"],a=["popup","tag","flag","label","drop","blob"];for(var b in a){(function(d){Raphael.st[d]=function(){return Raphael.el[d].apply(this,arguments)}})(a[b])}for(var b in c){(function(d){Raphael.st[d]=function(){for(var e=0;e<this.length;e++){this[e][d].apply(this[e],arguments)}return this}})(c[b])}})();Raphael.g={shim:{stroke:"none",fill:"#000","fill-opacity":0},txtattr:{font:"12px Arial, sans-serif",fill:"#fff"},colors:(function(){var c=[0.6,0.2,0.05,0.1333,0.75,0],a=[];for(var b=0;b<10;b++){if(b<c.length){a.push("hsb("+c[b]+",.75, .75)")}else{a.push("hsb("+c[b-c.length]+", 1, .5)")}}return a})(),snapEnds:function(j,k,h){var e=j,l=k;if(e==l){return{from:e,to:l,power:0}}function m(d){return Math.abs(d-0.5)<0.25?~~(d)+0.5:Math.round(d)}var g=(l-e)/h,a=~~(g),c=a,b=0;if(a){while(c){b--;c=~~(g*Math.pow(10,b))/Math.pow(10,b)}b++}else{while(!a){b=b||1;a=~~(g*Math.pow(10,b))/Math.pow(10,b);b++}b&&b--}l=m(k*Math.pow(10,b))/Math.pow(10,b);if(l<k){l=m((k+0.5)*Math.pow(10,b))/Math.pow(10,b)}e=m((j-(b>0?0:0.5))*Math.pow(10,b))/Math.pow(10,b);return{from:e,to:l,power:b}},axis:function(p,o,k,D,e,G,g,J,h,a,q){a=a==null?2:a;h=h||"t";G=G||10;q=arguments[arguments.length-1];var C=h=="|"||h==" "?["M",p+0.5,o,"l",0,0.001]:g==1||g==3?["M",p+0.5,o,"l",0,-k]:["M",p,o+0.5,"l",k,0],s=this.snapEnds(D,e,G),H=s.from,z=s.to,F=s.power,E=0,w={font:"11px 'Fontin Sans', Fontin-Sans, sans-serif"},v=q.set(),I;I=(z-H)/G;var n=H,m=F>0?F:0;r=k/G;if(+g==1||+g==3){var b=o,u=(g-1?1:-1)*(a+3+!!(g-1));while(b>=o-k){h!="-"&&h!=" "&&(C=C.concat(["M",p-(h=="+"||h=="|"?a:!(g-1)*a*2),b+0.5,"l",a*2+1,0]));v.push(q.text(p+u,b,(J&&J[E++])||(Math.round(n)==n?n:+n.toFixed(m))).attr(w).attr({"text-anchor":g-1?"start":"end"}));n+=I;b-=r}if(Math.round(b+r-(o-k))){h!="-"&&h!=" "&&(C=C.concat(["M",p-(h=="+"||h=="|"?a:!(g-1)*a*2),o-k+0.5,"l",a*2+1,0]));v.push(q.text(p+u,o-k,(J&&J[E])||(Math.round(n)==n?n:+n.toFixed(m))).attr(w).attr({"text-anchor":g-1?"start":"end"}))}}else{n=H;m=(F>0)*F;u=(g?-1:1)*(a+9+!g);var c=p,r=k/G,A=0,B=0;while(c<=p+k){h!="-"&&h!=" "&&(C=C.concat(["M",c+0.5,o-(h=="+"?a:!!g*a*2),"l",0,a*2+1]));v.push(A=q.text(c,o+u,(J&&J[E++])||(Math.round(n)==n?n:+n.toFixed(m))).attr(w));var l=A.getBBox();if(B>=l.x-5){v.pop(v.length-1).remove()}else{B=l.x+l.width}n+=I;c+=r}if(Math.round(c-r-p-k)){h!="-"&&h!=" "&&(C=C.concat(["M",p+k+0.5,o-(h=="+"?a:!!g*a*2),"l",0,a*2+1]));v.push(q.text(p+k,o+u,(J&&J[E])||(Math.round(n)==n?n:+n.toFixed(m))).attr(w))}}var K=q.path(C);K.text=v;K.all=q.set([K,v]);K.remove=function(){this.text.remove();this.constructor.prototype.remove.call(this)};return K},labelise:function(a,c,b){if(a){return(a+"").replace(/(##+(?:\.#+)?)|(%%+(?:\.%+)?)/g,function(d,f,e){if(f){return(+c).toFixed(f.replace(/^#+\.?/g,"").length)}if(e){return(c*100/b).toFixed(e.replace(/^%+\.?/g,"").length)+"%"}})}else{return(+c).toFixed(0)}}};
\ No newline at end of file
diff --git a/webroot/rsrc/externals/raphael/g.raphael.line.js b/webroot/rsrc/externals/raphael/g.raphael.line.js
index 2c8925ddc2..fe8892e190 100644
--- a/webroot/rsrc/externals/raphael/g.raphael.line.js
+++ b/webroot/rsrc/externals/raphael/g.raphael.line.js
@@ -1,11 +1,12 @@
/**
* @provides raphael-g-line
* @do-not-minify
+ * @nolint
*/
/*!
* g.Raphael 0.5 - Charting library, based on Raphaël
*
* Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com)
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
*/
(function(){function a(g,n){var f=g.length/n,h=0,e=f,m=0,i=[];while(h<g.length){e--;if(e<0){m+=g[h]*(1+e);i.push(m/f);m=g[h++]*-e;e+=f}else{m+=g[h++]}}return i}function d(f,e,p,n,k,j){var h=(p-f)/2,g=(k-p)/2,q=Math.atan((p-f)/Math.abs(n-e)),o=Math.atan((k-p)/Math.abs(n-j));q=e<n?Math.PI-q:q;o=j<n?Math.PI-o:o;var i=Math.PI/2-((q+o)%(Math.PI*2))/2,s=h*Math.sin(i+q),m=h*Math.cos(i+q),r=g*Math.sin(i+o),l=g*Math.cos(i+o);return{x1:p-s,y1:n+m,x2:p+r,y2:n+l}}function b(f,P,O,e,h,A,z,J){var s=this;J=J||{};if(!f.raphael.is(A[0],"array")){A=[A]}if(!f.raphael.is(z[0],"array")){z=[z]}var q=J.gutter||10,B=Math.max(A[0].length,z[0].length),t=J.symbol||"",S=J.colors||s.colors,v=null,p=null,ad=f.set(),T=[];for(var ac=0,L=z.length;ac<L;ac++){B=Math.max(B,z[ac].length)}var ae=f.set();for(ac=0,L=z.length;ac<L;ac++){if(J.shade){ae.push(f.path().attr({stroke:"none",fill:S[ac],opacity:J.nostroke?1:0.3}))}if(z[ac].length>e-2*q){z[ac]=a(z[ac],e-2*q);B=e-2*q}if(A[ac]&&A[ac].length>e-2*q){A[ac]=a(A[ac],e-2*q)}}var W=Array.prototype.concat.apply([],A),U=Array.prototype.concat.apply([],z),u=s.snapEnds(Math.min.apply(Math,W),Math.max.apply(Math,W),A[0].length-1),E=u.from,o=u.to,N=s.snapEnds(Math.min.apply(Math,U),Math.max.apply(Math,U),z[0].length-1),C=N.from,n=N.to,Z=(e-q*2)/((o-E)||1),V=(h-q*2)/((n-C)||1);var G=f.set();if(J.axis){var m=(J.axis+"").split(/[,\s]+/);+m[0]&&G.push(s.axis(P+q,O+q,e-2*q,E,o,J.axisxstep||Math.floor((e-2*q)/20),2,f));+m[1]&&G.push(s.axis(P+e-q,O+h-q,h-2*q,C,n,J.axisystep||Math.floor((h-2*q)/20),3,f));+m[2]&&G.push(s.axis(P+q,O+h-q,e-2*q,E,o,J.axisxstep||Math.floor((e-2*q)/20),0,f));+m[3]&&G.push(s.axis(P+q,O+h-q,h-2*q,C,n,J.axisystep||Math.floor((h-2*q)/20),1,f))}var M=f.set(),aa=f.set(),r;for(ac=0,L=z.length;ac<L;ac++){if(!J.nostroke){M.push(r=f.path().attr({stroke:S[ac],"stroke-width":J.width||2,"stroke-linejoin":"round","stroke-linecap":"round","stroke-dasharray":J.dash||""}))}var g=Raphael.is(t,"array")?t[ac]:t,H=f.set();T=[];for(var ab=0,w=z[ac].length;ab<w;ab++){var l=P+q+((A[ac]||A[0])[ab]-E)*Z,k=O+h-q-(z[ac][ab]-C)*V;(Raphael.is(g,"array")?g[ab]:g)&&H.push(f[Raphael.is(g,"array")?g[ab]:g](l,k,(J.width||2)*3).attr({fill:S[ac],stroke:"none"}));if(J.smooth){if(ab&&ab!=w-1){var R=P+q+((A[ac]||A[0])[ab-1]-E)*Z,F=O+h-q-(z[ac][ab-1]-C)*V,Q=P+q+((A[ac]||A[0])[ab+1]-E)*Z,D=O+h-q-(z[ac][ab+1]-C)*V,af=d(R,F,l,k,Q,D);T=T.concat([af.x1,af.y1,l,k,af.x2,af.y2])}if(!ab){T=["M",l,k,"C",l,k]}}else{T=T.concat([ab?"L":"M",l,k])}}if(J.smooth){T=T.concat([l,k,l,k])}aa.push(H);if(J.shade){ae[ac].attr({path:T.concat(["L",l,O+h-q,"L",P+q+((A[ac]||A[0])[0]-E)*Z,O+h-q,"z"]).join(",")})}!J.nostroke&&r.attr({path:T.join(",")})}function K(an){var ak=[];for(var al=0,ap=A.length;al<ap;al++){ak=ak.concat(A[al])}ak.sort();var aq=[],ah=[];for(al=0,ap=ak.length;al<ap;al++){ak[al]!=ak[al-1]&&aq.push(ak[al])&&ah.push(P+q+(ak[al]-E)*Z)}ak=aq;ap=ak.length;var ag=an||f.set();for(al=0;al<ap;al++){var Y=ah[al]-(ah[al]-(ah[al-1]||P))/2,ao=((ah[al+1]||P+e)-ah[al])/2+(ah[al]-(ah[al-1]||P))/2,x;an?(x={}):ag.push(x=f.rect(Y-1,O,Math.max(ao+1,1),h).attr({stroke:"none",fill:"#000",opacity:0}));x.values=[];x.symbols=f.set();x.y=[];x.x=ah[al];x.axis=ak[al];for(var aj=0,am=z.length;aj<am;aj++){aq=A[aj]||A[0];for(var ai=0,y=aq.length;ai<y;ai++){if(aq[ai]==ak[al]){x.values.push(z[aj][ai]);x.y.push(O+h-q-(z[aj][ai]-C)*V);x.symbols.push(ad.symbols[aj][ai])}}}an&&an.call(x)}!an&&(v=ag)}function I(al){var ah=al||f.set(),x;for(var aj=0,an=z.length;aj<an;aj++){for(var ai=0,ak=z[aj].length;ai<ak;ai++){var ag=P+q+((A[aj]||A[0])[ai]-E)*Z,am=P+q+((A[aj]||A[0])[ai?ai-1:1]-E)*Z,y=O+h-q-(z[aj][ai]-C)*V;al?(x={}):ah.push(x=f.circle(ag,y,Math.abs(am-ag)/2).attr({stroke:"none",fill:"#000",opacity:0}));x.x=ag;x.y=y;x.value=z[aj][ai];x.line=ad.lines[aj];x.shade=ad.shades[aj];x.symbol=ad.symbols[aj][ai];x.symbols=ad.symbols[aj];x.axis=(A[aj]||A[0])[ai];al&&al.call(x)}}!al&&(p=ah)}ad.push(M,ae,aa,G,v,p);ad.lines=M;ad.shades=ae;ad.symbols=aa;ad.axis=G;ad.hoverColumn=function(j,i){!v&&K();v.mouseover(j).mouseout(i);return this};ad.clickColumn=function(i){!v&&K();v.click(i);return this};ad.hrefColumn=function(Y){var ag=f.raphael.is(arguments[0],"array")?arguments[0]:arguments;if(!(arguments.length-1)&&typeof Y=="object"){for(var j in Y){for(var y=0,X=v.length;y<X;y++){if(v[y].axis==j){v[y].attr("href",Y[j])}}}}!v&&K();for(y=0,X=ag.length;y<X;y++){v[y]&&v[y].attr("href",ag[y])}return this};ad.hover=function(j,i){!p&&I();p.mouseover(j).mouseout(i);return this};ad.click=function(i){!p&&I();p.click(i);return this};ad.each=function(i){I(i);return this};ad.eachColumn=function(i){K(i);return this};return ad}var c=function(){};c.prototype=Raphael.g;b.prototype=new c;Raphael.fn.linechart=function(f,k,g,e,j,i,h){return new b(this,f,k,g,e,j,i,h)}})();
\ No newline at end of file
diff --git a/webroot/rsrc/externals/raphael/raphael.js b/webroot/rsrc/externals/raphael/raphael.js
index fbd1fab40d..c70fa44f72 100644
--- a/webroot/rsrc/externals/raphael/raphael.js
+++ b/webroot/rsrc/externals/raphael/raphael.js
@@ -1,12 +1,13 @@
/**
* @provides raphael-core
* @do-not-minify
+ * @nolint
*/
// ┌─────────────────────────────────────────────────────────────────────┐ \\
// │ Raphaël 2.0.1 - JavaScript Vector Library │ \\
// ├─────────────────────────────────────────────────────────────────────┤ \\
// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
// └─────────────────────────────────────────────────────────────────────┘ \\
(function(a){var b="0.4.0",c="hasOwnProperty",d=/[\.\/]/,e="*",f=function(){},g=function(a,b){return a-b},h,i,j={n:{}},k=function(a,b){var c=j,d=i,e=Array.prototype.slice.call(arguments,2),f=k.listeners(a),l=0,m=!1,n,o=[],p={},q=[],r=[];h=a,i=0;for(var s=0,t=f.length;s<t;s++)"zIndex"in f[s]&&(o.push(f[s].zIndex),f[s].zIndex<0&&(p[f[s].zIndex]=f[s]));o.sort(g);while(o[l]<0){n=p[o[l++]],q.push(n.apply(b,e));if(i){i=d;return q}}for(s=0;s<t;s++){n=f[s];if("zIndex"in n)if(n.zIndex==o[l]){q.push(n.apply(b,e));if(i){i=d;return q}do{l++,n=p[o[l]],n&&q.push(n.apply(b,e));if(i){i=d;return q}}while(n)}else p[n.zIndex]=n;else{q.push(n.apply(b,e));if(i){i=d;return q}}}i=d;return q.length?q:null};k.listeners=function(a){var b=a.split(d),c=j,f,g,h,i,k,l,m,n,o=[c],p=[];for(i=0,k=b.length;i<k;i++){n=[];for(l=0,m=o.length;l<m;l++){c=o[l].n,g=[c[b[i]],c[e]],h=2;while(h--)f=g[h],f&&(n.push(f),p=p.concat(f.f||[]))}o=n}return p},k.on=function(a,b){var c=a.split(d),e=j;for(var g=0,h=c.length;g<h;g++)e=e.n,!e[c[g]]&&(e[c[g]]={n:{}}),e=e[c[g]];e.f=e.f||[];for(g=0,h=e.f.length;g<h;g++)if(e.f[g]==b)return f;e.f.push(b);return function(a){+a==+a&&(b.zIndex=+a)}},k.stop=function(){i=1},k.nt=function(a){if(a)return(new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)")).test(h);return h},k.unbind=function(a,b){var f=a.split(d),g,h,i,k,l,m,n,o=[j];for(k=0,l=f.length;k<l;k++)for(m=0;m<o.length;m+=i.length-2){i=[m,1],g=o[m].n;if(f[k]!=e)g[f[k]]&&i.push(g[f[k]]);else for(h in g)g[c](h)&&i.push(g[h]);o.splice.apply(o,i)}for(k=0,l=o.length;k<l;k++){g=o[k];while(g.n){if(b){if(g.f){for(m=0,n=g.f.length;m<n;m++)if(g.f[m]==b){g.f.splice(m,1);break}!g.f.length&&delete g.f}for(h in g.n)if(g.n[c](h)&&g.n[h].f){var p=g.n[h].f;for(m=0,n=p.length;m<n;m++)if(p[m]==b){p.splice(m,1);break}!p.length&&delete g.n[h].f}}else{delete g.f;for(h in g.n)g.n[c](h)&&g.n[h].f&&delete g.n[h].f}g=g.n}}},k.once=function(a,b){var c=function(){b.apply(this,arguments),k.unbind(a,c)};return k.on(a,c)},k.version=b,k.toString=function(){return"You are running Eve "+b},typeof module!="undefined"&&module.exports?module.exports=k:a.eve=k})(this),function(){function cr(b,d,e,f,h,i){e=Q(e);var j,k,l,m=[],o,p,q,t=b.ms,u={},v={},w={};if(f)for(y=0,z=cl.length;y<z;y++){var x=cl[y];if(x.el.id==d.id&&x.anim==b){x.percent!=e?(cl.splice(y,1),l=1):k=x,d.attr(x.totalOrigin);break}}else f=+v;for(var y=0,z=b.percents.length;y<z;y++){if(b.percents[y]==e||b.percents[y]>f*b.top){e=b.percents[y],p=b.percents[y-1]||0,t=t/b.top*(e-p),o=b.percents[y+1],j=b.anim[e];break}f&&d.attr(b.anim[b.percents[y]])}if(!!j){if(!k){for(var A in j)if(j[g](A))if(U[g](A)||d.paper.customAttributes[g](A)){u[A]=d.attr(A),u[A]==null&&(u[A]=T[A]),v[A]=j[A];switch(U[A]){case C:w[A]=(v[A]-u[A])/t;break;case"colour":u[A]=a.getRGB(u[A]);var B=a.getRGB(v[A]);w[A]={r:(B.r-u[A].r)/t,g:(B.g-u[A].g)/t,b:(B.b-u[A].b)/t};break;case"path":var D=bG(u[A],v[A]),E=D[1];u[A]=D[0],w[A]=[];for(y=0,z=u[A].length;y<z;y++){w[A][y]=[0];for(var F=1,G=u[A][y].length;F<G;F++)w[A][y][F]=(E[y][F]-u[A][y][F])/t}break;case"transform":var H=d._,I=bP(H[A],v[A]);if(I){u[A]=I.from,v[A]=I.to,w[A]=[],w[A].real=!0;for(y=0,z=u[A].length;y<z;y++){w[A][y]=[u[A][y][0]];for(F=1,G=u[A][y].length;F<G;F++)w[A][y][F]=(v[A][y][F]-u[A][y][F])/t}}else{var J=d.matrix||new bQ,K={_:{transform:H.transform},getBBox:function(){return d.getBBox(1)}};u[A]=[J.a,J.b,J.c,J.d,J.e,J.f],bN(K,v[A]),v[A]=K._.transform,w[A]=[(K.matrix.a-J.a)/t,(K.matrix.b-J.b)/t,(K.matrix.c-J.c)/t,(K.matrix.d-J.d)/t,(K.matrix.e-J.e)/t,(K.matrix.e-J.f)/t]}break;case"csv":var L=r(j[A])[s](c),M=r(u[A])[s](c);if(A=="clip-rect"){u[A]=M,w[A]=[],y=M.length;while(y--)w[A][y]=(L[y]-u[A][y])/t}v[A]=L;break;default:L=[][n](j[A]),M=[][n](u[A]),w[A]=[],y=d.paper.customAttributes[A].length;while(y--)w[A][y]=((L[y]||0)-(M[y]||0))/t}}var O=j.easing,P=a.easing_formulas[O];if(!P){P=r(O).match(N);if(P&&P.length==5){var R=P;P=function(a){return cp(a,+R[1],+R[2],+R[3],+R[4],t)}}else P=be}q=j.start||b.start||+(new Date),x={anim:b,percent:e,timestamp:q,start:q+(b.del||0),status:0,initstatus:f||0,stop:!1,ms:t,easing:P,from:u,diff:w,to:v,el:d,callback:j.callback,prev:p,next:o,repeat:i||b.times,origin:d.attr(),totalOrigin:h},cl.push(x);if(f&&!k&&!l){x.stop=!0,x.start=new Date-t*f;if(cl.length==1)return cn()}l&&(x.start=new Date-x.ms*f),cl.length==1&&cm(cn)}else k.initstatus=f,k.start=new Date-k.ms*f;eve("anim.start."+d.id,d,b)}}function cq(a,b){var c=[],d={};this.ms=b,this.times=1;if(a){for(var e in a)a[g](e)&&(d[Q(e)]=a[e],c.push(Q(e)));c.sort(bc)}this.anim=d,this.top=c[c.length-1],this.percents=c}function cp(a,b,c,d,e,f){function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(z(f)<b)return e;j=(3*i*e+2*h)*e+g;if(z(j)<1e-6)break;e=e-f/j}c=0,d=1,e=a;if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(z(f-a)<b)return e;a>f?c=e:d=e,e=(d-c)/2+c}return e}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function m(a){return((i*a+h)*a+g)*a}var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;return n(a,1/(200*f))}function cd(){return this.x+q+this.y+q+this.width+" × "+this.height}function cc(){return this.x+q+this.y}function bQ(a,b,c,d,e,f){a!=null?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function bw(a){var b=[];for(var c=0,d=a.length;d-2>c;c+=2){var e=[{x:+a[c],y:+a[c+1]},{x:+a[c],y:+a[c+1]},{x:+a[c+2],y:+a[c+3]},{x:+a[c+4],y:+a[c+5]}];d-4==c?(e[0]={x:+a[c-2],y:+a[c-1]},e[3]=e[2]):c&&(e[0]={x:+a[c-2],y:+a[c-1]}),b.push(["C",(-e[0].x+6*e[1].x+e[2].x)/6,(-e[0].y+6*e[1].y+e[2].y)/6,(e[1].x+6*e[2].x-e[3].x)/6,(e[1].y+6*e[2].y-e[3].y)/6,e[2].x,e[2].y])}return b}function bv(){return this.hex}function bt(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),h=d.cache=d.cache||{},i=d.count=d.count||[];if(h[g](f)){bs(i,f);return c?c(h[f]):h[f]}i.length>=1e3&&delete h[i.shift()],i.push(f),h[f]=a[m](b,e);return c?c(h[f]):h[f]}return d}function bs(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function a(c){if(a.is(c,"function"))return b?c():eve.on("DOMload",c);if(a.is(c,E))return a._engine.create[m](a,c.splice(0,3+a.is(c[0],C))).add(c);var d=Array.prototype.slice.call(arguments,0);if(a.is(d[d.length-1],"function")){var e=d.pop();return b?e.call(a._engine.create[m](a,d)):eve.on("DOMload",function(){e.call(a._engine.create[m](a,d))})}return a._engine.create[m](a,arguments)}a.version="2.0.1",a.eve=eve;var b,c=/[, ]+/,d={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},e=/\{(\d+)\}/g,f="prototype",g="hasOwnProperty",h={doc:document,win:window},i={was:Object.prototype[g].call(h.win,"Raphael"),is:h.win.Raphael},j=function(){this.ca=this.customAttributes={}},k,l="appendChild",m="apply",n="concat",o="createTouch"in h.doc,p="",q=" ",r=String,s="split",t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[s](q),u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},v=r.prototype.toLowerCase,w=Math,x=w.max,y=w.min,z=w.abs,A=w.pow,B=w.PI,C="number",D="string",E="array",F="toString",G="fill",H=Object.prototype.toString,I={},J="push",K=a._ISURL=/^url\(['"]?([^\)]+?)['"]?\)$/i,L=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,M={NaN:1,Infinity:1,"-Infinity":1},N=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,O=w.round,P="setAttribute",Q=parseFloat,R=parseInt,S=r.prototype.toUpperCase,T=a._availableAttrs={"arrow-end":"none","arrow-start":"none",blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/","letter-spacing":0,opacity:1,path:"M0,0",r:0,rx:0,ry:0,src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",transform:"",width:0,x:0,y:0},U=a._availableAnimAttrs={blur:C,"clip-rect":"csv",cx:C,cy:C,fill:"colour","fill-opacity":C,"font-size":C,height:C,opacity:C,path:"path",r:C,rx:C,ry:C,stroke:"colour","stroke-opacity":C,"stroke-width":C,transform:"transform",width:C,x:C,y:C},V=/\s*,\s*/,W={hs:1,rg:1},X=/,?([achlmqrstvxz]),?/gi,Y=/([achlmrqstvz])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?\s*,?\s*)+)/ig,Z=/([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?\s*,?\s*)+)/ig,$=/(-?\d*\.?\d*(?:e[\-+]?\d+)?)\s*,?\s*/ig,_=a._radial_gradient=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,ba={},bb=function(a,b){return a.key-b.key},bc=function(a,b){return Q(a)-Q(b)},bd=function(){},be=function(a){return a},bf=a._rectPath=function(a,b,c,d,e){if(e)return[["M",a+e,b],["l",c-e*2,0],["a",e,e,0,0,1,e,e],["l",0,d-e*2],["a",e,e,0,0,1,-e,e],["l",e*2-c,0],["a",e,e,0,0,1,-e,-e],["l",0,e*2-d],["a",e,e,0,0,1,e,-e],["z"]];return[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]]},bg=function(a,b,c,d){d==null&&(d=c);return[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]]},bh=a._getPath={path:function(a){return a.attr("path")},circle:function(a){var b=a.attrs;return bg(b.cx,b.cy,b.r)},ellipse:function(a){var b=a.attrs;return bg(b.cx,b.cy,b.rx,b.ry)},rect:function(a){var b=a.attrs;return bf(b.x,b.y,b.width,b.height,b.r)},image:function(a){var b=a.attrs;return bf(b.x,b.y,b.width,b.height)},text:function(a){var b=a._getBBox();return bf(b.x,b.y,b.width,b.height)}},bi=a.mapPath=function(a,b){if(!b)return a;var c,d,e,f,g,h,i;a=bG(a);for(e=0,g=a.length;e<g;e++){i=a[e];for(f=1,h=i.length;f<h;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d}return a};a._g=h,a.type=h.win.SVGAngle||h.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(a.type=="VML"){var bj=h.doc.createElement("div"),bk;bj.innerHTML='<v:shape adj="1"/>',bk=bj.firstChild,bk.style.behavior="url(#default#VML)";if(!bk||typeof bk.adj!="object")return a.type=p;bj=null}a.svg=!(a.vml=a.type=="VML"),a._Paper=j,a.fn=k=j.prototype=a.prototype,a._id=0,a._oid=0,a.is=function(a,b){b=v.call(b);if(b=="finite")return!M[g](+a);if(b=="array")return a instanceof Array;return b=="null"&&a===null||b==typeof a&&a!==null||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||H.call(a).slice(8,-1).toLowerCase()==b},a.angle=function(b,c,d,e,f,g){if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return(180+w.atan2(-i,-h)*180/B+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)},a.rad=function(a){return a%360*B/180},a.deg=function(a){return a*180/B%360},a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,E)){var e=b.length;while(e--)if(z(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(f<d)return c-f;if(f>b-d)return c-f+b}return c};var bl=a.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=w.random()*16|0,c=a=="x"?b:b&3|8;return c.toString(16)});a.setWindow=function(b){eve("setWindow",a,h.win,b),h.win=b,h.doc=h.win.document,a._engine.initWin&&a._engine.initWin(h.win)};var bm=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write("<body>"),e.close(),d=e.body}catch(f){d=createPopup().document.body}var g=d.createTextRange();bm=bt(function(a){try{d.style.color=r(a).replace(c,p);var b=g.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=h.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",h.doc.body.appendChild(i),bm=bt(function(a){i.style.color=a;return h.doc.defaultView.getComputedStyle(i,p).getPropertyValue("color")})}return bm(b)},bn=function(){return"hsb("+[this.h,this.s,this.b]+")"},bo=function(){return"hsl("+[this.h,this.s,this.l]+")"},bp=function(){return this.hex},bq=function(b,c,d){c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b&&(d=b.b,c=b.g,b=b.r);if(c==null&&a.is(b,D)){var e=a.getRGB(b);b=e.r,c=e.g,d=e.b}if(b>1||c>1||d>1)b/=255,c/=255,d/=255;return[b,c,d]},br=function(b,c,d,e){b*=255,c*=255,d*=255;var f={r:b,g:c,b:d,hex:a.rgb(b,c,d),toString:bp};a.is(e,"finite")&&(f.opacity=e);return f};a.color=function(b){var c;a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b?(c=a.hsb2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b?(c=a.hsl2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):(a.is(b,"string")&&(b=a.getRGB(b)),a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b?(c=a.rgb2hsl(b),b.h=c.h,b.s=c.s,b.l=c.l,c=a.rgb2hsb(b),b.v=c.b):(b={hex:"none"},b.r=b.g=b.b=b.h=b.s=b.v=b.l=-1)),b.toString=bp;return b},a.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,f,g,h,i;a=a%360/60,i=c*b,h=i*(1-z(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return br(e,f,g,d)},a.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h);if(a>1||b>1||c>1)a/=360,b/=100,c/=100;a*=360;var e,f,g,h,i;a=a%360/60,i=2*b*(c<.5?c:1-c),h=i*(1-z(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return br(e,f,g,d)},a.rgb2hsb=function(a,b,c){c=bq(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;f=x(a,b,c),g=f-y(a,b,c),d=g==0?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=g==0?0:g/f;return{h:d,s:e,b:f,toString:bn}},a.rgb2hsl=function(a,b,c){c=bq(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;g=x(a,b,c),h=y(a,b,c),i=g-h,d=i==0?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=i==0?0:f<.5?i/(2*f):i/(2-2*f);return{h:d,s:e,l:f,toString:bo}},a._path2string=function(){return this.join(",").replace(X,"$1")};var bu=a._preload=function(a,b){var c=h.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,h.doc.body.removeChild(this)},c.onerror=function(){h.doc.body.removeChild(this)},h.doc.body.appendChild(c),c.src=a};a.getRGB=bt(function(b){if(!b||!!((b=r(b)).indexOf("-")+1))return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bv};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none",toString:bv};!W[g](b.toLowerCase().substring(0,2))&&b.charAt()!="#"&&(b=bm(b));var c,d,e,f,h,i,j,k=b.match(L);if(k){k[2]&&(f=R(k[2].substring(5),16),e=R(k[2].substring(3,5),16),d=R(k[2].substring(1,3),16)),k[3]&&(f=R((i=k[3].charAt(3))+i,16),e=R((i=k[3].charAt(2))+i,16),d=R((i=k[3].charAt(1))+i,16)),k[4]&&(j=k[4][s](V),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),k[1].toLowerCase().slice(0,4)=="rgba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100));if(k[5]){j=k[5][s](V),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,f,h)}if(k[6]){j=k[6][s](V),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsla"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,f,h)}k={r:d,g:e,b:f,toString:bv},k.hex="#"+(16777216|f|e<<8|d<<16).toString(16).slice(1),a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bv}},a),a.hsb=bt(function(b,c,d){return a.hsb2rgb(b,c,d).hex}),a.hsl=bt(function(b,c,d){return a.hsl2rgb(b,c,d).hex}),a.rgb=bt(function(a,b,c){return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b}));return c.hex},a.getColor.reset=function(){delete this.start},a.parsePathString=bt(function(b){if(!b)return null;var c={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,E)&&a.is(b[0],E)&&(d=by(b)),d.length||r(b).replace(Y,function(a,b,e){var f=[],g=b.toLowerCase();e.replace($,function(a,b){b&&f.push(+b)}),g=="m"&&f.length>2&&(d.push([b][n](f.splice(0,2))),g="l",b=b=="m"?"l":"L");if(g=="r")d.push([b][n](f));else while(f.length>=c[g]){d.push([b][n](f.splice(0,c[g])));if(!c[g])break}}),d.toString=a._path2string;return d}),a.parseTransformString=bt(function(b){if(!b)return null;var c={r:3,s:4,t:2,m:6},d=[];a.is(b,E)&&a.is(b[0],E)&&(d=by(b)),d.length||r(b).replace(Z,function(a,b,c){var e=[],f=v.call(b);c.replace($,function(a,b){b&&e.push(+b)}),d.push([b][n](e))}),d.toString=a._path2string;return d}),a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=A(j,3),l=A(j,2),m=i*i,n=m*i,o=k*a+l*3*i*c+j*3*i*i*e+n*g,p=k*b+l*3*i*d+j*3*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,x=j*e+i*g,y=j*f+i*h,z=90-w.atan2(q-s,r-t)*180/B;(q>s||r<t)&&(z+=180);return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:x,y:y},alpha:z}},a._removedFactory=function(a){return function(){throw new Error("Raphaël: you are calling to method “"+a+"” of removed object")}};var bx=bt(function(a){if(!a)return{x:0,y:0,width:0,height:0};a=bG(a);var b=0,c=0,d=[],e=[],f;for(var g=0,h=a.length;g<h;g++){f=a[g];if(f[0]=="M")b=f[1],c=f[2],d.push(b),e.push(c);else{var i=bF(b,c,f[1],f[2],f[3],f[4],f[5],f[6]);d=d[n](i.min.x,i.max.x),e=e[n](i.min.y,i.max.y),b=f[5],c=f[6]}}var j=y[m](0,d),k=y[m](0,e);return{x:j,y:k,width:x[m](0,d)-j,height:x[m](0,e)-k}},null,function(a){return{x:a.x,y:a.y,width:a.width,height:a.height}}),by=function(b){var c=[];if(!a.is(b,E)||!a.is(b&&b[0],E))b=a.parsePathString(b);for(var d=0,e=b.length;d<e;d++){c[d]=[];for(var f=0,g=b[d].length;f<g;f++)c[d][f]=b[d][f]}c.toString=a._path2string;return c},bz=a._pathToRelative=bt(function(b){if(!a.is(b,E)||!a.is(b&&b[0],E))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;b[0][0]=="M"&&(d=b[0][1],e=b[0][2],f=d,g=e,h++,c.push(["M",d,e]));for(var i=h,j=b.length;i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=v.call(l[0])){k[0]=v.call(l[0]);switch(k[0]){case"a":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]-d).toFixed(3),k[7]=+(l[7]-e).toFixed(3);break;case"v":k[1]=+(l[1]-e).toFixed(3);break;case"m":f=l[1],g=l[2];default:for(var m=1,n=l.length;m<n;m++)k[m]=+(l[m]-(m%2?d:e)).toFixed(3)}}else{k=c[i]=[],l[0]=="m"&&(f=l[1]+d,g=l[2]+e);for(var o=0,p=l.length;o<p;o++)c[i][o]=l[o]}var q=c[i].length;switch(c[i][0]){case"z":d=f,e=g;break;case"h":d+=+c[i][q-1];break;case"v":e+=+c[i][q-1];break;default:d+=+c[i][q-2],e+=+c[i][q-1]}}c.toString=a._path2string;return c},0,by),bA=a._pathToAbsolute=bt(function(b){if(!a.is(b,E)||!a.is(b&&b[0],E))b=a.parsePathString(b);if(!b||!b.length)return[["M",0,0]];var c=[],d=0,e=0,f=0,g=0,h=0;b[0][0]=="M"&&(d=+b[0][1],e=+b[0][2],f=d,g=e,h++,c[0]=["M",d,e]);for(var i,j,k=h,l=b.length;k<l;k++){c.push(i=[]),j=b[k];if(j[0]!=S.call(j[0])){i[0]=S.call(j[0]);switch(i[0]){case"A":i[1]=j[1],i[2]=j[2],i[3]=j[3],i[4]=j[4],i[5]=j[5],i[6]=+(j[6]+d),i[7]=+(j[7]+e);break;case"V":i[1]=+j[1]+e;break;case"H":i[1]=+j[1]+d;break;case"R":var m=[d,e][n](j.slice(1));for(var o=2,p=m.length;o<p;o++)m[o]=+m[o]+d,m[++o]=+m[o]+e;c.pop(),c=c[n](bw(m));break;case"M":f=+j[1]+d,g=+j[2]+e;default:for(o=1,p=j.length;o<p;o++)i[o]=+j[o]+(o%2?d:e)}}else if(j[0]=="R")m=[d,e][n](j.slice(1)),c.pop(),c=c[n](bw(m)),i=["R"][n](j.slice(-2));else for(var q=0,r=j.length;q<r;q++)i[q]=j[q];switch(i[0]){case"Z":d=f,e=g;break;case"H":d=i[1];break;case"V":e=i[1];break;case"M":f=i[i.length-2],g=i[i.length-1];default:d=i[i.length-2],e=i[i.length-1]}}c.toString=a._path2string;return c},null,by),bB=function(a,b,c,d){return[a,b,c,d,c,d]},bC=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},bD=function(a,b,c,d,e,f,g,h,i,j){var k=B*120/180,l=B/180*(+e||0),m=[],o,p=bt(function(a,b,c){var d=a*w.cos(c)-b*w.sin(c),e=a*w.sin(c)+b*w.cos(c);return{x:d,y:e}});if(!j){o=p(a,b,-l),a=o.x,b=o.y,o=p(h,i,-l),h=o.x,i=o.y;var q=w.cos(B/180*e),r=w.sin(B/180*e),t=(a-h)/2,u=(b-i)/2,v=t*t/(c*c)+u*u/(d*d);v>1&&(v=w.sqrt(v),c=v*c,d=v*d);var x=c*c,y=d*d,A=(f==g?-1:1)*w.sqrt(z((x*y-x*u*u-y*t*t)/(x*u*u+y*t*t))),C=A*c*u/d+(a+h)/2,D=A*-d*t/c+(b+i)/2,E=w.asin(((b-D)/d).toFixed(9)),F=w.asin(((i-D)/d).toFixed(9));E=a<C?B-E:E,F=h<C?B-F:F,E<0&&(E=B*2+E),F<0&&(F=B*2+F),g&&E>F&&(E=E-B*2),!g&&F>E&&(F=F-B*2)}else E=j[0],F=j[1],C=j[2],D=j[3];var G=F-E;if(z(G)>k){var H=F,I=h,J=i;F=E+k*(g&&F>E?1:-1),h=C+c*w.cos(F),i=D+d*w.sin(F),m=bD(h,i,c,d,e,0,g,I,J,[F,H,C,D])}G=F-E;var K=w.cos(E),L=w.sin(E),M=w.cos(F),N=w.sin(F),O=w.tan(G/4),P=4/3*c*O,Q=4/3*d*O,R=[a,b],S=[a+P*L,b-Q*K],T=[h+P*N,i-Q*M],U=[h,i];S[0]=2*R[0]-S[0],S[1]=2*R[1]-S[1];if(j)return[S,T,U][n](m);m=[S,T,U][n](m).join()[s](",");var V=[];for(var W=0,X=m.length;W<X;W++)V[W]=W%2?p(m[W-1],m[W],l).y:p(m[W],m[W+1],l).x;return V},bE=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:A(j,3)*a+A(j,2)*3*i*c+j*3*i*i*e+A(i,3)*g,y:A(j,3)*b+A(j,2)*3*i*d+j*3*i*i*f+A(i,3)*h}},bF=bt(function(a,b,c,d,e,f,g,h){var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+w.sqrt(j*j-4*i*k))/2/i,n=(-j-w.sqrt(j*j-4*i*k))/2/i,o=[b,h],p=[a,g],q;z(l)>"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bE(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bE(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y)),i=f-2*d+b-(h-2*f+d),j=2*(d-b)-2*(f-d),k=b-d,l=(-j+w.sqrt(j*j-4*i*k))/2/i,n=(-j-w.sqrt(j*j-4*i*k))/2/i,z(l)>"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bE(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bE(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y));return{min:{x:y[m](0,p),y:y[m](0,o)},max:{x:x[m](0,p),y:x[m](0,o)}}}),bG=a._path2curve=bt(function(a,b){var c=bA(a),d=b&&bA(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][n](bD[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x)),d=b.y+(b.y-(b.by||b.y)),a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x)),b.qy=b.y+(b.y-(b.qy||b.y)),a=["C"][n](bC(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][n](bC(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](bB(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](bB(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](bB(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](bB(b.x,b.y,b.X,b.Y))}return a},h=function(a,b){if(a[b].length>7){a[b].shift();var e=a[b];while(e.length)a.splice(b++,0,["C"][n](e.splice(0,6)));a.splice(b,1),k=x(c.length,d&&d.length||0)}},i=function(a,b,e,f,g){a&&b&&a[g][0]=="M"&&b[g][0]!="M"&&(b.splice(g,0,["M",f.x,f.y]),e.bx=0,e.by=0,e.x=a[g][1],e.y=a[g][2],k=x(c.length,d&&d.length||0))};for(var j=0,k=x(c.length,d&&d.length||0);j<k;j++){c[j]=g(c[j],e),h(c,j),d&&(d[j]=g(d[j],f)),d&&h(d,j),i(c,d,e,f,j),i(d,c,f,e,j);var l=c[j],o=d&&d[j],p=l.length,q=d&&o.length;e.x=l[p-2],e.y=l[p-1],e.bx=Q(l[p-4])||e.x,e.by=Q(l[p-3])||e.y,f.bx=d&&(Q(o[q-4])||f.x),f.by=d&&(Q(o[q-3])||f.y),f.x=d&&o[q-2],f.y=d&&o[q-1]}return d?[c,d]:c},null,by),bH=a._parseDots=bt(function(b){var c=[];for(var d=0,e=b.length;d<e;d++){var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);if(f.color.error)return null;f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),c.push(f)}for(d=1,e=c.length-1;d<e;d++)if(!c[d].offset){var h=Q(c[d-1].offset||0),i=0;for(var j=d+1;j<e;j++)if(c[j].offset){i=c[j].offset;break}i||(i=100,j=e),i=Q(i);var k=(i-h)/(j-d+1);for(;d<j;d++)h+=k,c[d].offset=h+"%"}return c}),bI=a._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)},bJ=a._tofront=function(a,b){b.top!==a&&(bI(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},bK=a._toback=function(a,b){b.bottom!==a&&(bI(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},bL=a._insertafter=function(a,b,c){bI(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},bM=a._insertbefore=function(a,b,c){bI(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},bN=a._extractTransform=function(b,c){if(c==null)return b._.transform;c=r(c).replace(/\.{3}|\u2026/g,b._.transform||p);var d=a.parseTransformString(c),e=0,f=0,g=0,h=1,i=1,j=b._,k=new bQ;j.transform=d||[];if(d)for(var l=0,m=d.length;l<m;l++){var n=d[l],o=n.length,q=r(n[0]).toLowerCase(),s=n[0]!=q,t=s?k.invert():0,u,v,w,x,y;q=="t"&&o==3?s?(u=t.x(0,0),v=t.y(0,0),w=t.x(n[1],n[2]),x=t.y(n[1],n[2]),k.translate(w-u,x-v)):k.translate(n[1],n[2]):q=="r"?o==2?(y=y||b.getBBox(1),k.rotate(n[1],y.x+y.width/2,y.y+y.height/2),e+=n[1]):o==4&&(s?(w=t.x(n[2],n[3]),x=t.y(n[2],n[3]),k.rotate(n[1],w,x)):k.rotate(n[1],n[2],n[3]),e+=n[1]):q=="s"?o==2||o==3?(y=y||b.getBBox(1),k.scale(n[1],n[o-1],y.x+y.width/2,y.y+y.height/2),h*=n[1],i*=n[o-1]):o==5&&(s?(w=t.x(n[3],n[4]),x=t.y(n[3],n[4]),k.scale(n[1],n[2],w,x)):k.scale(n[1],n[2],n[3],n[4]),h*=n[1],i*=n[2]):q=="m"&&o==7&&k.add(n[1],n[2],n[3],n[4],n[5],n[6]),j.dirtyT=1,b.matrix=k}b.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,h==1&&i==1&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1},bO=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return a.length==4?[b,0,a[2],a[3]]:[b,0];case"s":return a.length==5?[b,1,1,a[3],a[4]]:a.length==3?[b,1,1]:[b,1]}},bP=a._equaliseTransform=function(b,c){c=r(c).replace(/\.{3}|\u2026/g,b),b=a.parseTransformString(b)||[],c=a.parseTransformString(c)||[];var d=x(b.length,c.length),e=[],f=[],g=0,h,i,j,k;for(;g<d;g++){j=b[g]||bO(c[g]),k=c[g]||bO(j);if(j[0]!=k[0]||j[0].toLowerCase()=="r"&&(j[2]!=k[2]||j[3]!=k[3])||j[0].toLowerCase()=="s"&&(j[3]!=k[3]||j[4]!=k[4]))return;e[g]=[],f[g]=[];for(h=0,i=x(j.length,k.length);h<i;h++)h in j&&(e[g][h]=j[h]),h in k&&(f[g][h]=k[h])}return{from:e,to:f}};a._getContainer=function(b,c,d,e){var f;f=e==null&&!a.is(b,"object")?h.doc.getElementById(b):b;if(f!=null){if(f.tagName)return c==null?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d};return{container:1,x:b,y:c,width:d,height:e}}},a.pathToRelative=bz,a._engine={},a.path2curve=bG,a.matrix=function(a,b,c,d,e,f){return new bQ(a,b,c,d,e,f)},function(b){function d(a){var b=w.sqrt(c(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}function c(a){return a[0]*a[0]+a[1]*a[1]}b.add=function(a,b,c,d,e,f){var g=[[],[],[]],h=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],i=[[a,c,e],[b,d,f],[0,0,1]],j,k,l,m;a&&a instanceof bQ&&(i=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]);for(j=0;j<3;j++)for(k=0;k<3;k++){m=0;for(l=0;l<3;l++)m+=h[j][l]*i[l][k];g[j][k]=m}this.a=g[0][0],this.b=g[1][0],this.c=g[0][1],this.d=g[1][1],this.e=g[0][2],this.f=g[1][2]},b.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new bQ(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},b.clone=function(){return new bQ(this.a,this.b,this.c,this.d,this.e,this.f)},b.translate=function(a,b){this.add(1,0,0,1,a,b)},b.scale=function(a,b,c,d){b==null&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},b.rotate=function(b,c,d){b=a.rad(b),c=c||0,d=d||0;var e=+w.cos(b).toFixed(9),f=+w.sin(b).toFixed(9);this.add(e,f,-f,e,c,d),this.add(1,0,0,1,-c,-d)},b.x=function(a,b){return a*this.a+b*this.c+this.e},b.y=function(a,b){return a*this.b+b*this.d+this.f},b.get=function(a){return+this[r.fromCharCode(97+a)].toFixed(4)},b.toString=function(){return a.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},b.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},b.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},b.split=function(){var b={};b.dx=this.e,b.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];b.scalex=w.sqrt(c(e[0])),d(e[0]),b.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*b.shear,e[1][1]-e[0][1]*b.shear],b.scaley=w.sqrt(c(e[1])),d(e[1]),b.shear/=b.scaley;var f=-e[0][1],g=e[1][1];g<0?(b.rotate=a.deg(w.acos(g)),f<0&&(b.rotate=360-b.rotate)):b.rotate=a.deg(w.asin(f)),b.isSimple=!+b.shear.toFixed(9)&&(b.scalex.toFixed(9)==b.scaley.toFixed(9)||!b.rotate),b.isSuperSimple=!+b.shear.toFixed(9)&&b.scalex.toFixed(9)==b.scaley.toFixed(9)&&!b.rotate,b.noRotation=!+b.shear.toFixed(9)&&!b.rotate;return b},b.toTransformString=function(a){var b=a||this[s]();if(b.isSimple){b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4);return(b.dx&&b.dy?"t"+[b.dx,b.dy]:p)+(b.scalex!=1||b.scaley!=1?"s"+[b.scalex,b.scaley,0,0]:p)+(b.rotate?"r"+[b.rotate,0,0]:p)}return"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(bQ.prototype);var bR=navigator.userAgent.match(/Version\/(.*?)\s/)||navigator.userAgent.match(/Chrome\/(\d+)/);navigator.vendor=="Apple Computer, Inc."&&(bR&&bR[1]<4||navigator.platform.slice(0,2)=="iP")||navigator.vendor=="Google Inc."&&bR&&bR[1]<8?k.safari=function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});setTimeout(function(){a.remove()})}:k.safari=bd;var bS=function(){this.returnValue=!1},bT=function(){return this.originalEvent.preventDefault()},bU=function(){this.cancelBubble=!0},bV=function(){return this.originalEvent.stopPropagation()},bW=function(){if(h.doc.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,f=function(e){var f=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,i=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft,j=e.clientX+i,k=e.clientY+f;if(o&&u[g](b))for(var l=0,m=e.targetTouches&&e.targetTouches.length;l<m;l++)if(e.targetTouches[l].target==a){var n=e;e=e.targetTouches[l],e.originalEvent=n,e.preventDefault=bT,e.stopPropagation=bV;break}return c.call(d,e,j,k)};a.addEventListener(e,f,!1);return function(){a.removeEventListener(e,f,!1);return!0}};if(h.doc.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.win.event;var b=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,e=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;a.preventDefault=a.preventDefault||bS,a.stopPropagation=a.stopPropagation||bU;return c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return!0};return f}}(),bX=[],bY=function(a){var b=a.clientX,c=a.clientY,d=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,e=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft,f,g=bX.length;while(g--){f=bX[g];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];if(j.identifier==f.el._drag.id){b=j.clientX,c=j.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();var k=f.el.node,l,m=k.nextSibling,n=k.parentNode,p=k.style.display;h.win.opera&&n.removeChild(k),k.style.display="none",l=f.el.paper.getElementByPoint(b,c),k.style.display=p,h.win.opera&&(m?n.insertBefore(k,m):n.appendChild(k)),l&&eve("drag.over."+f.el.id,f.el,l),b+=e,c+=d,eve("drag.move."+f.el.id,f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},bZ=function(b){a.unmousemove(bY).unmouseup(bZ);var c=bX.length,d;while(c--)d=bX[c],d.el._drag={},eve("drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,b);bX=[]},b$=a.el={};for(var b_=t.length;b_--;)(function(b){a[b]=b$[b]=function(c,d){a.is(c,"function")&&(this.events=this.events||[],this.events.push({name:b,f:c,unbind:bW(this.shape||this.node||h.doc,b,c,d||this)}));return this},a["un"+b]=b$["un"+b]=function(a){var c=this.events,d=c.length;while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind(),c.splice(d,1),!c.length&&delete this.events;return this}return this}})(t[b_]);b$.data=function(b,c){var d=ba[this.id]=ba[this.id]||{};if(arguments.length==1){if(a.is(b,"object")){for(var e in b)b[g](e)&&this.data(e,b[e]);return this}eve("data.get."+this.id,this,d[b],b);return d[b]}d[b]=c,eve("data.set."+this.id,this,c,b);return this},b$.removeData=function(a){a==null?ba[this.id]={}:ba[this.id]&&delete ba[this.id][a];return this},b$.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},b$.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var ca=[];b$.drag=function(b,c,d,e,f,g){function i(i){(i.originalEvent||i).preventDefault();var j=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,k=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft;this._drag.x=i.clientX+k,this._drag.y=i.clientY+j,this._drag.id=i.identifier,!bX.length&&a.mousemove(bY).mouseup(bZ),bX.push({el:this,move_scope:e,start_scope:f,end_scope:g}),c&&eve.on("drag.start."+this.id,c),b&&eve.on("drag.move."+this.id,b),d&&eve.on("drag.end."+this.id,d),eve("drag.start."+this.id,f||e||this,i.clientX+k,i.clientY+j,i)}this._drag={},ca.push({el:this,start:i}),this.mousedown(i);return this},b$.onDragOver=function(a){a?eve.on("drag.over."+this.id,a):eve.unbind("drag.over."+this.id)},b$.undrag=function(){var b=ca.length;while(b--)ca[b].el==this&&(this.unmousedown(ca[b].start),ca.splice(b,1),eve.unbind("drag.*."+this.id));!ca.length&&a.unmousemove(bY).unmouseup(bZ)},k.circle=function(b,c,d){var e=a._engine.circle(this,b||0,c||0,d||0);this.__set__&&this.__set__.push(e);return e},k.rect=function(b,c,d,e,f){var g=a._engine.rect(this,b||0,c||0,d||0,e||0,f||0);this.__set__&&this.__set__.push(g);return g},k.ellipse=function(b,c,d,e){var f=a._engine.ellipse(this,b||0,c||0,d||0,e||0);this.__set__&&this.__set__.push(f);return f},k.path=function(b){b&&!a.is(b,D)&&!a.is(b[0],E)&&(b+=p);var c=a._engine.path(a.format[m](a,arguments),this);this.__set__&&this.__set__.push(c);return c},k.image=function(b,c,d,e,f){var g=a._engine.image(this,b||"about:blank",c||0,d||0,e||0,f||0);this.__set__&&this.__set__.push(g);return g},k.text=function(b,c,d){var e=a._engine.text(this,b||0,c||0,r(d));this.__set__&&this.__set__.push(e);return e},k.set=function(b){!a.is(b,"array")&&(b=Array.prototype.splice.call(arguments,0,arguments.length));var c=new cs(b);this.__set__&&this.__set__.push(c);return c},k.setStart=function(a){this.__set__=a||this.set()},k.setFinish=function(a){var b=this.__set__;delete this.__set__;return b},k.setSize=function(b,c){return a._engine.setSize.call(this,b,c)},k.setViewBox=function(b,c,d,e,f){return a._engine.setViewBox.call(this,b,c,d,e,f)},k.top=k.bottom=null,k.raphael=a;var cb=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,i=b.top+(h.win.pageYOffset||e.scrollTop||d.scrollTop)-f,j=b.left+(h.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:i,x:j}};k.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=h.doc.elementFromPoint(a,b);if(h.win.opera&&e.tagName=="svg"){var f=cb(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var i=d.getIntersectionList(g,null);i.length&&(e=i[i.length-1])}if(!e)return null;while(e.parentNode&&e!=d.parentNode&&!e.raphael)e=e.parentNode;e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null;return e},k.getById=function(a){var b=this.bottom;while(b){if(b.id==a)return b;b=b.next}return null},k.forEach=function(a,b){var c=this.bottom;while(c){if(a.call(b,c)===!1)return this;c=c.next}return this},b$.getBBox=function(a){if(this.removed)return{};var b=this._;if(a){if(b.dirty||!b.bboxwt)this.realPath=bh[this.type](this),b.bboxwt=bx(this.realPath),b.bboxwt.toString=cd,b.dirty=0;return b.bboxwt}if(b.dirty||b.dirtyT||!b.bbox){if(b.dirty||!this.realPath)b.bboxwt=0,this.realPath=bh[this.type](this);b.bbox=bx(bi(this.realPath,this.matrix)),b.bbox.toString=cd,b.dirty=b.dirtyT=0}return b.bbox},b$.clone=function(){if(this.removed)return null;var a=this.paper[this.type]().attr(this.attr());this.__set__&&this.__set__.push(a);return a},b$.glow=function(a){if(this.type=="text")return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:a.opacity||.5,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||bh[this.type](this);f=this.matrix?bi(f,this.matrix):f;for(var g=1;g<c+1;g++)e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var ce={},cf=function(b,c,d,e,f,g,h,i,j){var k=0,l=100,m=[b,c,d,e,f,g,h,i].join(),n=ce[m],o,p;!n&&(ce[m]=n={data:[]}),n.timer&&clearTimeout(n.timer),n.timer=setTimeout(function(){delete ce[m]},2e3);if(j!=null&&!n.precision){var q=cf(b,c,d,e,f,g,h,i);n.precision=~~q*10,n.data=[]}l=n.precision||l;for(var r=0;r<l+1;r++){n.data[r*l]?p=n.data[r*l]:(p=a.findDotsAtSegment(b,c,d,e,f,g,h,i,r/l),n.data[r*l]=p),r&&(k+=A(A(o.x-p.x,2)+A(o.y-p.y,2),.5));if(j!=null&&k>=j)return p;o=p}if(j==null)return k},cg=function(b,c){return function(d,e,f){d=bG(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M")g=+i[1],h=+i[2];else{j=cf(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cf(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),k+=["C"+m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k,k=["M"+m.x,m.y+"C"+m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!b&&!c){m=cf(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j,g=+i[5],h=+i[6]}k+=i.shift()+i}l.end=k,m=b?n:c?l:a.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},ch=cg(1),ci=cg(),cj=cg(0,1);a.getTotalLength=ch,a.getPointAtLength=ci,a.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return cj(a,b).end;var d=cj(a,c,1);return b?cj(d,b).end:d},b$.getTotalLength=function(){if(this.type=="path"){if(this.node.getTotalLength)return this.node.getTotalLength();return ch(this.attrs.path)}},b$.getPointAtLength=function(a){if(this.type=="path")return ci(this.attrs.path,a)},b$.getSubpath=function(b,c){if(this.type=="path")return a.getSubpath(this.attrs.path,b,c)};var ck=a.easing_formulas={linear:function(a){return a},"<":function(a){return A(a,1.7)},">":function(a){return A(a,.48)},"<>":function(a){var b=.48-a/1.04,c=w.sqrt(.1734+b*b),d=c-b,e=A(z(d),1/3)*(d<0?-1:1),f=-c-b,g=A(z(f),1/3)*(f<0?-1:1),h=e+g+.5;return(1-h)*3*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==!!a)return a;return A(2,-10*a)*w.sin((a-.075)*2*B/.3)+1},bounce:function(a){var b=7.5625,c=2.75,d;a<1/c?d=b*a*a:a<2/c?(a-=1.5/c,d=b*a*a+.75):a<2.5/c?(a-=2.25/c,d=b*a*a+.9375):(a-=2.625/c,d=b*a*a+.984375);return d}};ck.easeIn=ck["ease-in"]=ck["<"],ck.easeOut=ck["ease-out"]=ck[">"],ck.easeInOut=ck["ease-in-out"]=ck["<>"],ck["back-in"]=ck.backIn,ck["back-out"]=ck.backOut;var cl=[],cm=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},cn=function(){var b=+(new Date),c=0;for(;c<cl.length;c++){var d=cl[c];if(d.el.removed||d.paused)continue;var e=b-d.start,f=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,o={},p,r={},s;d.initstatus?(e=(d.initstatus*d.anim.top-d.prev)/(d.percent-d.prev)*f,d.status=d.initstatus,delete d.initstatus,d.stop&&cl.splice(c--,1)):d.status=(d.prev+(d.percent-d.prev)*(e/f))/d.anim.top;if(e<0)continue;if(e<f){var t=h(e/f);for(var u in i)if(i[g](u)){switch(U[u]){case C:p=+i[u]+t*f*j[u];break;case"colour":p="rgb("+[co(O(i[u].r+t*f*j[u].r)),co(O(i[u].g+t*f*j[u].g)),co(O(i[u].b+t*f*j[u].b))].join(",")+")";break;case"path":p=[];for(var v=0,w=i[u].length;v<w;v++){p[v]=[i[u][v][0]];for(var x=1,y=i[u][v].length;x<y;x++)p[v][x]=+i[u][v][x]+t*f*j[u][v][x];p[v]=p[v].join(q)}p=p.join(q);break;case"transform":if(j[u].real){p=[];for(v=0,w=i[u].length;v<w;v++){p[v]=[i[u][v][0]];for(x=1,y=i[u][v].length;x<y;x++)p[v][x]=i[u][v][x]+t*f*j[u][v][x]}}else{var z=function(a){return+i[u][a]+t*f*j[u][a]};p=[["m",z(0),z(1),z(2),z(3),z(4),z(5)]]}break;case"csv":if(u=="clip-rect"){p=[],v=4;while(v--)p[v]=+i[u][v]+t*f*j[u][v]}break;default:var A=[][n](i[u]);p=[],v=m.paper.customAttributes[u].length;while(v--)p[v]=+A[v]+t*f*j[u][v]}o[u]=p}m.attr(o),function(a,b,c){setTimeout(function(){eve("anim.frame."+a,b,c)})}(m.id,m,d.anim)}else{(function(b,c,d){setTimeout(function(){eve("anim.frame."+c.id,c,d),eve("anim.finish."+c.id,c,d),a.is(b,"function")&&b.call(c)})})(d.callback,m,d.anim),m.attr(k),cl.splice(c--,1);if(d.repeat>1&&!d.next){for(s in k)k[g](s)&&(r[s]=d.totalOrigin[s]);d.el.attr(r),cr(d.anim,d.el,d.anim.percents[0],null,d.totalOrigin,d.repeat-1)}d.next&&!d.stop&&cr(d.anim,d.el,d.next,null,d.totalOrigin,d.repeat)}}a.svg&&m&&m.paper&&m.paper.safari(),cl.length&&cm(cn)},co=function(a){return a>255?255:a<0?0:a};b$.animateWith=function(b,c,d,e,f,g){var h=d?a.animation(d,e,f,g):c,i=b.status(c);return this.animate(h).status(h,i*c.ms/h.ms)},b$.onAnimation=function(a){a?eve.on("anim.frame."+this.id,a):eve.unbind("anim.frame."+this.id);return this},cq.prototype.delay=function(a){var b=new cq(this.anim,this.ms);b.times=this.times,b.del=+a||0;return b},cq.prototype.repeat=function(a){var b=new cq(this.anim,this.ms);b.del=this.del,b.times=w.floor(x(a,0))||1;return b},a.animation=function(b,c,d,e){if(b instanceof cq)return b;if(a.is(d,"function")||!d)e=e||d||null,d=null;b=Object(b),c=+c||0;var f={},h,i;for(i in b)b[g](i)&&Q(i)!=i&&Q(i)+"%"!=i&&(h=!0,f[i]=b[i]);if(!h)return new cq(b,c);d&&(f.easing=d),e&&(f.callback=e);return new cq({100:f},c)},b$.animate=function(b,c,d,e){var f=this;if(f.removed){e&&e.call(f);return f}var g=b instanceof cq?b:a.animation(b,c,d,e);cr(g,f,g.percents[0],null,f.attr());return f},b$.setTime=function(a,b){a&&b!=null&&this.status(a,y(b,a.ms)/a.ms);return this},b$.status=function(a,b){var c=[],d=0,e,f;if(b!=null){cr(a,this,-1,y(b,1));return this}e=cl.length;for(;d<e;d++){f=cl[d];if(f.el.id==this.id&&(!a||f.anim==a)){if(a)return f.status;c.push({anim:f.anim,status:f.status})}}if(a)return 0;return c},b$.pause=function(a){for(var b=0;b<cl.length;b++)cl[b].el.id==this.id&&(!a||cl[b].anim==a)&&eve("anim.pause."+this.id,this,cl[b].anim)!==!1&&(cl[b].paused=!0);return this},b$.resume=function(a){for(var b=0;b<cl.length;b++)if(cl[b].el.id==this.id&&(!a||cl[b].anim==a)){var c=cl[b];eve("anim.resume."+this.id,this,c.anim)!==!1&&(delete c.paused,this.status(c.anim,c.status))}return this},b$.stop=function(a){for(var b=0;b<cl.length;b++)cl[b].el.id==this.id&&(!a||cl[b].anim==a)&&eve("anim.stop."+this.id,this,cl[b].anim)!==!1&&cl.splice(b--,1);return this},b$.toString=function(){return"Raphaël’s object"};var cs=function(a){this.items=[],this.length=0,this.type="set";if(a)for(var b=0,c=a.length;b<c;b++)a[b]&&(a[b].constructor==b$.constructor||a[b].constructor==cs)&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},ct=cs.prototype;ct.push=function(){var a,b;for(var c=0,d=arguments.length;c<d;c++)a=arguments[c],a&&(a.constructor==b$.constructor||a.constructor==cs)&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},ct.pop=function(){this.length&&delete this[this.length--];return this.items.pop()},ct.forEach=function(a,b){for(var c=0,d=this.items.length;c<d;c++)if(a.call(b,this.items[c],c)===!1)return this;return this};for(var cu in b$)b$[g](cu)&&(ct[cu]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][m](c,b)})}}(cu));ct.attr=function(b,c){if(b&&a.is(b,E)&&a.is(b[0],"object"))for(var d=0,e=b.length;d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items.length;f<g;f++)this.items[f].attr(b,c);return this},ct.clear=function(){while(this.length)this.pop()},ct.splice=function(a,b,c){a=a<0?x(this.length+a,0):a,b=x(0,y(this.length-a,b));var d=[],e=[],f=[],g;for(g=2;g<arguments.length;g++)f.push(arguments[g]);for(g=0;g<b;g++)e.push(this[a+g]);for(;g<this.length-a;g++)d.push(this[a+g]);var h=f.length;for(g=0;g<h+d.length;g++)this.items[a+g]=this[a+g]=g<h?f[g]:d[g-h];g=this.items.length=this.length-=b-h;while(this[g])delete this[g++];return new cs(e)},ct.exclude=function(a){for(var b=0,c=this.length;b<c;b++)if(this[b]==a){this.splice(b,1);return!0}},ct.animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items.length,g=f,h,i=this,j;if(!f)return this;e&&(j=function(){!--f&&e.call(i)}),d=a.is(d,D)?d:j;var k=a.animation(b,c,d,j);h=this.items[--g].animate(k);while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,k);return this},ct.insertAfter=function(a){var b=this.items.length;while(b--)this.items[b].insertAfter(a);return this},ct.getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}a=y[m](0,a),b=y[m](0,b);return{x:a,y:b,width:x[m](0,c)-a,height:x[m](0,d)-b}},ct.clone=function(a){a=new cs;for(var b=0,c=this.items.length;b<c;b++)a.push(this.items[b].clone());return a},ct.toString=function(){return"Raphaël‘s set"},a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[g](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=R(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[g](e)){var f=a.glyphs[e];b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a]||"M"})+"z"};if(f.k)for(var h in f.k)f[g](h)&&(b.glyphs[e].k[h]=f.k[h])}}return a},k.getFont=function(b,c,d,e){e=e||"normal",d=d||"normal",c=+c||{normal:400,bold:700,lighter:300,bolder:800}[c]||400;if(!!a.fonts){var f=a.fonts[b];if(!f){var h=new RegExp("(^|\\s)"+b.replace(/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[g](i)&&h.test(i)){f=a.fonts[i];break}}var j;if(f)for(var k=0,l=f.length;k<l;k++){j=f[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j}},k.print=function(b,d,e,f,g,h,i){h=h||"middle",i=x(y(i||0,1),-1);var j=this.set(),k=r(e)[s](p),l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];var o=f.face.bbox[s](c),q=+o[0],t=+o[1]+(h=="baseline"?o[3]-o[1]+ +f.face.descent:(o[3]-o[1])/2);for(var u=0,v=k.length;u<v;u++){var w=u&&f.glyphs[k[u-1]]||{},z=f.glyphs[k[u]];l+=u?(w.w||f.w)+(w.k&&w.k[k[u]]||0)+f.w*i:0,z&&z.d&&j.push(this.path(z.d).attr({fill:"#000",stroke:"none",transform:[["t",l*n,0]]}))}j.transform(["...s",n,n,q,t,"t",(b-q)/n,(d-t)/n])}return j},k.add=function(b){if(a.is(b,"array")){var c=this.set(),e=0,f=b.length,h;for(;e<f;e++)h=b[e]||{},d[g](h.type)&&c.push(this[h.type]().attr(h))}return c},a.format=function(b,c){var d=a.is(c,E)?[0][n](c):arguments;b&&a.is(b,D)&&d.length-1&&(b=b.replace(e,function(a,b){return d[++b]==null?p:d[b]}));return b||p},a.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),typeof e=="function"&&f&&(e=e()))}),e=(e==null||e==d?a:e)+"";return e};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}}(),a.ninja=function(){i.was?h.win.Raphael=i.is:delete Raphael;return a},a.st=ct,function(b,c,d){function e(){/in/.test(b.readyState)?setTimeout(e,9):a.eve("DOMload")}b.readyState==null&&b.addEventListener&&(b.addEventListener(c,d=function(){b.removeEventListener(c,d,!1),b.readyState="complete"},!1),b.readyState="loading"),e()}(document,"DOMContentLoaded"),i.was?h.win.Raphael=a:Raphael=a,eve.on("DOMload",function(){b=!0})}(),window.Raphael.svg&&function(a){var b="hasOwnProperty",c=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=a.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};a.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var q=function(d,e){if(e){typeof d=="string"&&(d=q(d));for(var f in e)e[b](f)&&(f.substring(0,6)=="xlink:"?d.setAttributeNS(n,f.substring(6),c(e[f])):d.setAttribute(f,c(e[f])))}else d=a._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r=function(b,e){var j="linear",k=b.id+e,m=.5,n=.5,o=b.node,p=b.paper,r=o.style,s=a._g.doc.getElementById(k);if(!s){e=c(e).replace(a._radial_gradient,function(a,b,c){j="radial";if(b&&c){m=d(b),n=d(c);var e=(n>.5)*2-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&n!=.5&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/);if(j=="linear"){var t=e.shift();t=-d(t);if(isNaN(t))return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=a._parseDots(e);if(!w)return null;k=k.replace(/[\(\)\s,\xb0#]/g,"_"),b.gradient&&k!=b.gradient.id&&(p.defs.removeChild(b.gradient),delete b.gradient);if(!b.gradient){s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,j=="radial"?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;x<y;x++)s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff"}))}}q(o,{fill:"url(#"+k+")",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1;return 1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},t=function(d,e,f){if(d.type=="path"){var g=c(e).toLowerCase().split("-"),h=d.paper,i=f?"end":"start",j=d.node,k=d.attrs,l=k["stroke-width"],n=g.length,r="classic",s,t,u,v,w,x=3,y=3,z=5;while(n--)switch(g[n]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":r=g[n];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2}r=="open"?(x+=2,y+=2,z+=2,u=1,v=f?4:1,w={fill:"none",stroke:k.stroke}):(v=u=x/2,w={fill:k.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={};if(r!="none"){var A="raphael-marker-"+r,B="raphael-marker-"+i+r+x+y;a._g.doc.getElementById(A)?p[A]++:(h.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[r],id:A})),p[A]=1);var C=a._g.doc.getElementById(B),D;C?(p[B]++,D=C.getElementsByTagName("use")[0]):(C=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:v,refY:y/2}),D=q(q("use"),{"xlink:href":"#"+A,transform:(f?" rotate(180 "+x/2+" "+y/2+") ":m)+"scale("+x/z+","+y/z+")","stroke-width":1/((x/z+y/z)/2)}),C.appendChild(D),h.defs.appendChild(C),p[B]=1),q(D,w);var E=u*(r!="diamond"&&r!="oval");f?(s=d._.arrows.startdx*l||0,t=a.getTotalLength(k.path)-E*l):(s=E*l,t=a.getTotalLength(k.path)-(d._.arrows.enddx*l||0)),w={},w["marker-"+i]="url(#"+B+")";if(t||s)w.d=Raphael.getSubpath(k.path,s,t);q(j,w),d._.arrows[i+"Path"]=A,d._.arrows[i+"Marker"]=B,d._.arrows[i+"dx"]=E,d._.arrows[i+"Type"]=r,d._.arrows[i+"String"]=e}else f?(s=d._.arrows.startdx*l||0,t=a.getTotalLength(k.path)-s):(s=0,t=a.getTotalLength(k.path)-(d._.arrows.enddx*l||0)),d._.arrows[i+"Path"]&&q(j,{d:Raphael.getSubpath(k.path,s,t)}),delete d._.arrows[i+"Path"],delete d._.arrows[i+"Marker"],delete d._.arrows[i+"dx"],delete d._.arrows[i+"Type"],delete d._.arrows[i+"String"];for(w in p)if(p[b](w)&&!p[w]){var F=a._g.doc.getElementById(w);F&&F.parentNode.removeChild(F)}}},u={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},v=function(a,b,d){b=u[c(b).toLowerCase()];if(b){var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0}[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=b.length;while(h--)g[h]=b[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f)if(f[b](o)){if(!a._availableAttrs[b](o))continue;var p=f[o];k[o]=p;switch(o){case"blur":d.blur(p);break;case"href":case"title":case"target":var u=i.parentNode;if(u.tagName.toLowerCase()!="a"){var w=q("a");u.insertBefore(w,i),w.appendChild(i),u=w}o=="target"&&p=="blank"?u.setAttributeNS(n,"show","new"):u.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":t(d,p);break;case"arrow-end":t(d,p,1);break;case"clip-rect":var x=c(p).split(j);if(x.length==4){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var z=q("clipPath"),A=q("rect");z.id=a.createUUID(),q(A,{x:x[0],y:x[1],width:x[2],height:x[3]}),z.appendChild(A),d.paper.defs.appendChild(z),q(i,{"clip-path":"url(#"+z.id+")"}),d.clip=A}if(!p){var B=i.getAttribute("clip-path");if(B){var C=a._g.doc.getElementById(B.replace(/(^url\(#|\)$)/g,l));C&&C.parentNode.removeChild(C),q(i,{"clip-path":l}),delete d.clip}}break;case"path":d.type=="path"&&(q(i,{d:p?k.path=a._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case"width":i.setAttribute(o,p),d._.dirty=1;if(k.fx)o="x",p=k.x;else break;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if(o=="rx"&&d.type=="rect")break;case"cx":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"height":i.setAttribute(o,p),d._.dirty=1;if(k.fy)o="y",p=k.y;else break;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if(o=="ry"&&d.type=="rect")break;case"cy":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"r":d.type=="rect"?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":d.type=="image"&&i.setAttributeNS(n,"href",p);break;case"stroke-width":if(d._.sx!=1||d._.sy!=1)p/=g(h(d._.sx),h(d._.sy))||1;d.paper._vbSize&&(p*=d.paper._vbSize),i.setAttribute(o,p),k["stroke-dasharray"]&&v(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"stroke-dasharray":v(d,p,f);break;case"fill":var D=c(p).match(a._ISURL);if(D){z=q("pattern");var F=q("image");z.id=a.createUUID(),q(z,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(F,{x:0,y:0,"xlink:href":D[1]}),z.appendChild(F),function(b){a._preload(D[1],function(){var a=this.offsetWidth,c=this.offsetHeight;q(b,{width:a,height:c}),q(F,{width:a,height:c}),d.paper.safari()})}(z),d.paper.defs.appendChild(z),i.style.fill="url(#"+z.id+")",q(i,{fill:"url(#"+z.id+")"}),d.pattern=z,d.pattern&&s(d);break}var G=a.getRGB(p);if(!G.error)delete f.gradient,delete k.gradient,!a.is(k.opacity,"undefined")&&a.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!a.is(k["fill-opacity"],"undefined")&&a.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});else if((d.type=="circle"||d.type=="ellipse"||c(p).charAt()!="r")&&r(d,p)){if("opacity"in k||"fill-opacity"in k){var H=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(H){var I=H.getElementsByTagName("stop");q(I[I.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}}k.gradient=p,k.fill="none";break}G[b]("opacity")&&q(i,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(p),i.setAttribute(o,G.hex),o=="stroke"&&G[b]("opacity")&&q(i,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity}),o=="stroke"&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":(d.type=="circle"||d.type=="ellipse"||c(p).charAt()!="r")&&r(d,p);break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){H=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),H&&(I=H.getElementsByTagName("stop"),q(I[I.length-1],{"stop-opacity":p}));break};default:o=="font-size"&&(p=e(p,10)+"px");var J=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[J]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if(d.type=="text"&&!!(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){g.text=f.text;while(h.firstChild)h.removeChild(h.firstChild);var j=c(f.text).split("\n"),k=[],m;for(var n=0,o=j.length;n<o;n++)m=q("tspan"),n&&q(m,{dy:i*x,x:g.x}),m.appendChild(a._g.doc.createTextNode(j[n])),h.appendChild(m),k[n]=m}else{k=h.getElementsByTagName("tspan");for(n=0,o=k.length;n<o;n++)n?q(k[n],{dy:i*x,x:g.x}):q(k[0],{dy:0})}q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&a.is(r,"finite")&&q(k[0],{dy:r})}},z=function(b,c){var d=0,e=0;this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.matrix=a.matrix(),this.realPath=null,this.paper=c,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},A=a.el;z.prototype=A,A.constructor=z,a._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new z(c,b);d.type="path",w(d,{fill:"none",stroke:"#000",path:a});return d},A.rotate=function(a,b,e){if(this.removed)return this;a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),e==null&&(b=e);if(b==null||e==null){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}this.transform(this._.transform.concat([["r",a,b,e]]));return this},A.scale=function(a,b,e,f){if(this.removed)return this;a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),b==null&&(b=a),f==null&&(e=f);if(e==null||f==null)var g=this.getBBox(1);e=e==null?g.x+g.width/2:e,f=f==null?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]]));return this},A.translate=function(a,b){if(this.removed)return this;a=c(a).split(j),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this.transform(this._.transform.concat([["t",a,b]]));return this},A.transform=function(c){var d=this._;if(c==null)return d.transform;a._extractTransform(this,c),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix});if(d.sx!=1||d.sy!=1){var e=this.attrs[b]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})}return this},A.hide=function(){!this.removed&&this.paper.safari(this.node.style.display="none");return this},A.show=function(){!this.removed&&this.paper.safari(this.node.style.display="");return this},A.remove=function(){if(!this.removed){var b=this.paper;b.__set__&&b.__set__.exclude(this),k.unbind("*.*."+this.id),this.gradient&&b.defs.removeChild(this.gradient),a._tear(this,b),this.node.parentNode.removeChild(this.node);for(var c in this)this[c]=typeof this[c]=="function"?a._removedFactory(c):null;this.removed=!0}},A._getBBox=function(){if(this.node.style.display=="none"){this.show();var a=!0}var b={};try{b=this.node.getBBox()}catch(c){}finally{b=b||{}}a&&this.hide();return b},A.attr=function(c,d){if(this.removed)return this;if(c==null){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);e.gradient&&e.fill=="none"&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform;return e}if(d==null&&a.is(c,"string")){if(c=="fill"&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;if(c=="transform")return this._.transform;var g=c.split(j),h={};for(var i=0,l=g.length;i<l;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return l-1?h:h[g[0]]}if(d==null&&a.is(c,"array")){h={};for(i=0,l=c.length;i<l;i++)h[c[i]]=this.attr(c[i]);return h}if(d!=null){var m={};m[c]=d}else c!=null&&a.is(c,"object")&&(m=c);for(var n in m)k("attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes)if(this.paper.customAttributes[b](n)&&m[b](n)&&a.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o)o[b](p)&&(m[p]=o[p])}w(this,m);return this},A.toFront=function(){if(this.removed)return this;this.node.parentNode.tagName.toLowerCase()=="a"?this.node.parentNode.parentNode.appendChild(this.node.parentNode):this.node.parentNode.appendChild(this.node);var b=this.paper;b.top!=this&&a._tofront(this,b);return this},A.toBack=function(){if(this.removed)return this;var b=this.node.parentNode;b.tagName.toLowerCase()=="a"?b.parentNode.insertBefore(this.node.parentNode,this.node.parentNode.parentNode.firstChild):b.firstChild!=this.node&&b.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper);var c=this.paper;return this},A.insertAfter=function(b){if(this.removed)return this;var c=b.node||b[b.length-1].node;c.nextSibling?c.parentNode.insertBefore(this.node,c.nextSibling):c.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper);return this},A.insertBefore=function(b){if(this.removed)return this;var c=b.node||b[0].node;c.parentNode.insertBefore(this.node,c),a._insertbefore(this,b,this.paper);return this},A.blur=function(b){var c=this;if(+b!==0){var d=q("filter"),e=q("feGaussianBlur");c.attrs.blur=b,d.id=a.createUUID(),q(e,{stdDeviation:+b||1.5}),d.appendChild(e),c.paper.defs.appendChild(d),c._blur=d,q(c.node,{filter:"url(#"+d.id+")"})}else c._blur&&(c._blur.parentNode.removeChild(c._blur),delete c._blur,delete c.attrs.blur),c.node.removeAttribute("filter")},a._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new z(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs);return f},a._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs);return h},a._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new z(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs);return g},a._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image";return h},a._engine.text=function(b,c,d,e){var f=q("text");b.canvas&&b.canvas.appendChild(f);var g=new z(f,b);g.attrs={x:c,y:d,"text-anchor":"middle",text:e,font:a._availableAttrs.font,stroke:"none",fill:"#000"},g.type="text",w(g,g.attrs);return g},a._engine.setSize=function(a,b){this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox);return this},a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,g=b.height;if(!c)throw new Error("SVG container not found.");var h=q("svg"),i="overflow:hidden;",j;d=d||0,e=e||0,f=f||512,g=g||342,q(h,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg"}),c==1?(h.style.cssText=i+"position:absolute;left:"+d+"px;top:"+e+"px",a._g.doc.body.appendChild(h),j=1):(h.style.cssText=i+"position:relative",c.firstChild?c.insertBefore(h,c.firstChild):c.appendChild(h)),c=new a._Paper,c.width=f,c.height=g,c.canvas=h,c.clear(),c._left=c._top=0,j&&(c.renderfix=function(){}),c.renderfix();return c},a._engine.setViewBox=function(a,b,c,d,e){k("setViewBox",this,this._viewBox,[a,b,c,d,e]);var f=g(c/this.width,d/this.height),h=this.top,i=e?"meet":"xMinYMin",j,l;a==null?(this._vbSize&&(f=1),delete this._vbSize,j="0 0 "+this.width+m+this.height):(this._vbSize=f,j=a+m+b+m+c+m+d),q(this.canvas,{viewBox:j,preserveAspectRatio:i});while(f&&h)l="stroke-width"in h.attrs?h.attrs["stroke-width"]:1,h.attr({"stroke-width":l}),h._.dirty=1,h._.dirtyT=1,h=h.prev;this._viewBox=[a,b,c,d,!!e];return this},a.prototype.renderfix=function(){var a=this.canvas,b=a.style,c=a.getScreenCTM()||a.createSVGMatrix(),d=-c.e%1,e=-c.f%1;if(d||e)d&&(this._left=(this._left+d)%1,b.left=this._left+"px"),e&&(this._top=(this._top+e)%1,b.top=this._top+"px")},a.prototype.clear=function(){a.eve("clear",this);var b=this.canvas;while(b.firstChild)b.removeChild(b.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(a._g.doc.createTextNode("Created with Raphaël "+a.version)),b.appendChild(this.desc),b.appendChild(this.defs=q("defs"))},a.prototype.remove=function(){k("remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]=typeof this[b]=="function"?a._removedFactory(b):null};var B=a.st;for(var C in A)A[b](C)&&!B[b](C)&&(B[C]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(C))}(window.Raphael),window.Raphael.vml&&function(a){var b="hasOwnProperty",c=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=a.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(b){var d=/[ahqstv]/ig,e=a._pathToAbsolute;c(b).match(d)&&(e=a._path2curve),d=/[clmz]/g;if(e==a._pathToAbsolute&&!c(b).match(d)){var g=c(b).replace(q,function(a,b,c){var d=[],e=b.toLowerCase()=="m",g=p[b];c.replace(s,function(a){e&&d.length==2&&(g+=d+p[b=="m"?"l":"L"],d=[]),d.push(f(a*u))});return g+d});return g}var h=e(b),i,j;g=[];for(var k=0,l=h.length;k<l;k++){i=h[k],j=h[k][0].toLowerCase(),j=="z"&&(j="x");for(var m=1,r=i.length;m<r;m++)j+=f(i[m]*u)+(m!=r-1?",":o);g.push(j)}return g.join(n)},y=function(b,c,d){var e=a.matrix();e.rotate(-b,.5,.5);return{dx:e.x(c,d),dy:e.y(c,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q,r=u/b,s=u/c;m.visibility="hidden";if(!!b&&!!c){l.coordsize=i(r)+n+i(s),m.rotation=f*(b*c<0?-1:1);if(f){var t=y(f,d,e);d=t.dx,e=t.dy}b<0&&(p+="x"),c<0&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d*-r+n+e*-s;if(k||g.fillsize){var v=l.getElementsByTagName(j);v=v&&v[0],l.removeChild(v),k&&(t=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),v.position=t.dx*o+n+t.dy*o),g.fillsize&&(v.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(v)}m.visibility="visible"}};a.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};var A=function(a,b,d){var e=c(b).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";while(g--)switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]}var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q,r=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),s=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),t=e;for(var y in i)i[b](y)&&(m[y]=i[y]);r&&(m.path=a._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur);if(i.path&&e.type=="path"||r)l.path=x(~c(m.path).toLowerCase().indexOf("r")?a._pathToAbsolute(m.path):m.path),e.type=="image"&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0));"transform"in i&&e.transform(i.transform);if(s){var B=+m.cx,D=+m.cy,E=+m.rx||+m.r||0,G=+m.ry||+m.r||0;l.path=a.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((B-E)*u),f((D-G)*u),f((B+E)*u),f((D+G)*u),f(B*u))}if("clip-rect"in i){var H=c(i["clip-rect"]).split(k);if(H.length==4){H[2]=+H[2]+ +H[0],H[3]=+H[3]+ +H[1];var I=l.clipRect||a._g.doc.createElement("div"),J=I.style;J.clip=a.format("rect({1}px {2}px {3}px {0}px)",H),l.clipRect||(J.position="absolute",J.top=0,J.left=0,J.width=e.paper.width+"px",J.height=e.paper.height+"px",l.parentNode.insertBefore(I,l),I.appendChild(l),l.clipRect=I)}i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip="auto")}if(e.textpath){var K=e.textpath.style;i.font&&(K.font=i.font),i["font-family"]&&(K.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(K.fontSize=i["font-size"]),i["font-weight"]&&(K.fontWeight=i["font-weight"]),i["font-style"]&&(K.fontStyle=i["font-style"])}"arrow-start"in i&&A(t,i["arrow-start"]),"arrow-end"in i&&A(t,i["arrow-end"],1);if(i.opacity!=null||i["stroke-width"]!=null||i.fill!=null||i.src!=null||i.stroke!=null||i["stroke-width"]!=null||i["stroke-opacity"]!=null||i["fill-opacity"]!=null||i["stroke-dasharray"]!=null||i["stroke-miterlimit"]!=null||i["stroke-linejoin"]!=null||i["stroke-linecap"]!=null){var L=l.getElementsByTagName(j),M=!1;L=L&&L[0],!L&&(M=L=F(j)),e.type=="image"&&i.src&&(L.src=i.src),i.fill&&(L.on=!0);if(L.on==null||i.fill=="none"||i.fill===null)L.on=!1;if(L.on&&i.fill){var N=c(i.fill).match(a._ISURL);if(N){L.parentNode==l&&l.removeChild(L),L.rotate=!0,L.src=N[1],L.type="tile";var O=e.getBBox(1);L.position=O.x+n+O.y,e._.fillpos=[O.x,O.y],a._preload(N[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else L.color=a.getRGB(i.fill).hex,L.src=o,L.type="solid",a.getRGB(i.fill).error&&(t.type in{circle:1,ellipse:1}||c(i.fill).charAt()!="r")&&C(t,i.fill,L)&&(m.fill="none",m.gradient=i.fill,L.rotate=!1)}if("fill-opacity"in i||"opacity"in i){var P=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+a.getRGB(i.fill).o+1||2)-1);P=h(g(P,0),1),L.opacity=P,L.src&&(L.color="none")}l.appendChild(L);var Q=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],T=!1;!Q&&(T=Q=F("stroke"));if(i.stroke&&i.stroke!="none"||i["stroke-width"]||i["stroke-opacity"]!=null||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])Q.on=!0;(i.stroke=="none"||i.stroke===null||Q.on==null||i.stroke==0||i["stroke-width"]==0)&&(Q.on=!1);var U=a.getRGB(i.stroke);Q.on&&i.stroke&&(Q.color=U.hex),P=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+U.o+1||2)-1);var V=(d(i["stroke-width"])||1)*.75;P=h(g(P,0),1),i["stroke-width"]==null&&(V=m["stroke-width"]),i["stroke-width"]&&(Q.weight=V),V&&V<1&&(P*=V)&&(Q.weight=1),Q.opacity=P,i["stroke-linejoin"]&&(Q.joinstyle=i["stroke-linejoin"]||"miter"),Q.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(Q.endcap=i["stroke-linecap"]=="butt"?"flat":i["stroke-linecap"]=="square"?"square":"round");if(i["stroke-dasharray"]){var W={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};Q.dashstyle=W[b](i["stroke-dasharray"])?W[i["stroke-dasharray"]]:o}T&&l.appendChild(Q)}if(t.type=="text"){t.paper.canvas.style.display=o;var X=t.paper.span,Y=100,Z=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=X.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),Z=d(m["font-size"]||Z&&Z[0])||10,p.fontSize=Z*Y+"px",t.textpath.string&&(X.innerHTML=c(t.textpath.string).replace(/</g,"&#60;").replace(/&/g,"&#38;").replace(/\n/g,"<br>"));var $=X.getBoundingClientRect();t.W=m.w=($.right-$.left)/Y,t.H=m.h=($.bottom-$.top)/Y,t.X=m.x,t.Y=m.y+t.H/2,("x"in i||"y"in i)&&(t.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));var _=["x","y","text","font","font-family","font-weight","font-style","font-size"];for(var ba=0,bb=_.length;ba<bb;ba++)if(_[ba]in i){t._.dirty=1;break}switch(m["text-anchor"]){case"start":t.textpath.style["v-text-align"]="left",t.bbx=t.W/2;break;case"end":t.textpath.style["v-text-align"]="right",t.bbx=-t.W/2;break;default:t.textpath.style["v-text-align"]="center",t.bbx=0}t.textpath.style["v-text-kern"]=!0}},C=function(b,f,g){b.attrs=b.attrs||{};var h=b.attrs,i=Math.pow,j,k,l="linear",m=".5 .5";b.attrs.gradient=f,f=c(f).replace(a._radial_gradient,function(a,b,c){l="radial",b&&c&&(b=d(b),c=d(c),i(b-.5,2)+i(c-.5,2)>.25&&(c=e.sqrt(.25-i(b-.5,2))*((c>.5)*2-1)+.5),m=b+n+c);return o}),f=f.split(/\s*\-\s*/);if(l=="linear"){var p=f.shift();p=-d(p);if(isNaN(p))return null}var q=a._parseDots(f);if(!q)return null;b=b.shape||b.node;if(q.length){b.removeChild(g),g.on=!0,g.method="none",g.color=q[0].color,g.color2=q[q.length-1].color;var r=[];for(var s=0,t=q.length;s<t;s++)q[s].offset&&r.push(q[s].offset+n+q[s].color);g.colors=r.length?r.join():"0% "+g.color,l=="radial"?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=m,g.angle=0):(g.type="gradient",g.angle=(270-p)%360),b.appendChild(g)}return 1},D=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=c,this.matrix=a.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},E=a.el;D.prototype=E,E.constructor=D,E.transform=function(b){if(b==null)return this._.transform;var d=this.paper._viewBoxShift,e=d?"s"+[d.scale,d.scale]+"-1-1t"+[d.dx,d.dy]:o,f;d&&(f=b=c(b).replace(/\.{3}|\u2026/g,this._.transform||o)),a._extractTransform(this,e+b);var g=this.matrix.clone(),h=this.skew,i=this.node,j,k=~c(this.attrs.fill).indexOf("-"),l=!c(this.attrs.fill).indexOf("url(");g.translate(-0.5,-0.5);if(l||k||this.type=="image"){h.matrix="1 0 0 1",h.offset="0 0",j=g.split();if(k&&j.noRotation||!j.isSimple){i.style.filter=g.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;i.coordorigin=q*-u+n+r*-u,z(this,1,1,q,r,0)}else i.style.filter=o,z(this,j.scalex,j.scaley,j.dx,j.dy,j.rotate)}else i.style.filter=o,h.matrix=c(g),h.offset=g.offset();f&&(this._.transform=f);return this},E.rotate=function(a,b,e){if(this.removed)return this;if(a!=null){a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),e==null&&(b=e);if(b==null||e==null){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,b,e]]));return this}},E.translate=function(a,b){if(this.removed)return this;a=c(a).split(k),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=b),this.transform(this._.transform.concat([["t",a,b]]));return this},E.scale=function(a,b,e,f){if(this.removed)return this;a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),b==null&&(b=a),f==null&&(e=f);if(e==null||f==null)var g=this.getBBox(1);e=e==null?g.x+g.width/2:e,f=f==null?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this._.dirtyT=1;return this},E.hide=function(){!this.removed&&(this.node.style.display="none");return this},E.show=function(){!this.removed&&(this.node.style.display=o);return this},E._getBBox=function(){if(this.removed)return{};return{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed){this.paper.__set__&&this.paper.__set__.exclude(this),a.eve.unbind("*.*."+this.id),a._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var b in this)this[b]=typeof this[b]=="function"?a._removedFactory(b):null;this.removed=!0}},E.attr=function(c,d){if(this.removed)return this;if(c==null){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);e.gradient&&e.fill=="none"&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform;return e}if(d==null&&a.is(c,"string")){if(c==j&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;var g=c.split(k),h={};for(var i=0,m=g.length;i<m;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return m-1?h:h[g[0]]}if(this.attrs&&d==null&&a.is(c,"array")){h={};for(i=0,m=c.length;i<m;i++)h[c[i]]=this.attr(c[i]);return h}var n;d!=null&&(n={},n[c]=d),d==null&&a.is(c,"object")&&(n=c);for(var o in n)l("attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes)if(this.paper.customAttributes[b](o)&&n[b](o)&&a.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p)p[b](q)&&(n[q]=p[q])}n.text&&this.type=="text"&&(this.textpath.string=n.text),B(this,n)}return this},E.toFront=function(){!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&a._tofront(this,this.paper);return this},E.toBack=function(){if(this.removed)return this;this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper));return this},E.insertAfter=function(b){if(this.removed)return this;b.constructor==a.st.constructor&&(b=b[b.length-1]),b.node.nextSibling?b.node.parentNode.insertBefore(this.node,b.node.nextSibling):b.node.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper);return this},E.insertBefore=function(b){if(this.removed)return this;b.constructor==a.st.constructor&&(b=b[0]),b.node.parentNode.insertBefore(this.node,b.node),a._insertbefore(this,b,this.paper);return this},E.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(r,o),+b!==0?(this.attrs.blur=b,c.filter=d+n+m+".Blur(pixelradius="+(+b||1.5)+")",c.margin=a.format("-{0}px 0 0 -{0}px",f(+b||1.5))):(c.filter=d,c.margin=0,delete this.attrs.blur)},a._engine.path=function(a,b){var c=F("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F("skew");f.on=!0,c.appendChild(f),d.skew=f,d.transform(o);return d},a._engine.rect=function(b,c,d,e,f,g){var h=a._rectPath(c,d,e,f,g),i=b.path(h),j=i.attrs;i.X=j.x=c,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect";return i},a._engine.ellipse=function(a,b,c,d,e){var f=a.path(),g=f.attrs;f.X=b-d,f.Y=c-e,f.W=d*2,f.H=e*2,f.type="ellipse",B(f,{cx:b,cy:c,rx:d,ry:e});return f},a._engine.circle=function(a,b,c,d){var e=a.path(),f=e.attrs;e.X=b-d,e.Y=c-d,e.W=e.H=d*2,e.type="circle",B(e,{cx:b,cy:c,r:d});return e},a._engine.image=function(b,c,d,e,f,g){var h=a._rectPath(d,e,f,g),i=b.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];k.src=c,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=c,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0);return i},a._engine.text=function(b,d,e,g){var h=F("shape"),i=F("path"),j=F("textpath");d=d||0,e=e||0,g=g||"",i.v=a.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=c(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new D(h,b),l={fill:"#000",stroke:"none",font:a._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=c(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),b.canvas.appendChild(h);var m=F("skew");m.on=!0,h.appendChild(m),k.skew=m,k.transform(o);return k},a._engine.setSize=function(b,c){var d=this.canvas.style;this.width=b,this.height=c,b==+b&&(b+="px"),c==+c&&(c+="px"),d.width=b,d.height=c,d.clip="rect(0 "+b+" "+c+" 0)",this._viewBox&&a._engine.setViewBox.apply(this,this._viewBox);return this},a._engine.setViewBox=function(b,c,d,e,f){a.eve("setViewBox",this,this._viewBox,[b,c,d,e,f]);var h=this.width,i=this.height,j=1/g(d/h,e/i),k,l;f&&(k=i/e,l=h/d,d*k<h&&(b-=(h-d*k)/2/k),e*l<i&&(c-=(i-e*l)/2/l)),this._viewBox=[b,c,d,e,!!f],this._viewBoxShift={dx:-b,dy:-c,scale:j},this.forEach(function(a){a.transform("...")});return this};var F;a._engine.initWin=function(a){var b=a.document;b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),F=function(a){return b.createElement("<rvml:"+a+' class="rvml">')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},a._engine.initWin(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e,f=b.width,g=b.x,h=b.y;if(!c)throw new Error("VML container not found.");var i=new a._Paper,j=i.canvas=a._g.doc.createElement("div"),k=j.style;g=g||0,h=h||0,f=f||512,d=d||342,i.width=f,i.height=d,f==+f&&(f+="px"),d==+d&&(d+="px"),i.coordsize=u*1e3+n+u*1e3,i.coordorigin="0 0",i.span=a._g.doc.createElement("span"),i.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",j.appendChild(i.span),k.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d),c==1?(a._g.doc.body.appendChild(j),k.left=g+"px",k.top=h+"px",k.position="absolute"):c.firstChild?c.insertBefore(j,c.firstChild):c.appendChild(j),i.renderfix=function(){};return i},a.prototype.clear=function(){a.eve("clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]=typeof this[b]=="function"?a._removedFactory(b):null;return!0};var G=a.st;for(var H in E)E[b](H)&&!G[b](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}(window.Raphael)
\ No newline at end of file
diff --git a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
index 5fd59a0f5f..0017cb5489 100644
--- a/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
+++ b/webroot/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js
@@ -1,111 +1,109 @@
/**
* @provides javelin-behavior-aphlict-dropdown
* @requires javelin-behavior
* javelin-request
* javelin-stratcom
* javelin-vector
* javelin-dom
* javelin-uri
*/
JX.behavior('aphlict-dropdown', function(config) {
var dropdown = JX.$(config.dropdownID);
var count = JX.$(config.countID);
var bubble = JX.$(config.bubbleID);
var visible = false;
var request = null;
var dirty = true;
function refresh() {
if (dirty) {
JX.DOM.setContent(dropdown, config.loadingText);
JX.DOM.alterClass(
dropdown,
'phabricator-notification-menu-loading',
true);
}
if (request) { //already fetching
return;
}
request = new JX.Request('/notification/panel/', function(response) {
- var display = (response.number > 999)
- ? "\u221E"
- : response.number;
+ var display = (response.number > 999) ? "\u221E" : response.number;
JX.DOM.setContent(count, display);
- if (response.number == 0) {
+ if (response.number === 0) {
JX.DOM.alterClass(bubble, 'alert-unread', false);
} else {
JX.DOM.alterClass(bubble, 'alert-unread', true);
}
dirty = false;
JX.DOM.alterClass(
dropdown,
'phabricator-notification-menu-loading',
false);
JX.DOM.setContent(dropdown, JX.$H(response.content));
request = null;
});
request.send();
}
JX.Stratcom.listen(
'click',
null,
function(e) {
if (!e.getNode('phabricator-notification-menu')) {
// Click outside the dropdown; hide it.
JX.DOM.hide(dropdown);
visible = false;
return;
}
if (e.getNode('tag:a')) {
// User clicked a link, just follow the link.
return;
}
// If the user clicked a notification (but missed a link) and it has a
// primary URI, go there.
var href = e.getNodeData('notification').href;
if (href) {
JX.$U(href).go();
e.kill();
}
});
JX.DOM.listen(
bubble,
'click',
null,
function(e) {
if (!e.isNormalClick()) {
return;
}
if (visible) {
JX.DOM.hide(dropdown);
} else {
if (dirty) {
refresh();
}
var p = JX.$V(bubble);
p.y = null;
p.x -= 6;
p.setPos(dropdown);
JX.DOM.show(dropdown);
}
visible = !visible;
e.kill();
}
- )
+ );
JX.Stratcom.listen('notification-panel-update', null, function() {
dirty = true;
refresh();
});
});
diff --git a/webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js b/webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js
index c57d496cb7..19198f8be0 100644
--- a/webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js
+++ b/webroot/rsrc/js/application/aphlict/behavior-aphlict-listen.js
@@ -1,90 +1,88 @@
/**
* @provides javelin-behavior-aphlict-listen
* @requires javelin-behavior
* javelin-aphlict
* javelin-stratcom
* javelin-request
* javelin-uri
* javelin-dom
* javelin-json
* phabricator-notification
*/
JX.behavior('aphlict-listen', function(config) {
var showing_reload = false;
function onready() {
var client = new JX.Aphlict(config.id, config.server, config.port)
.setHandler(onaphlictmessage)
.start();
}
// Respond to a notification from the Aphlict notification server. We send
// a request to Phabricator to get notification details.
function onaphlictmessage(type, message) {
if (type == 'receive') {
var request = new JX.Request('/notification/individual/', onnotification)
.addData({key: message.key})
.send();
} else if (__DEV__) {
if (config.debug) {
- var details = message
- ? JX.JSON.stringify(message)
- : '';
+ var details = message ? JX.JSON.stringify(message) : '';
new JX.Notification()
.setContent('(Aphlict) [' + type + '] ' + details)
.alterClassName('jx-notification-debug', true)
.setDuration(0)
.show();
}
}
}
// Respond to a response from Phabricator about a specific notification.
function onnotification(response) {
if (!response.pertinent) {
return;
}
JX.Stratcom.invoke('notification-panel-update', null, {});
// Show the notification itself.
new JX.Notification()
.setContent(JX.$H(response.content))
.show();
// If the notification affected an object on this page, show a
// permanent reload notification if we aren't already.
if ((response.primaryObjectPHID in config.pageObjects) &&
!showing_reload) {
var reload = new JX.Notification()
.setContent('Page updated, click to reload.')
.alterClassName('jx-notification-alert', true)
.setDuration(0);
- reload.listen('activate', function(e) { JX.$U().go(); })
+ reload.listen('activate', function(e) { JX.$U().go(); });
reload.show();
showing_reload = true;
}
}
// Wait for the element to load, and don't do anything if it never loads.
// If we just go crazy and start making calls to it before it loads, its
// interfaces won't be registered yet.
JX.Stratcom.listen('aphlict-component-ready', null, onready);
// Add Flash object to page
JX.$(config.containerID).innerHTML =
- '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000">'
- + '<param name="movie" value="/rsrc/swf/aphlict.swf" />'
- + '<param name="allowScriptAccess" value="always" />'
- + '<param name="wmode" value="opaque" />'
- + '<embed src="/rsrc/swf/aphlict.swf" wmode="opaque"'
- + 'width="0" height="0" id="' + config.id + '">'
- + '</embed></object>'; //Evan sanctioned
+ '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000">' +
+ '<param name="movie" value="/rsrc/swf/aphlict.swf" />' +
+ '<param name="allowScriptAccess" value="always" />' +
+ '<param name="wmode" value="opaque" />' +
+ '<embed src="/rsrc/swf/aphlict.swf" wmode="opaque"' +
+ 'width="0" height="0" id="' + config.id + '">' +
+ '</embed></object>'; //Evan sanctioned
});
diff --git a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js
index a9ddb485e7..bf4d89b969 100644
--- a/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js
+++ b/webroot/rsrc/js/application/conpherence/behavior-widget-pane.js
@@ -1,182 +1,186 @@
/**
* @requires javelin-behavior
* javelin-dom
* javelin-stratcom
* javelin-workflow
* javelin-util
* phabricator-notification
* javelin-behavior-device
* @provides javelin-behavior-conpherence-widget-pane
*/
JX.behavior('conpherence-widget-pane', function(config) {
var toggle_widget = function (data) {
var device = JX.Device.getDevice();
var is_desktop = device == 'desktop';
if (config.widgetRegistery[data.widget] == config.devicesOnly &&
is_desktop) {
return;
}
var root = JX.DOM.find(document, 'div', 'conpherence-layout');
var widgetPane = JX.DOM.find(root, 'div', 'conpherence-widget-pane');
+ var i;
+ var tag_data;
+ var node;
+
for (var widget in config.widgetRegistery) {
// device-only widgets are *always shown* on the desktop
if (config.widgetRegistery[widget] == config.devicesOnly) {
if (is_desktop) {
JX.$(widget).style.display = 'block';
if (config.widgetExtraNodes[widget]) {
- for (var i in config.widgetExtraNodes[widget]) {
- var tag_data = config.widgetExtraNodes[widget][i];
- var node = JX.DOM.find(root, tag_data.tagname, tag_data.sigil);
+ for (i in config.widgetExtraNodes[widget]) {
+ tag_data = config.widgetExtraNodes[widget][i];
+ node = JX.DOM.find(root, tag_data.tagname, tag_data.sigil);
node.style.display = tag_data.desktopstyle;
}
}
continue;
}
}
var cur_toggle = JX.$(widget + '-toggle');
var toggle_class = config.widgetToggleMap[widget];
if (widget == data.widget) {
JX.DOM.alterClass(cur_toggle, toggle_class, true);
JX.$(widget).style.display = 'block';
if (config.widgetRegistery[widget] == config.devicesOnly) {
widgetPane.style.height = '42px';
} else {
widgetPane.style.height = '100%';
}
if (config.widgetExtraNodes[widget]) {
- for (var i in config.widgetExtraNodes[widget]) {
- var tag_data = config.widgetExtraNodes[widget][i];
- var node = JX.DOM.find(root, tag_data.tagname, tag_data.sigil);
+ for (i in config.widgetExtraNodes[widget]) {
+ tag_data = config.widgetExtraNodes[widget][i];
+ node = JX.DOM.find(root, tag_data.tagname, tag_data.sigil);
node.style.display = tag_data.showstyle;
}
}
// some one off code for conpherence messages
if (widget == 'conpherence-message-pane') {
JX.Stratcom.invoke('conpherence-redraw-thread', null, {});
JX.Stratcom.invoke('conpherence-update-page-data', null, {});
}
// some one off code for conpherence list
if (widget == 'conpherence-menu-pane') {
JX.Stratcom.invoke(
'conpherence-update-page-data',
null,
{ use_base_uri : true, title: 'Conpherence' }
);
}
} else {
JX.DOM.alterClass(
cur_toggle,
toggle_class,
false
);
JX.$(widget).style.display = 'none';
if (config.widgetExtraNodes[widget]) {
- for (var i in config.widgetExtraNodes[widget]) {
- var tag_data = config.widgetExtraNodes[widget][i];
- var node = JX.DOM.find(root, tag_data.tagname, tag_data.sigil);
+ for (i in config.widgetExtraNodes[widget]) {
+ tag_data = config.widgetExtraNodes[widget][i];
+ node = JX.DOM.find(root, tag_data.tagname, tag_data.sigil);
node.style.display = tag_data.hidestyle;
}
}
}
}
};
JX.Stratcom.listen(
['touchstart', 'mousedown'],
'conpherence-change-widget',
function(e) {
e.kill();
var data = e.getNodeData('conpherence-change-widget');
toggle_widget(data);
}
);
JX.Stratcom.listen(
'conpherence-toggle-widget',
null,
function (e) {
toggle_widget(e.getData());
}
);
/* people widget */
JX.Stratcom.listen(
['submit', 'didSyntheticSubmit'],
'add-person',
function (e) {
e.kill();
var root = e.getNode('conpherence-layout');
var form = e.getNode('tag:form');
var data = e.getNodeData('add-person');
var peopleRoot = e.getNode('widgets-people');
var messages = null;
try {
messages = JX.DOM.find(root, 'div', 'conpherence-messages');
} catch (ex) {
}
var latestTransactionData = JX.Stratcom.getData(
JX.DOM.find(
root,
'input',
'latest-transaction-id'
));
data.latest_transaction_id = latestTransactionData.id;
JX.Workflow.newFromForm(form, data)
.setHandler(JX.bind(this, function (r) {
if (messages) {
JX.DOM.appendContent(messages, JX.$H(r.transactions));
messages.scrollTop = messages.scrollHeight;
}
// update the people widget
JX.DOM.setContent(
peopleRoot,
JX.$H(r.people_widget)
);
}))
.start();
}
);
JX.Stratcom.listen(
['touchstart', 'mousedown'],
'remove-person',
function (e) {
var peopleRoot = e.getNode('widgets-people');
var form = JX.DOM.find(peopleRoot, 'form');
var data = e.getNodeData('remove-person');
// we end up re-directing to conpherence home
JX.Workflow.newFromForm(form, data)
.start();
}
);
/* settings widget */
var onsubmitSettings = function (e) {
e.kill();
var form = e.getNode('tag:form');
var button = JX.DOM.find(form, 'button');
JX.Workflow.newFromForm(form)
.setHandler(JX.bind(this, function (r) {
new JX.Notification()
.setDuration(6000)
.setContent(r)
.show();
button.disabled = '';
JX.DOM.alterClass(button, 'disabled', false);
}))
.start();
};
JX.Stratcom.listen(
['submit', 'didSyntheticSubmit'],
'notifications-update',
onsubmitSettings
);
});
diff --git a/webroot/rsrc/js/application/countdown/timer.js b/webroot/rsrc/js/application/countdown/timer.js
index 1b404b4609..69a3e2265a 100644
--- a/webroot/rsrc/js/application/countdown/timer.js
+++ b/webroot/rsrc/js/application/countdown/timer.js
@@ -1,48 +1,47 @@
/**
* @provides javelin-behavior-countdown-timer
* @requires javelin-behavior
* javelin-dom
- * javelin-util
*/
JX.behavior('countdown-timer', function(config) {
var container = JX.$(config.container);
calculateTimeLeft();
function setComponent(which, content) {
var component = JX.DOM.find(container, '*', 'phabricator-timer-' + which);
JX.DOM.setContent(component, content);
}
function calculateTimeLeft() {
var days = 0;
var hours = 0;
var minutes = 0;
var seconds = 0;
var current_timestamp = Math.round(new Date() / 1000);
var delta = config.timestamp - current_timestamp;
if (delta > 0) {
days = Math.floor(delta/86400);
delta -= days * 86400;
hours = Math.floor(delta/3600);
delta -= hours * 3600;
minutes = Math.floor(delta / 60);
delta -= minutes * 60;
seconds = delta;
setTimeout(calculateTimeLeft, 1000);
}
setComponent('days', days);
setComponent('hours', hours);
setComponent('minutes', minutes);
setComponent('seconds', seconds);
}
});
diff --git a/webroot/rsrc/js/application/differential/DifferentialInlineCommentEditor.js b/webroot/rsrc/js/application/differential/DifferentialInlineCommentEditor.js
index 08339e1585..b0a2ec8e3b 100644
--- a/webroot/rsrc/js/application/differential/DifferentialInlineCommentEditor.js
+++ b/webroot/rsrc/js/application/differential/DifferentialInlineCommentEditor.js
@@ -1,275 +1,275 @@
/**
* @provides differential-inline-comment-editor
* @requires javelin-dom
* javelin-util
* javelin-stratcom
* javelin-install
* javelin-request
* javelin-workflow
*/
JX.install('DifferentialInlineCommentEditor', {
construct : function(uri) {
this._uri = uri;
},
events : ['done'],
members : {
_uri : null,
_undoText : null,
_skipOverInlineCommentRows : function(node) {
// TODO: Move this semantic information out of class names.
while (node && node.className.indexOf('inline') !== -1) {
node = node.nextSibling;
}
return node;
},
_buildRequestData : function() {
return {
op : this.getOperation(),
on_right : this.getOnRight(),
id : this.getID(),
number : this.getLineNumber(),
is_new : this.getIsNew(),
length : this.getLength(),
changeset : this.getChangeset(),
text : this.getText() || ''
};
},
_draw : function(content, exact_row) {
var row = this.getRow();
var table = this.getTable();
var target = exact_row ? row : this._skipOverInlineCommentRows(row);
return copyRows(table, content, target);
},
_removeUndoLink : function() {
var rows = JX.DifferentialInlineCommentEditor._undoRows;
if (rows) {
for (var ii = 0; ii < rows.length; ii++) {
JX.DOM.remove(rows[ii]);
}
}
},
_undo : function() {
this._removeUndoLink();
this.setText(this._undoText);
this.start();
},
_registerUndoListener : function() {
if (!JX.DifferentialInlineCommentEditor._activeEditor) {
JX.Stratcom.listen(
'click',
'differential-inline-comment-undo',
function(e) {
JX.DifferentialInlineCommentEditor._activeEditor._undo();
e.kill();
});
}
JX.DifferentialInlineCommentEditor._activeEditor = this;
},
_setRowState : function(state) {
var is_hidden = (state == 'hidden');
var is_loading = (state == 'loading');
var row = this.getRow();
JX.DOM.alterClass(row, 'differential-inline-hidden', is_hidden);
JX.DOM.alterClass(row, 'differential-inline-loading', is_loading);
},
_didContinueWorkflow : function(response) {
var drawn = this._draw(JX.$N('div', JX.$H(response)));
var op = this.getOperation();
if (op == 'edit') {
this._setRowState('hidden');
}
JX.DOM.find(
drawn[0],
'textarea',
'differential-inline-comment-edit-textarea').focus();
var oncancel = JX.bind(this, function(e) {
e.kill();
this._didCancelWorkflow();
if (op == 'edit') {
this._setRowState('visible');
}
JX.DOM.remove(drawn[0]);
});
JX.DOM.listen(drawn[0], 'click', 'inline-edit-cancel', oncancel);
var onsubmit = JX.bind(this, function(e) {
e.kill();
JX.Workflow.newFromForm(e.getTarget())
.setHandler(JX.bind(this, function(response) {
JX.DOM.remove(drawn[0]);
if (op == 'edit') {
this._setRowState('visible');
}
this._didCompleteWorkflow(response);
}))
.start();
JX.DOM.alterClass(drawn[0], 'differential-inline-loading', true);
});
JX.DOM.listen(
drawn[0],
['submit', 'didSyntheticSubmit'],
'inline-edit-form',
onsubmit);
},
_didCompleteWorkflow : function(response) {
var op = this.getOperation();
// We don't get any markup back if the user deletes a comment, or saves
// an empty comment (which effects a delete).
if (response.markup) {
this._draw(JX.$N('div', JX.$H(response.markup)));
}
// These operations remove the old row (edit adds a new row first).
var remove_old = (op == 'edit' || op == 'delete');
if (remove_old) {
JX.DOM.remove(this.getRow());
var other_rows = this.getOtherRows();
for(var i = 0; i < other_rows.length; ++i) {
JX.DOM.remove(other_rows[i]);
}
}
// Once the user saves something, get rid of the 'undo' option. A
// particular case where we need this is saving a delete, when we might
// otherwise leave around an 'undo' for an earlier edit to the same
// comment.
this._removeUndoLink();
JX.Stratcom.invoke('differential-inline-comment-update');
this.invoke('done');
},
_didCancelWorkflow : function() {
this.invoke('done');
var op = this.getOperation();
if (op == 'delete') {
// No undo for delete, we prompt the user explicitly.
return;
}
+ var textarea;
try {
- var textarea = JX.DOM.find(
+ textarea = JX.DOM.find(
document.body, // TODO: use getDialogRootNode() when available
'textarea',
'differential-inline-comment-edit-textarea');
} catch (ex) {
// The close handler is called whenever the dialog closes, even if the
// user closed it by completing the workflow with "Save". The
// JX.Workflow API should probably be refined to allow programmatic
// distinction of close caused by 'cancel' vs 'submit'. Testing for
// presence of the textarea serves as a proxy for detecting a 'cancel'.
return;
}
var text = textarea.value;
// If the user hasn't edited the text (i.e., no change from original for
// 'edit' or no text at all), don't offer them an undo.
- if (text == this.getOriginalText() || text == '') {
+ if (text == this.getOriginalText() || text === '') {
return;
}
// Save the text so we can 'undo' back to it.
this._undoText = text;
- var template = this.getOnRight()
- ? this.getTemplates().r
- : this.getTemplates().l;
+ var templates = this.getTemplates();
+ var template = this.getOnRight() ? templates.r : templates.l;
template = JX.$N('div', JX.$H(template));
// NOTE: Operation order matters here; we can't remove anything until
// after we draw the new rows because _draw uses the old rows to figure
// out where to place the comment.
// We use 'exact_row' to put the "undo" text directly above the affected
// comment.
var exact_row = true;
var rows = this._draw(template, exact_row);
this._removeUndoLink();
JX.DifferentialInlineCommentEditor._undoRows = rows;
},
start : function() {
this._registerUndoListener();
var data = this._buildRequestData();
var op = this.getOperation();
if (op == 'delete') {
this._setRowState('loading');
var oncomplete = JX.bind(this, this._didCompleteWorkflow);
var onclose = JX.bind(this, function() {
this._setRowState('visible');
this._didCancelWorkflow();
});
new JX.Workflow(this._uri, data)
.setHandler(oncomplete)
.setCloseHandler(onclose)
.start();
} else {
var handler = JX.bind(this, this._didContinueWorkflow);
if (op == 'edit') {
this._setRowState('loading');
}
new JX.Request(this._uri, handler)
.setData(data)
.send();
}
return this;
}
},
statics : {
/**
* Global refernece to the 'undo' rows currently rendered in the document.
*/
_undoRows : null,
/**
* Global listener for the 'undo' click associated with the currently
* displayed 'undo' link. When an editor is start()ed, it becomes the active
* editor.
*/
_activeEditor : null
},
properties : {
operation : null,
row : null,
otherRows: [],
table : null,
onRight : null,
ID : null,
lineNumber : null,
changeset : null,
length : null,
isNew : null,
text : null,
templates : null,
originalText : null
}
});
diff --git a/webroot/rsrc/js/application/differential/behavior-comment-jump.js b/webroot/rsrc/js/application/differential/behavior-comment-jump.js
index f4d5f91228..9c971df11e 100644
--- a/webroot/rsrc/js/application/differential/behavior-comment-jump.js
+++ b/webroot/rsrc/js/application/differential/behavior-comment-jump.js
@@ -1,32 +1,32 @@
/**
* @provides javelin-behavior-differential-comment-jump
* @requires javelin-behavior
- * javelin-util
+ * javelin-stratcom
* javelin-dom
*/
JX.behavior('differential-comment-jump', function(config) {
function handle_jump(offset) {
return (function(e) {
var parent = JX.$('differential-review-stage');
var clicked = e.getNode('differential-inline-comment');
var inlines = JX.DOM.scry(parent, 'div', 'differential-inline-comment');
var jumpto = null;
for (var ii = 0; ii < inlines.length; ii++) {
if (inlines[ii] == clicked) {
jumpto = inlines[(ii + offset + inlines.length) % inlines.length];
break;
}
}
JX.Stratcom.invoke('differential-toggle-file-request', null, {
- element: jumpto,
+ element: jumpto
});
JX.DOM.scrollTo(jumpto);
e.kill();
});
}
JX.Stratcom.listen('click', 'differential-inline-prev', handle_jump(-1));
JX.Stratcom.listen('click', 'differential-inline-next', handle_jump(+1));
});
diff --git a/webroot/rsrc/js/application/differential/behavior-comment-preview.js b/webroot/rsrc/js/application/differential/behavior-comment-preview.js
index 6a90ec95b5..c7b789d566 100644
--- a/webroot/rsrc/js/application/differential/behavior-comment-preview.js
+++ b/webroot/rsrc/js/application/differential/behavior-comment-preview.js
@@ -1,93 +1,94 @@
/**
* @provides javelin-behavior-differential-feedback-preview
* @requires javelin-behavior
* javelin-stratcom
* javelin-dom
* javelin-request
* javelin-util
* phabricator-shaped-request
*/
JX.behavior('differential-feedback-preview', function(config) {
var action = JX.$(config.action);
var content = JX.$(config.content);
var previewTokenizers = {};
- for (var field in config.previewTokenizers) {
+ var field;
+ for (field in config.previewTokenizers) {
var tokenizer = JX.$(config.previewTokenizers[field]);
previewTokenizers[field] = JX.Stratcom.getData(tokenizer).tokenizer;
}
var callback = function(r) {
var preview = JX.$(config.preview);
JX.DOM.setContent(preview, JX.$H(r));
JX.Stratcom.invoke('differential-preview-update', null, {
container: preview
});
};
var getdata = function() {
var data = {
content : content.value,
action : action.value
};
for (var field in previewTokenizers) {
data[field] = JX.keys(previewTokenizers[field].getTokens()).join(',');
}
return data;
};
var request = new JX.PhabricatorShapedRequest(config.uri, callback, getdata);
request.listen('error', function (error) {
JX.DOM.setContent(JX.$(config.preview), JX.$H('ERROR: ' + error.info));
});
var trigger = JX.bind(request, request.trigger);
JX.DOM.listen(content, 'keydown', null, trigger);
JX.DOM.listen(action, 'change', null, trigger);
- for (var field in previewTokenizers) {
+ for (field in previewTokenizers) {
previewTokenizers[field].listen('change', trigger);
}
request.start();
function refreshInlinePreview() {
new JX.Request(config.inlineuri, function(r) {
var inline = JX.$(config.inline);
JX.DOM.setContent(inline, JX.$H(r));
JX.Stratcom.invoke('differential-preview-update', null, {
container: inline
});
// Go through the previews and activate any "View" links where the
// actual comment appears in the document.
var links = JX.DOM.scry(
inline,
'a',
'differential-inline-preview-jump');
for (var ii = 0; ii < links.length; ii++) {
var data = JX.Stratcom.getData(links[ii]);
try {
JX.$(data.anchor);
links[ii].href = '#' + data.anchor;
JX.DOM.setContent(links[ii], 'View');
} catch (ignored) {
// This inline comment isn't visible, e.g. on some other diff.
}
}
})
.setTimeout(5000)
.send();
}
JX.Stratcom.listen(
'differential-inline-comment-update',
null,
refreshInlinePreview);
refreshInlinePreview();
});
diff --git a/webroot/rsrc/js/application/differential/behavior-dropdown-menus.js b/webroot/rsrc/js/application/differential/behavior-dropdown-menus.js
index e199bca5fa..00d8419ba0 100644
--- a/webroot/rsrc/js/application/differential/behavior-dropdown-menus.js
+++ b/webroot/rsrc/js/application/differential/behavior-dropdown-menus.js
@@ -1,149 +1,149 @@
/**
* @provides javelin-behavior-differential-dropdown-menus
* @requires javelin-behavior
* javelin-dom
* javelin-util
* javelin-stratcom
* phabricator-dropdown-menu
* phabricator-menu-item
* phabricator-phtize
*/
JX.behavior('differential-dropdown-menus', function(config) {
var pht = JX.phtize(config.pht);
function show_more(container) {
var nodes = JX.DOM.scry(container, 'tr', 'context-target');
for (var ii = 0; ii < nodes.length; ii++) {
var show = JX.DOM.scry(nodes[ii], 'a', 'show-more');
for (var jj = 0; jj < show.length; jj++) {
if (JX.Stratcom.getData(show[jj]).type != 'all') {
continue;
}
var event_data = {
context : nodes[ii],
show : show[jj]
};
JX.Stratcom.invoke('differential-reveal-context', null, event_data);
}
}
}
function build_menu(button, data) {
function link_to(name, uri) {
var item = new JX.PhabricatorMenuItem(
name,
JX.bind(null, window.open, uri),
uri);
item.setDisabled(!uri);
return item;
}
var reveal_item = new JX.PhabricatorMenuItem('', function () {
show_more(JX.$(data.containerID));
});
var diffusion_item;
if (data.diffusionURI) {
// Show this only if we have a link, since when this appears in Diffusion
// it is otherwise potentially confusing.
diffusion_item = link_to(pht('Browse in Diffusion'), data.diffusionURI);
}
var menu = new JX.PhabricatorDropdownMenu(buttons[ii])
.addItem(reveal_item);
var visible_item = new JX.PhabricatorMenuItem('', function () {
JX.Stratcom.invoke('differential-toggle-file', null, {
- diff: JX.DOM.scry(JX.$(data.containerID), 'table', 'differential-diff'),
+ diff: JX.DOM.scry(JX.$(data.containerID), 'table', 'differential-diff')
});
});
menu.addItem(visible_item);
if (diffusion_item) {
menu.addItem(diffusion_item);
}
menu.addItem(link_to(pht('View Standalone'), data.standaloneURI));
if (data.leftURI) {
menu.addItem(link_to(pht('Show Raw File (Left)'), data.leftURI));
}
if (data.rightURI) {
menu.addItem(link_to(pht('Show Raw File (Right)'), data.rightURI));
}
if (data.editor) {
menu.addItem(new JX.PhabricatorMenuItem(
pht('Open in Editor'),
JX.bind(null, location.assign, data.editor), // Open in the same window.
data.editor));
}
if (data.editorConfigure) {
menu.addItem(link_to(pht('Configure Editor'), data.editorConfigure));
}
menu.listen(
'open',
function() {
// When the user opens the menu, check if there are any "Show More"
// links in the changeset body. If there aren't, disable the "Show
// Entire File" menu item since it won't change anything.
var nodes = JX.DOM.scry(JX.$(data.containerID), 'a', 'show-more');
if (nodes.length) {
reveal_item.setDisabled(false);
reveal_item.setName(pht('Show Entire File'));
} else {
reveal_item.setDisabled(true);
reveal_item.setName(pht('Entire File Shown'));
}
visible_item.setDisabled(true);
visible_item.setName(pht("Can't Toggle Unloaded File"));
var diffs = JX.DOM.scry(JX.$(data.containerID),
'table', 'differential-diff');
if (diffs.length > 1) {
JX.$E(
'More than one node with sigil "differential-diff" was found in "'+
data.containerID+'."');
} else if (diffs.length == 1) {
diff = diffs[0];
visible_item.setDisabled(false);
if (JX.Stratcom.getData(diff).hidden) {
visible_item.setName(pht('Expand File'));
} else {
visible_item.setName(pht('Collapse File'));
}
} else {
// Do nothing when there is no diff shown in the table. For example,
// the file is binary.
}
});
}
var buttons = JX.DOM.scry(window.document, 'a', 'differential-view-options');
for (var ii = 0; ii < buttons.length; ii++) {
build_menu(buttons[ii], JX.Stratcom.getData(buttons[ii]));
}
JX.Stratcom.listen(
'click',
'differential-reveal-all',
function(e) {
var containers = JX.DOM.scry(
JX.$('differential-review-stage'),
'div',
'differential-changeset');
for (var i=0; i < containers.length; i++) {
show_more(containers[i]);
}
e.kill();
});
});
diff --git a/webroot/rsrc/js/application/differential/behavior-edit-inline-comments.js b/webroot/rsrc/js/application/differential/behavior-edit-inline-comments.js
index 07183a7389..1ab0edae23 100644
--- a/webroot/rsrc/js/application/differential/behavior-edit-inline-comments.js
+++ b/webroot/rsrc/js/application/differential/behavior-edit-inline-comments.js
@@ -1,264 +1,264 @@
/**
* @provides javelin-behavior-differential-edit-inline-comments
* @requires javelin-behavior
* javelin-stratcom
* javelin-dom
* javelin-util
* javelin-vector
* differential-inline-comment-editor
*/
JX.behavior('differential-edit-inline-comments', function(config) {
var selecting = false;
var reticle = JX.$N('div', {className: 'differential-reticle'});
JX.DOM.hide(reticle);
document.body.appendChild(reticle);
var origin = null;
var target = null;
var root = null;
var changeset = null;
var editor = null;
function updateReticle() {
var top = origin;
var bot = target;
if (JX.$V(top).y > JX.$V(bot).y) {
var tmp = top;
top = bot;
bot = tmp;
}
var code = target.nextSibling;
var pos = JX.$V(top).add(1 + JX.Vector.getDim(target).x, 0);
var dim = JX.Vector.getDim(code).add(-4, 0);
if (isOnRight(target)) {
dim.x += JX.Vector.getDim(code.nextSibling).x;
}
dim.y = (JX.$V(bot).y - pos.y) + JX.Vector.getDim(bot).y;
pos.setPos(reticle);
dim.setDim(reticle);
JX.DOM.show(reticle);
}
function hideReticle() {
JX.DOM.hide(reticle);
}
JX.DifferentialInlineCommentEditor.listen('done', function() {
selecting = false;
editor = false;
hideReticle();
set_link_state(false);
});
function isOnRight(node) {
return node.parentNode.firstChild != node;
}
function isNewFile(node) {
var data = JX.Stratcom.getData(root);
return isOnRight(node) || (data.left != data.right);
}
function getRowNumber(th_node) {
try {
return parseInt(th_node.id.match(/^C\d+[ON]L(\d+)$/)[1], 10);
} catch (x) {
return undefined;
}
}
var set_link_state = function(active) {
JX.DOM.alterClass(JX.$(config.stage), 'inline-editor-active', active);
};
JX.Stratcom.listen(
'mousedown',
['differential-changeset', 'tag:th'],
function(e) {
if (editor ||
selecting ||
e.isRightButton() ||
getRowNumber(e.getTarget()) === undefined) {
return;
}
selecting = true;
root = e.getNode('differential-changeset');
origin = target = e.getTarget();
var data = e.getNodeData('differential-changeset');
if (isOnRight(target)) {
changeset = data.right;
} else {
changeset = data.left;
}
updateReticle();
e.kill();
});
JX.Stratcom.listen(
'mouseover',
['differential-changeset', 'tag:th'],
function(e) {
if (!selecting ||
editor ||
(getRowNumber(e.getTarget()) === undefined) ||
(isOnRight(e.getTarget()) != isOnRight(origin)) ||
(e.getNode('differential-changeset') !== root)) {
return;
}
target = e.getTarget();
updateReticle();
});
JX.Stratcom.listen(
'mouseup',
null,
function(e) {
if (editor || !selecting) {
return;
}
var o = getRowNumber(origin);
var t = getRowNumber(target);
var insert;
var len;
if (t < o) {
len = (o - t);
o = t;
insert = origin.parentNode;
} else {
len = (t - o);
insert = target.parentNode;
}
editor = new JX.DifferentialInlineCommentEditor(config.uri)
.setTemplates(config.undo_templates)
.setOperation('new')
.setChangeset(changeset)
.setLineNumber(o)
.setLength(len)
.setIsNew(isNewFile(target) ? 1 : 0)
.setOnRight(isOnRight(target) ? 1 : 0)
.setRow(insert.nextSibling)
.setTable(insert.parentNode)
.start();
set_link_state(true);
e.kill();
});
JX.Stratcom.listen(
['mouseover', 'mouseout'],
'differential-inline-comment',
function(e) {
if (e.getType() == 'mouseout') {
hideReticle();
} else {
root = e.getNode('differential-changeset');
if (root) {
var data = e.getNodeData('differential-inline-comment');
var change = e.getNodeData('differential-changeset');
var id_part = data.on_right ? change.right : change.left;
var th = e.getNode('tag:td').previousSibling;
var new_part = isNewFile(th) ? 'N' : 'O';
var prefix = 'C' + id_part + new_part + 'L';
origin = JX.$(prefix + data.number);
target = JX.$(prefix + (parseInt(data.number, 10) +
parseInt(data.length, 10)));
updateReticle();
}
}
});
var action_handler = function(op, e) {
e.kill();
if (editor) {
return;
}
var node = e.getNode('differential-inline-comment');
handle_inline_action(node, op);
- }
+ };
var handle_inline_action = function(node, op) {
var data = JX.Stratcom.getData(node);
var row = node.parentNode.parentNode;
var other_rows = [];
if (JX.Stratcom.hasSigil(node, 'differential-inline-comment-preview')) {
// The DOM structure around the comment is different if it's part of the
// preview, so make sure not to pass the wrong container.
row = node;
if (op === 'delete') {
// Furthermore, deleting a comment in the preview does not automatically
// delete other occurrences of the same comment, so do that manually.
var nodes = JX.DOM.scry(
document.body,
'div',
'differential-inline-comment');
for (var i = 0; i < nodes.length; ++i) {
if (JX.Stratcom.getData(nodes[i]).id === data.id) {
other_rows.push(nodes[i]);
}
}
}
}
var original = data.original;
if (op == 'reply') {
// If the user hit "reply", the original text is empty (a new reply), not
// the text of the comment they're replying to.
original = '';
}
editor = new JX.DifferentialInlineCommentEditor(config.uri)
.setTemplates(config.undo_templates)
.setOperation(op)
.setID(data.id)
.setLineNumber(data.number)
.setLength(data.length)
.setOnRight(data.on_right)
.setOriginalText(original)
.setRow(row)
.setOtherRows(other_rows)
.setTable(row.parentNode)
.start();
set_link_state(true);
- }
+ };
for (var op in {'edit' : 1, 'delete' : 1, 'reply' : 1}) {
JX.Stratcom.listen(
'click',
['differential-inline-comment', 'differential-inline-' + op],
JX.bind(null, action_handler, op));
}
JX.Stratcom.listen(
'differential-inline-action',
null,
function(e) {
var data = e.getData();
handle_inline_action(data.node, data.op);
});
});
diff --git a/webroot/rsrc/js/application/differential/behavior-keyboard-nav.js b/webroot/rsrc/js/application/differential/behavior-keyboard-nav.js
index ef9baae675..98d0b73a04 100644
--- a/webroot/rsrc/js/application/differential/behavior-keyboard-nav.js
+++ b/webroot/rsrc/js/application/differential/behavior-keyboard-nav.js
@@ -1,274 +1,277 @@
/**
* @provides javelin-behavior-differential-keyboard-navigation
* @requires javelin-behavior
* javelin-dom
* javelin-stratcom
* phabricator-keyboard-shortcut
*/
JX.behavior('differential-keyboard-navigation', function(config) {
var cursor = -1;
var changesets;
var selection_begin = null;
var selection_end = null;
var refreshFocus = function() {};
function init() {
if (changesets) {
return;
}
changesets = JX.DOM.scry(document.body, 'div', 'differential-changeset');
}
function getBlocks(cursor) {
// TODO: This might not be terribly fast; we can't currently memoize it
// because it can change as ajax requests come in (e.g., content loads).
var rows = JX.DOM.scry(changesets[cursor], 'tr');
var blocks = [[changesets[cursor], changesets[cursor]]];
var start = null;
var type;
var ii;
// Don't show code blocks inside a collapsed file.
var diff = JX.DOM.scry(changesets[cursor], 'table', 'differential-diff');
if (diff.length == 1 && JX.Stratcom.getData(diff[0]).hidden) {
return blocks;
}
function push() {
if (start) {
blocks.push([start, rows[ii - 1]]);
}
start = null;
}
for (ii = 0; ii < rows.length; ii++) {
type = getRowType(rows[ii]);
if (type == 'comment') {
// If we see these types of rows, make a block for each one.
push();
}
if (!type) {
push();
} else if (type && !start) {
start = rows[ii];
}
}
push();
return blocks;
}
function getRowType(row) {
// NOTE: Being somewhat over-general here to allow other types of objects
// to be easily focused in the future (inline comments, 'show more..').
if (row.className.indexOf('inline') !== -1) {
return 'comment';
}
if (row.className.indexOf('differential-changeset') !== -1) {
return 'file';
}
var cells = JX.DOM.scry(row, 'td');
for (var ii = 0; ii < cells.length; ii++) {
// NOTE: The semantic use of classnames here is for performance; don't
// emulate this elsewhere since it's super terrible.
if (cells[ii].className.indexOf('old') !== -1 ||
cells[ii].className.indexOf('new') !== -1) {
return 'change';
}
}
return null;
}
function jump(manager, delta, jump_to_type) {
init();
if (cursor < 0) {
if (delta < 0) {
// If the user goes "back" without a selection, just reject the action.
return;
} else {
cursor = 0;
}
}
while (true) {
var blocks = getBlocks(cursor);
var focus;
if (delta < 0) {
focus = blocks.length;
} else {
focus = -1;
}
for (var ii = 0; ii < blocks.length; ii++) {
if (blocks[ii][0] == selection_begin) {
focus = ii;
break;
}
}
while (true) {
focus += delta;
if (blocks[focus]) {
var row_type = getRowType(blocks[focus][0]);
if (jump_to_type && row_type != jump_to_type) {
continue;
}
selection_begin = blocks[focus][0];
selection_end = blocks[focus][1];
manager.scrollTo(selection_begin);
- (refreshFocus = function() {
+
+ refreshFocus = function() {
manager.focusOn(selection_begin, selection_end);
- })();
+ };
+
+ refreshFocus();
return;
} else {
var adjusted = (cursor + delta);
if (adjusted < 0 || adjusted >= changesets.length) {
// Stop cursor movement when the user reaches either end.
return;
}
cursor = adjusted;
// Break the inner loop and go to the next file.
break;
}
}
}
}
// When inline comments are updated, wipe out our cache of blocks since
// comments may have been added or deleted.
JX.Stratcom.listen(
null,
'differential-inline-comment-update',
function() {
changesets = null;
});
// Same thing when a file is hidden or shown; don't want to highlight
// invisible code.
JX.Stratcom.listen(
'differential-toggle-file-toggled',
null,
function() {
changesets = null;
init();
refreshFocus();
});
var haunt_mode = 0;
function haunt() {
haunt_mode = (haunt_mode + 1) % 3;
var el = JX.$(config.haunt);
for (var ii = 1; ii <= 2; ii++) {
JX.DOM.alterClass(el, 'differential-haunt-mode-'+ii, (haunt_mode == ii));
}
}
new JX.KeyboardShortcut('j', 'Jump to next change.')
.setHandler(function(manager) {
jump(manager, 1);
})
.register();
new JX.KeyboardShortcut('k', 'Jump to previous change.')
.setHandler(function(manager) {
jump(manager, -1);
})
.register();
new JX.KeyboardShortcut('J', 'Jump to next file.')
.setHandler(function(manager) {
jump(manager, 1, 'file');
})
.register();
new JX.KeyboardShortcut('K', 'Jump to previous file.')
.setHandler(function(manager) {
jump(manager, -1, 'file');
})
.register();
new JX.KeyboardShortcut('n', 'Jump to next inline comment.')
.setHandler(function(manager) {
jump(manager, 1, 'comment');
})
.register();
new JX.KeyboardShortcut('p', 'Jump to previous inline comment.')
.setHandler(function(manager) {
jump(manager, -1, 'comment');
})
.register();
new JX.KeyboardShortcut('t', 'Jump to the table of contents.')
.setHandler(function(manager) {
var toc = JX.$('toc');
manager.scrollTo(toc);
})
.register();
new JX.KeyboardShortcut(
'h',
'Collapse or expand the file display (after jump).')
.setHandler(function(manager) {
if (!changesets || !changesets[cursor]) {
return;
}
JX.Stratcom.invoke('differential-toggle-file', null, {
diff: JX.DOM.scry(changesets[cursor], 'table', 'differential-diff')
});
})
.register();
function inline_op(node, op) {
if (!JX.DOM.scry(node, 'a', 'differential-inline-' + op)) {
// No link for this operation, e.g. editing a comment you can't edit.
return;
}
var data = {
node: JX.DOM.find(node, 'div', 'differential-inline-comment'),
op: op
};
JX.Stratcom.invoke('differential-inline-action', null, data);
}
new JX.KeyboardShortcut('r', 'Reply to selected inline comment.')
.setHandler(function(manager) {
inline_op(selection_begin, 'reply');
})
.register();
new JX.KeyboardShortcut('e', 'Edit selected inline comment.')
.setHandler(function(manager) {
inline_op(selection_begin, 'edit');
})
.register();
if (config.haunt) {
new JX.KeyboardShortcut('z', 'Cycle comment panel haunting modes.')
.setHandler(haunt)
.register();
}
});
diff --git a/webroot/rsrc/js/application/differential/behavior-populate.js b/webroot/rsrc/js/application/differential/behavior-populate.js
index 42ba3832f7..3add4c3b1a 100644
--- a/webroot/rsrc/js/application/differential/behavior-populate.js
+++ b/webroot/rsrc/js/application/differential/behavior-populate.js
@@ -1,177 +1,177 @@
/**
* @provides javelin-behavior-differential-populate
* @requires javelin-behavior
* javelin-workflow
* javelin-util
* javelin-dom
* javelin-stratcom
* javelin-behavior-device
* javelin-vector
* phabricator-tooltip
*/
JX.behavior('differential-populate', function(config) {
function onresponse(target_id, response) {
// As we populate the diff, we try to hold the document scroll position
// steady, so that, e.g., users who want to leave a comment on a diff with a
// large number of changes don't constantly have the text area scrolled off
// the bottom of the screen until the entire diff loads.
//
// There are two three major cases here:
//
// - If we're near the top of the document, never scroll.
// - If we're near the bottom of the document, always scroll.
// - Otherwise, scroll if the changes were above the midline of the
// viewport.
var target = JX.$(target_id);
var old_pos = JX.Vector.getScroll();
var old_view = JX.Vector.getViewport();
var old_dim = JX.Vector.getDocument();
// Number of pixels away from the top or bottom of the document which
// count as "nearby".
var sticky = 480;
var near_top = (old_pos.y <= sticky);
var near_bot = ((old_pos.y + old_view.y) >= (old_dim.y - sticky));
var target_pos = JX.Vector.getPos(target);
var target_dim = JX.Vector.getDim(target);
var target_mid = (target_pos.y + (target_dim.y / 2));
var view_mid = (old_pos.y + (old_view.y / 2));
var above_mid = (target_mid < view_mid);
JX.DOM.replace(target, JX.$H(response.changeset));
if (!near_top) {
if (near_bot || above_mid) {
// Figure out how much taller the document got.
var delta = (JX.Vector.getDocument().y - old_dim.y);
window.scrollTo(old_pos.x, old_pos.y + delta);
}
}
if (response.coverage) {
for (var k in response.coverage) {
try {
JX.DOM.replace(JX.$(k), JX.$H(response.coverage[k]));
} catch (ignored) {
// Not terribly important.
}
}
}
}
// NOTE: If you load the page at one device resolution and then resize to
// a different one we don't re-render the diffs, because it's a complicated
// mess and you could lose inline comments, cursor positions, etc.
var renderer = (JX.Device.getDevice() == 'desktop') ? '2up' : '1up';
// TODO: Once 1up works better, figure out when to show it.
renderer = '2up';
for (var k in config.registry) {
var data = {
ref : config.registry[k],
whitespace: config.whitespace,
renderer: renderer
};
new JX.Workflow(config.uri, data)
.setHandler(JX.bind(null, onresponse, k))
.start();
}
var highlighted = null;
var highlight_class = null;
JX.Stratcom.listen(
'click',
'differential-load',
function(e) {
var meta = e.getNodeData('differential-load');
var diff;
try {
diff = JX.$(meta.id);
- } catch (e) {
+ } catch (ex) {
// Already loaded.
}
if (diff) {
JX.DOM.setContent(
diff,
JX.$H('<div class="differential-loading">Loading...</div>'));
var data = {
ref : meta.ref,
whitespace : config.whitespace
};
new JX.Workflow(config.uri, data)
.setHandler(JX.bind(null, onresponse, meta.id))
.start();
}
if (meta.kill) {
e.kill();
}
});
JX.Stratcom.listen(
['mouseover', 'mouseout'],
['differential-changeset', 'tag:td'],
function(e) {
var t = e.getTarget();
// NOTE: Using className is not best practice, but the diff UI is perf
// sensitive.
if (!t.className.match(/cov|copy/)) {
return;
}
if (e.getType() == 'mouseout') {
JX.Tooltip.hide();
if (highlighted) {
JX.DOM.alterClass(highlighted, highlight_class, false);
highlighted = null;
}
} else {
highlight_class = null;
var msg;
var align = 'W';
var sibling = 'previousSibling';
var width = 120;
if (t.className.match(/cov-C/)) {
msg = 'Covered';
highlight_class = 'source-cov-C';
} else if (t.className.match(/cov-U/)) {
msg = 'Not Covered';
highlight_class = 'source-cov-U';
} else if (t.className.match(/cov-N/)) {
msg = 'Not Executable';
highlight_class = 'source-cov-N';
} else {
var match = /new-copy|new-move/.exec(t.className);
if (match) {
sibling = 'nextSibling';
width = 500;
msg = JX.Stratcom.getData(t).msg;
highlight_class = match[0];
}
}
if (msg) {
JX.Tooltip.show(t, width, align, msg);
}
if (highlight_class) {
highlighted = t[sibling];
JX.DOM.alterClass(highlighted, highlight_class, true);
}
}
});
});
diff --git a/webroot/rsrc/js/application/differential/behavior-show-all-comments.js b/webroot/rsrc/js/application/differential/behavior-show-all-comments.js
index cb0a927fda..6bd9f825a1 100644
--- a/webroot/rsrc/js/application/differential/behavior-show-all-comments.js
+++ b/webroot/rsrc/js/application/differential/behavior-show-all-comments.js
@@ -1,59 +1,59 @@
/**
* @provides javelin-behavior-differential-show-all-comments
* @requires javelin-behavior
* javelin-stratcom
* javelin-dom
*/
JX.behavior('differential-show-all-comments', function(config) {
var shown = false;
function reveal(node) {
if (shown) {
return false;
}
shown = true;
node = node || JX.DOM.find(
document.body,
'div',
'differential-all-comments-container');
if (node) {
JX.DOM.setContent(node, JX.$H(config.markup));
}
return true;
}
// Reveal the hidden comments if the user clicks "Show All Comments", or if
// there's an anchor in the URL, since we don't want to link to "#comment-3"
// and have it collapsed.
function at_comment_hash() {
return window.location.hash && window.location.hash.match(/comment/);
}
if (at_comment_hash()) {
reveal();
} else {
JX.Stratcom.listen(
'hashchange',
null,
function(e) {
if (at_comment_hash() && reveal()) {
try {
var target = JX.$(window.location.hash.replace(/^#/, ''));
window.scrollTo(0, target.offsetTop);
- } catch (e) {
+ } catch (ex) {
}
}
});
}
JX.Stratcom.listen(
'click',
'differential-show-all-comments',
function(e) {
reveal(e.getNode('differential-all-comments-container'));
e.kill();
});
});
diff --git a/webroot/rsrc/js/application/diffusion/behavior-audit-preview.js b/webroot/rsrc/js/application/diffusion/behavior-audit-preview.js
index fa2b6dddfe..7f7ebb904f 100644
--- a/webroot/rsrc/js/application/diffusion/behavior-audit-preview.js
+++ b/webroot/rsrc/js/application/diffusion/behavior-audit-preview.js
@@ -1,33 +1,33 @@
/**
* @provides javelin-behavior-audit-preview
* @requires javelin-behavior
* javelin-dom
* javelin-util
* phabricator-shaped-request
*/
JX.behavior('audit-preview', function(config) {
var preview = JX.$(config.preview);
var content = JX.$(config.content);
var action = JX.$(config.action);
var callback = function(r) {
JX.DOM.setContent(JX.$(config.preview), JX.$H(r));
};
var getdata = function() {
return {
action: action.value,
content: content.value
};
- }
+ };
var request = new JX.PhabricatorShapedRequest(config.uri, callback, getdata);
var trigger = JX.bind(request, request.trigger);
JX.DOM.listen(content, 'keydown', null, trigger);
JX.DOM.listen(action, 'change', null, trigger);
request.start();
});
diff --git a/webroot/rsrc/js/application/diffusion/behavior-commit-graph.js b/webroot/rsrc/js/application/diffusion/behavior-commit-graph.js
index b5306381d7..e9ab4b12bb 100644
--- a/webroot/rsrc/js/application/diffusion/behavior-commit-graph.js
+++ b/webroot/rsrc/js/application/diffusion/behavior-commit-graph.js
@@ -1,137 +1,143 @@
/**
* @provides javelin-behavior-diffusion-commit-graph
* @requires javelin-behavior
* javelin-dom
* javelin-stratcom
*/
JX.behavior('diffusion-commit-graph', function(config) {
var nodes = JX.DOM.scry(document.body, 'div', 'commit-graph');
var cxt;
// Pick the color for column 'c'.
function color(c) {
var colors = [
'#cc0000',
'#cc0099',
'#6600cc',
'#0033cc',
'#00cccc',
'#00cc33',
'#66cc00',
- '#cc9900',
+ '#cc9900'
];
return colors[c % colors.length];
}
// Stroke a line (for lines between commits).
function lstroke(c) {
cxt.lineWidth = 3;
cxt.strokeStyle = '#ffffff';
cxt.stroke();
cxt.lineWidth = 1;
cxt.strokeStyle = color(c);
cxt.stroke();
}
// Stroke with fill (for commit circles).
function fstroke(c) {
cxt.fillStyle = color(c);
cxt.strokeStyle = '#ffffff';
cxt.fill();
cxt.stroke();
}
for (var ii = 0; ii < nodes.length; ii++) {
var data = JX.Stratcom.getData(nodes[ii]);
var cell = 12; // Width of each thread.
- function xpos(col) {
+ var xpos = function(col) {
return (col * cell) + (cell / 2);
- }
+ };
var h = 26;
var w = cell * config.count;
var canvas = JX.$N('canvas', {width: w, height: h});
cxt = canvas.getContext('2d');
cxt.lineWidth = 3;
// This gives us sharper lines, since lines drawn on an integer (like 5)
// are drawn from 4.5 to 5.5.
cxt.translate(0.5, 0.5);
cxt.strokeStyle = '#ffffff';
cxt.fillStyle = '#ffffff';
// First, figure out which column this commit appears in. It is marked by
// "o" (if it has a commit after it) or "^" (if no other commit has it as
// a parent). We use this to figure out where to draw the join/split lines.
var origin = null;
- for (var jj = 0; jj < data.line.length; jj++) {
- var c = data.line.charAt(jj);
+ var jj;
+ var x;
+ var c;
+ for (jj = 0; jj < data.line.length; jj++) {
+ c = data.line.charAt(jj);
switch (c) {
case 'o':
case '^':
origin = xpos(jj);
break;
}
}
// Draw all the join lines. These start at some column at the top of the
// canvas and join the commit's column. They indicate branching.
- for (var jj = 0; jj < data.join.length; jj++) {
+ for (jj = 0; jj < data.join.length; jj++) {
var join = data.join[jj];
- var x = xpos(join);
+ x = xpos(join);
cxt.beginPath();
cxt.moveTo(x, 0);
cxt.bezierCurveTo(x, h/4, origin, h/4, origin, h/2);
lstroke(join);
}
// Draw all the split lines. These start at the commit and end at some
// column on the bottom of the canvas. They indicate merging.
- for (var jj = 0; jj < data.split.length; jj++) {
+ for (jj = 0; jj < data.split.length; jj++) {
var split = data.split[jj];
- var x = xpos(split);
+ x = xpos(split);
cxt.beginPath();
cxt.moveTo(origin, h/2);
cxt.bezierCurveTo(origin, 3*h/4, x, 3*h/4, x, h);
lstroke(split);
}
// Draw the vertical lines (a branch with no activity at this commit) and
// the commit circles.
- for (var jj = 0; jj < data.line.length; jj++) {
- var c = data.line.charAt(jj);
+ for (jj = 0; jj < data.line.length; jj++) {
+ c = data.line.charAt(jj);
switch (c) {
case 'o':
case '^':
- origin = xpos(jj);
case '|':
+ if (c == 'o' || c == '^') {
+ origin = xpos(jj);
+ }
+
cxt.beginPath();
cxt.moveTo(xpos(jj), (c == '^' ? h/2 : 0));
cxt.lineTo(xpos(jj), h);
lstroke(jj);
if (c == 'o' || c == '^') {
cxt.beginPath();
cxt.arc(xpos(jj), h/2, 3, 0, 2 * Math.PI, true);
fstroke(jj);
}
break;
}
}
JX.DOM.setContent(nodes[ii], canvas);
}
});
diff --git a/webroot/rsrc/js/application/diffusion/behavior-jump-to.js b/webroot/rsrc/js/application/diffusion/behavior-jump-to.js
index 6c51dc814a..852502e88f 100644
--- a/webroot/rsrc/js/application/diffusion/behavior-jump-to.js
+++ b/webroot/rsrc/js/application/diffusion/behavior-jump-to.js
@@ -1,15 +1,14 @@
/**
* @provides javelin-behavior-diffusion-jump-to
* @requires javelin-behavior
- * javelin-util
* javelin-vector
* javelin-dom
*/
JX.behavior('diffusion-jump-to', function(config) {
setTimeout(function() {
window.scrollTo(0, JX.$V(JX.$(config.target)).y - 100);
}, 0);
});
diff --git a/webroot/rsrc/js/application/maniphest/behavior-batch-editor.js b/webroot/rsrc/js/application/maniphest/behavior-batch-editor.js
index 7581318730..538a1f944e 100644
--- a/webroot/rsrc/js/application/maniphest/behavior-batch-editor.js
+++ b/webroot/rsrc/js/application/maniphest/behavior-batch-editor.js
@@ -1,156 +1,156 @@
/**
* @provides javelin-behavior-maniphest-batch-editor
* @requires javelin-behavior
* javelin-dom
* javelin-util
* phabricator-prefab
* multirow-row-manager
* javelin-json
*/
JX.behavior('maniphest-batch-editor', function(config) {
var root = JX.$(config.root);
var editor_table = JX.DOM.find(root, 'table', 'maniphest-batch-actions');
var manager = new JX.MultirowRowManager(editor_table);
var action_rows = [];
addRow({});
function renderRow(data) {
var action_select = JX.Prefab.renderSelect(
{
'add_project': 'Add Projects',
'remove_project' : 'Remove Projects',
'priority': 'Change Priority',
'status': 'Open / Close',
'add_comment': 'Comment',
'assign': 'Assign',
'add_ccs' : 'Add CCs',
'remove_ccs' : 'Remove CCs'
});
var proj_tokenizer = build_tokenizer(config.sources.project);
var owner_tokenizer = build_tokenizer(config.sources.owner);
var cc_tokenizer = build_tokenizer(config.sources.cc);
var priority_select = JX.Prefab.renderSelect(config.priorityMap);
var status_select = JX.Prefab.renderSelect(config.statusMap);
var comment_input = JX.$N('input', {style: {width: '100%'}});
var cell = JX.$N('td', {className: 'batch-editor-input'});
var vfunc = null;
function update() {
switch (action_select.value) {
case 'add_project':
case 'remove_project':
JX.DOM.setContent(cell, proj_tokenizer.template);
vfunc = function() {
return JX.keys(proj_tokenizer.object.getTokens());
};
break;
case 'add_ccs':
case 'remove_ccs':
JX.DOM.setContent(cell, cc_tokenizer.template);
vfunc = function() {
return JX.keys(cc_tokenizer.object.getTokens());
};
break;
case 'assign':
JX.DOM.setContent(cell, owner_tokenizer.template);
vfunc = function() {
return JX.keys(owner_tokenizer.object.getTokens());
};
break;
case 'add_comment':
JX.DOM.setContent(cell, comment_input);
vfunc = function() {
return comment_input.value;
};
break;
case 'priority':
JX.DOM.setContent(cell, priority_select);
vfunc = function() { return priority_select.value; };
break;
case 'status':
JX.DOM.setContent(cell, status_select);
vfunc = function() { return status_select.value; };
break;
}
- };
+ }
JX.DOM.listen(action_select, 'change', null, update);
update();
return {
nodes : [JX.$N('td', {}, action_select), cell],
dataCallback : function() {
return {
action: action_select.value,
value: vfunc()
};
}
};
}
function onaddaction(e) {
e.kill();
addRow({});
}
function addRow(info) {
var data = renderRow(info);
var row = manager.addRow(data.nodes);
var id = manager.getRowID(row);
action_rows[id] = data.dataCallback;
}
function onsubmit(e) {
var input = JX.$(config.input);
var actions = [];
for (var k in action_rows) {
actions.push(action_rows[k]());
}
input.value = JX.JSON.stringify(actions);
}
JX.DOM.listen(
root,
'click',
'add-action',
onaddaction);
JX.DOM.listen(
root,
'submit',
null,
onsubmit);
manager.listen(
'row-removed',
function(row_id) {
delete action_rows[row_id];
});
function build_tokenizer(tconfig) {
var template = JX.$N('div', JX.$H(config.tokenizerTemplate)).firstChild;
template.id = '';
var build_config = JX.copy({}, tconfig);
build_config.root = template;
var built = JX.Prefab.buildTokenizer(build_config);
built.tokenizer.start();
return {
object: built.tokenizer,
template: template
};
}
});
diff --git a/webroot/rsrc/js/application/maniphest/behavior-batch-selector.js b/webroot/rsrc/js/application/maniphest/behavior-batch-selector.js
index d5aaa60d98..c66a49e66e 100644
--- a/webroot/rsrc/js/application/maniphest/behavior-batch-selector.js
+++ b/webroot/rsrc/js/application/maniphest/behavior-batch-selector.js
@@ -1,158 +1,158 @@
/**
* @provides javelin-behavior-maniphest-batch-selector
* @requires javelin-behavior
* javelin-dom
* javelin-stratcom
* javelin-util
*/
JX.behavior('maniphest-batch-selector', function(config) {
var selected = {};
// Test if a task node is selected.
var get_id = function(task) {
return JX.Stratcom.getData(task).taskID;
- }
+ };
var is_selected = function(task) {
return (get_id(task) in selected);
- }
+ };
// Change the selected state of a task.
var change = function(task, to) {
if (to === undefined) {
to = !is_selected(task);
}
if (to) {
selected[get_id(task)] = true;
} else {
delete selected[get_id(task)];
}
JX.DOM.alterClass(
task,
'phabricator-object-item-selected',
is_selected(task));
update();
};
// Change all tasks to some state (used by "select all" / "clear selection"
// buttons).
var changeall = function(to) {
var inputs = JX.DOM.scry(document.body, 'li', 'maniphest-task');
for (var ii = 0; ii < inputs.length; ii++) {
change(inputs[ii], to);
}
- }
+ };
// Clear any document text selection after toggling a task via shift click,
// since errant clicks tend to start selecting various ranges otherwise.
var clear_selection = function() {
if (window.getSelection) {
if (window.getSelection().empty) {
window.getSelection().empty();
} else if (window.getSelection().removeAllRanges) {
window.getSelection().removeAllRanges();
}
} else if (document.selection) {
document.selection.empty();
}
- }
+ };
// Update the status text showing how many tasks are selected, and the button
// state.
var update = function() {
var count = JX.keys(selected).length;
var status;
- if (count == 0) {
+ if (count === 0) {
status = 'Shift-Click to Select Tasks';
} else if (status == 1) {
status = '1 Selected Task';
} else {
status = count + ' Selected Tasks';
}
JX.DOM.setContent(JX.$(config.status), status);
var submit = JX.$(config.submit);
- var disable = (count == 0);
+ var disable = (count === 0);
submit.disabled = disable;
JX.DOM.alterClass(submit, 'disabled', disable);
};
// When he user shift-clicks the task, update the rest of the application
// state.
JX.Stratcom.listen(
'click',
'maniphest-task',
function(e) {
var raw = e.getRawEvent();
if (!raw.shiftKey) {
return;
}
if (raw.ctrlKey || raw.altKey || raw.metaKey || e.isRightButton()) {
return;
}
if (JX.Stratcom.pass(e)) {
return;
}
e.kill();
change(e.getNode('maniphest-task'));
clear_selection();
});
// When the user clicks "Select All", select all tasks.
JX.DOM.listen(
JX.$(config.selectNone),
'click',
null,
function(e) {
changeall(false);
e.kill();
});
// When the user clicks "Clear Selection", clear the selection.
JX.DOM.listen(
JX.$(config.selectAll),
'click',
null,
function(e) {
changeall(true);
e.kill();
});
// When the user submits the form, dump selected state into it.
JX.DOM.listen(
JX.$(config.formID),
'submit',
null,
function(e) {
var inputs = [];
for (var k in selected) {
inputs.push(
JX.$N('input', {type: 'hidden', name: 'batch[]', value: k}));
}
JX.DOM.setContent(JX.$(config.idContainer), inputs);
});
update();
});
diff --git a/webroot/rsrc/js/application/maniphest/behavior-task-preview.js b/webroot/rsrc/js/application/maniphest/behavior-task-preview.js
index c9293f1235..46bd583b36 100644
--- a/webroot/rsrc/js/application/maniphest/behavior-task-preview.js
+++ b/webroot/rsrc/js/application/maniphest/behavior-task-preview.js
@@ -1,29 +1,29 @@
/**
* @provides javelin-behavior-maniphest-description-preview
* @requires javelin-behavior
* javelin-dom
* javelin-util
* phabricator-shaped-request
*/
JX.behavior('maniphest-description-preview', function(config) {
var preview = JX.$(config.preview);
var textarea = JX.$(config.textarea);
var callback = function(r) {
JX.DOM.setContent(JX.$(config.preview), JX.$H(r));
};
var getdata = function() {
return {
description : textarea.value
};
- }
+ };
var request = new JX.PhabricatorShapedRequest(config.uri, callback, getdata);
var trigger = JX.bind(request, request.trigger);
JX.DOM.listen(textarea, 'keydown', null, trigger);
request.start();
});
diff --git a/webroot/rsrc/js/application/maniphest/behavior-transaction-controls.js b/webroot/rsrc/js/application/maniphest/behavior-transaction-controls.js
index b532f9b0b6..b4087067a2 100644
--- a/webroot/rsrc/js/application/maniphest/behavior-transaction-controls.js
+++ b/webroot/rsrc/js/application/maniphest/behavior-transaction-controls.js
@@ -1,36 +1,36 @@
/**
* @provides javelin-behavior-maniphest-transaction-controls
* @requires javelin-behavior
* javelin-dom
* phabricator-prefab
*/
JX.behavior('maniphest-transaction-controls', function(config) {
var tokenizers = {};
for (var k in config.tokenizers) {
var tconfig = config.tokenizers[k];
tokenizers[k] = JX.Prefab.buildTokenizer(tconfig).tokenizer;
- tokenizers[k].start()
+ tokenizers[k].start();
}
JX.DOM.listen(
JX.$(config.select),
'change',
null,
function(e) {
for (var k in config.controlMap) {
if (k == JX.$(config.select).value) {
JX.DOM.show(JX.$(config.controlMap[k]));
if (tokenizers[k]) {
tokenizers[k].refresh();
}
} else {
JX.DOM.hide(JX.$(config.controlMap[k]));
}
}
});
});
diff --git a/webroot/rsrc/js/application/maniphest/behavior-transaction-preview.js b/webroot/rsrc/js/application/maniphest/behavior-transaction-preview.js
index 96186c7974..ca18eb69d4 100644
--- a/webroot/rsrc/js/application/maniphest/behavior-transaction-preview.js
+++ b/webroot/rsrc/js/application/maniphest/behavior-transaction-preview.js
@@ -1,60 +1,60 @@
/**
* @provides javelin-behavior-maniphest-transaction-preview
* @requires javelin-behavior
* javelin-dom
* javelin-util
* javelin-json
* javelin-stratcom
* phabricator-shaped-request
*/
JX.behavior('maniphest-transaction-preview', function(config) {
var comments = JX.$(config.comments);
var action = JX.$(config.action);
var callback = function(r) {
JX.DOM.setContent(JX.$(config.preview), JX.$H(r));
};
var getdata = function() {
var selected = action.value;
var value = null;
try {
var control = JX.$(config.map[selected]);
var input = ([]
.concat(JX.DOM.scry(control, 'select'))
.concat(JX.DOM.scry(control, 'input')))[0];
if (JX.DOM.isType(input, 'input')) {
// Avoid reading 'value'(s) out of the tokenizer free text input.
if (input.type != 'hidden') {
value = null;
// Get the tokenizer and all that delicious data
} else {
var tokenizer_dom = JX.$(config.tokenizers[selected].id);
var tokenizer = JX.Stratcom.getData(tokenizer_dom).tokenizer;
value = JX.JSON.stringify(JX.keys(tokenizer.getTokens()));
}
} else {
value = input.value;
}
} catch (_ignored_) {
// Ignored.
}
return {
comments : comments.value,
action : selected,
value : value || ''
};
- }
+ };
var request = new JX.PhabricatorShapedRequest(config.uri, callback, getdata);
var trigger = JX.bind(request, request.trigger);
JX.DOM.listen(comments, 'keydown', null, trigger);
JX.DOM.listen(action, 'change', null, trigger);
request.start();
});
diff --git a/webroot/rsrc/js/application/phame/phame-post-preview.js b/webroot/rsrc/js/application/phame/phame-post-preview.js
index 2025bc744a..2fd15bd0cf 100644
--- a/webroot/rsrc/js/application/phame/phame-post-preview.js
+++ b/webroot/rsrc/js/application/phame/phame-post-preview.js
@@ -1,81 +1,81 @@
/**
* @provides javelin-behavior-phame-post-preview
* @requires javelin-behavior
* javelin-dom
* javelin-util
* phabricator-shaped-request
*/
JX.behavior('phame-post-preview', function(config) {
var preview = JX.$(config.preview);
var body = JX.$(config.body);
var title = JX.$(config.title);
var phame_title = JX.$(config.phame_title);
var sync_titles = true;
var titleCallback = function(e) {
if (!sync_titles) {
return;
}
- var title_string = new String(title.value);
+ var title_string = title.value;
phame_title.value = normalizeSlug(title_string);
- }
+ };
var phameTitleKeyupCallback = function (e) {
// stop sync'ing once user edits phame_title directly
sync_titles = false;
var normalized = normalizeSlug(phame_title.value, true);
if (normalized == phame_title.value) {
return;
}
var position = phame_title.value.length;
if ('selectionStart' in phame_title) {
position = phame_title.selectionStart;
}
phame_title.value = normalized;
if ('setSelectionRange' in phame_title) {
phame_title.focus();
phame_title.setSelectionRange(position, position);
}
- }
+ };
var phameTitleBlurCallback = function (e) {
phame_title.value = normalizeSlug(phame_title.value);
- }
+ };
// This is a sort of implementation of PhabricatorSlug::normalize
var normalizeSlug = function (slug, spare_trailing_underscore) {
var s = slug.toLowerCase().replace(/[^a-z0-9/]+/g, '_').substr(0, 63);
if (spare_trailing_underscore) {
// do nothing
} else {
s = s.replace(/_$/g, '');
}
return s;
- }
+ };
var callback = function(r) {
JX.DOM.setContent(JX.$(config.preview), JX.$H(r));
};
var getdata = function() {
return {
body : body.value,
title : title.value,
phame_title : phame_title.value
};
- }
+ };
var request = new JX.PhabricatorShapedRequest(config.uri, callback, getdata);
var trigger = JX.bind(request, request.trigger);
JX.DOM.listen(body, 'keydown', null, trigger);
JX.DOM.listen(title, 'keydown', null, trigger);
JX.DOM.listen(title, 'keyup', null, titleCallback);
JX.DOM.listen(phame_title, 'keydown', null, trigger);
JX.DOM.listen(phame_title, 'keyup', null, phameTitleKeyupCallback);
JX.DOM.listen(phame_title, 'blur', null, phameTitleBlurCallback);
request.start();
});
diff --git a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js
index bb8bf26f21..aced690ff9 100644
--- a/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js
+++ b/webroot/rsrc/js/application/pholio/behavior-pholio-mock-view.js
@@ -1,831 +1,833 @@
/**
* @provides javelin-behavior-pholio-mock-view
* @requires javelin-behavior
* javelin-util
* javelin-stratcom
* javelin-dom
* javelin-vector
* javelin-magical-init
* javelin-request
* javelin-history
* javelin-workflow
* javelin-mask
* javelin-behavior-device
* phabricator-keyboard-shortcut
*/
JX.behavior('pholio-mock-view', function(config) {
var is_dragging = false;
var drag_begin;
var drag_end;
var panel = JX.$(config.panelID);
var viewport = JX.$(config.viewportID);
var selection_border;
var selection_fill;
var active_image;
var inline_comments = {};
/* -( Stage )-------------------------------------------------------------- */
var stage = (function() {
var loading = false;
var stageElement = JX.$(config.panelID);
var viewElement = JX.$(config.viewportID);
var gutterElement = JX.$('mock-inline-comments');
var reticles = [];
var cards = [];
var inline_phid_map = {};
function begin_load() {
if (loading) {
return;
}
loading = true;
clear_stage();
draw_loading();
}
function end_load() {
if (!loading) {
return;
}
loading = false;
draw_loading();
}
function draw_loading() {
JX.DOM.alterClass(stageElement, 'pholio-image-loading', loading);
}
function add_inline_node(node, phid) {
inline_phid_map[phid] = (inline_phid_map[phid] || []);
inline_phid_map[phid].push(node);
}
function add_reticle(reticle, phid) {
mark_ref(reticle, phid);
reticles.push(reticle);
add_inline_node(reticle, phid);
viewElement.appendChild(reticle);
}
function clear_stage() {
- for (var ii = 0; ii < reticles.length; ii++) {
+ var ii;
+ for (ii = 0; ii < reticles.length; ii++) {
JX.DOM.remove(reticles[ii]);
}
- for (var ii = 0; ii < cards.length; ii++) {
+ for (ii = 0; ii < cards.length; ii++) {
JX.DOM.remove(cards[ii]);
}
reticles = [];
cards = [];
inline_phid_map = {};
}
function highlight_inline(phid, show) {
var nodes = inline_phid_map[phid] || [];
var cls = 'pholio-mock-inline-comment-highlight';
for (var ii = 0; ii < nodes.length; ii++) {
JX.DOM.alterClass(nodes[ii], cls, show);
}
}
function remove_inline(phid) {
var nodes = inline_phid_map[phid] || [];
for (var ii = 0; ii < nodes.length; ii++) {
JX.DOM.remove(nodes[ii]);
}
delete inline_phid_map[phid];
}
function mark_ref(node, phid) {
JX.Stratcom.addSigil(node, 'pholio-inline-ref');
JX.Stratcom.addData(node, {phid: phid});
}
function add_card(card, phid) {
mark_ref(card, phid);
cards.push(card);
add_inline_node(card, phid);
gutterElement.appendChild(card);
}
return {
beginLoad: begin_load,
endLoad: end_load,
addReticle: add_reticle,
clearStage: clear_stage,
highlightInline: highlight_inline,
removeInline: remove_inline,
addCard: add_card
};
})();
function get_image_index(id) {
for (var ii = 0; ii < config.images.length; ii++) {
if (config.images[ii].id == id) {
return ii;
}
}
return null;
}
function get_image(id) {
var idx = get_image_index(id);
if (idx === null) {
return idx;
}
return config.images[idx];
}
function onload_image(id) {
if (active_image.id != id) {
// The user has clicked another image before this one loaded, so just
// bail.
return;
}
active_image.tag = this;
redraw_image();
}
function switch_image(delta) {
if (!active_image) {
return;
}
- var idx = get_image_index(active_image.id)
+ var idx = get_image_index(active_image.id);
idx = (idx + delta + config.images.length) % config.images.length;
select_image(config.images[idx].id);
}
function redraw_image() {
// Force the stage to scale as a function of the viewport size. Broadly,
// we make the stage 95% of the height of the viewport, then scale images
// to fit within it.
var new_y = (JX.Vector.getViewport().y * 0.90) - 150;
new_y = Math.max(320, new_y);
panel.style.height = new_y + 'px';
if (!active_image || !active_image.tag) {
return;
}
var tag = active_image.tag;
// If the image is too wide or tall for the viewport, scale it down so it
// fits.
var w = JX.Vector.getDim(panel);
w.x -= 40;
w.y -= 40;
var scale = 1;
if (w.x < tag.naturalWidth) {
scale = Math.min(scale, w.x / tag.naturalWidth);
}
if (w.y < tag.naturalHeight) {
scale = Math.min(scale, w.y / tag.naturalHeight);
}
if (scale < 1) {
tag.width = Math.floor(scale * tag.naturalWidth);
tag.height = Math.floor(scale * tag.naturalHeight);
} else {
tag.width = tag.naturalWidth;
tag.height = tag.naturalHeight;
}
viewport.style.top = Math.floor((new_y - tag.height) / 2) + 'px';
stage.endLoad();
JX.DOM.setContent(viewport, tag);
redraw_inlines(active_image.id);
}
function select_image(image_id) {
active_image = get_image(image_id);
active_image.tag = null;
stage.beginLoad();
var img = JX.$N('img', {className: 'pholio-mock-image'});
img.onload = JX.bind(img, onload_image, active_image.id);
img.src = active_image.fullURI;
var thumbs = JX.DOM.scry(
JX.$('pholio-mock-carousel'),
'a',
'mock-thumbnail');
for(var k in thumbs) {
var thumb_meta = JX.Stratcom.getData(thumbs[k]);
JX.DOM.alterClass(
thumbs[k],
'pholio-mock-carousel-thumb-current',
(active_image.id == thumb_meta.imageID));
}
load_inline_comments();
if (image_id != config.selectedID) {
JX.History.replace(active_image.pageURI);
}
}
JX.Stratcom.listen(
['mousedown', 'click'],
'mock-thumbnail',
function(e) {
if (!e.isNormalMouseEvent()) {
return;
}
e.kill();
select_image(e.getNodeData('mock-thumbnail').imageID);
});
select_image(config.selectedID);
JX.Stratcom.listen('mousedown', 'mock-viewport', function(e) {
if (!e.isNormalMouseEvent()) {
return;
}
if (JX.Device.getDevice() != 'desktop') {
return;
}
if (drag_begin) {
return;
}
e.kill();
is_dragging = true;
drag_begin = get_image_xy(JX.$V(e));
drag_end = drag_begin;
redraw_selection();
});
JX.enableDispatch(document.body, 'mousemove');
JX.Stratcom.listen('mousemove', null, function(e) {
if (!is_dragging) {
return;
}
drag_end = get_image_xy(JX.$V(e));
redraw_selection();
});
JX.Stratcom.listen(
['mouseover', 'mouseout'],
'pholio-inline-ref',
function(e) {
var phid = e.getNodeData('pholio-inline-ref').phid;
var show = (e.getType() == 'mouseover');
stage.highlightInline(phid, show);
});
JX.Stratcom.listen(
'mouseup',
null,
function(e) {
if (!is_dragging) {
return;
}
is_dragging = false;
if (!config.loggedIn) {
new JX.Workflow(config.logInLink).start();
return;
}
drag_end = get_image_xy(JX.$V(e));
resize_selection(16);
var data = {mockID: config.mockID};
var handler = function(r) {
var dialog = JX.$H(r).getFragment().firstChild;
JX.DOM.appendContent(viewport, dialog);
JX.$V(
Math.min(drag_begin.x, drag_end.x),
Math.max(drag_begin.y, drag_end.y) + 4
).setPos(dialog);
JX.DOM.focus(JX.DOM.find(dialog, 'textarea'));
- }
+ };
new JX.Workflow('/pholio/inline/save/', data)
.setHandler(handler)
.start();
});
function resize_selection(min_size) {
var start = {
x: Math.min(drag_begin.x, drag_end.x),
y: Math.min(drag_begin.y, drag_end.y)
};
var end = {
x: Math.max(drag_begin.x, drag_end.x),
y: Math.max(drag_begin.y, drag_end.y)
};
var width = end.x - start.x;
var height = end.y - start.y;
+ var addon;
if (width < min_size) {
- var addon = (min_size-width)/2;
+ addon = (min_size-width)/2;
start.x = Math.max(0, start.x - addon);
end.x = Math.min(active_image.tag.naturalWidth, end.x + addon);
- if (start.x == 0) {
+ if (start.x === 0) {
end.x = Math.min(min_size, active_image.tag.naturalWidth);
} else if (end.x == active_image.tag.naturalWidth) {
start.x = Math.max(0, active_image.tag.naturalWidth - min_size);
}
}
if (height < min_size) {
- var addon = (min_size-height)/2;
+ addon = (min_size-height)/2;
start.y = Math.max(0, start.y - addon);
end.y = Math.min(active_image.tag.naturalHeight, end.y + addon);
- if (start.y == 0) {
+ if (start.y === 0) {
end.y = Math.min(min_size, active_image.tag.naturalHeight);
} else if (end.y == active_image.tag.naturalHeight) {
start.y = Math.max(0, active_image.tag.naturalHeight - min_size);
}
}
drag_begin = start;
drag_end = end;
redraw_selection();
}
function redraw_inlines(id) {
if (!active_image) {
return;
}
if (active_image.id != id) {
return;
}
stage.clearStage();
var comment_holder = JX.$('mock-inline-comments');
JX.DOM.setContent(comment_holder, render_image_info(active_image));
var inlines = inline_comments[active_image.id];
if (!inlines || !inlines.length) {
return;
}
for (var ii = 0; ii < inlines.length; ii++) {
var inline = inlines[ii];
var card = JX.$H(inline.contentHTML).getFragment().firstChild;
stage.addCard(card, inline.phid);
if (!active_image.tag) {
// The image itself hasn't loaded yet, so we can't draw the inline
// reticles.
continue;
}
var inline_selection = render_reticle_fill();
stage.addReticle(inline_selection, inline.phid);
position_inline_rectangle(inline, inline_selection);
if (!inline.transactionphid) {
var inline_draft = render_reticle_border();
stage.addReticle(inline_draft, inline.phid);
position_inline_rectangle(inline, inline_draft);
}
}
}
function position_inline_rectangle(inline, rect) {
var scale = active_image.tag.width / active_image.tag.naturalWidth;
JX.$V(scale * inline.x, scale * inline.y).setPos(rect);
JX.$V(scale * inline.width, scale * inline.height).setDim(rect);
}
function get_image_xy(p) {
var img = active_image.tag;
var imgp = JX.$V(img);
var scale = 1 / get_image_scale();
var x = scale * Math.max(0, Math.min(p.x - imgp.x, img.width));
var y = scale * Math.max(0, Math.min(p.y - imgp.y, img.height));
return {
x: x,
y: y
};
}
function get_image_scale() {
var img = active_image.tag;
return img.width / img.naturalWidth;
}
function redraw_selection() {
selection_border = selection_border || render_reticle_border();
selection_fill = selection_fill || render_reticle_fill();
var p = JX.$V(
Math.min(drag_begin.x, drag_end.x),
Math.min(drag_begin.y, drag_end.y));
var d = JX.$V(
Math.max(drag_begin.x, drag_end.x) - p.x,
Math.max(drag_begin.y, drag_end.y) - p.y);
var scale = get_image_scale();
p.x *= scale;
p.y *= scale;
d.x *= scale;
d.y *= scale;
var nodes = [selection_fill, selection_border];
for (var ii = 0; ii < nodes.length; ii++) {
var node = nodes[ii];
viewport.appendChild(node);
p.setPos(node);
d.setDim(node);
}
}
function clear_selection() {
selection_fill && JX.DOM.remove(selection_fill);
selection_border && JX.DOM.remove(selection_border);
}
function load_inline_comments() {
var id = active_image.id;
var inline_comments_uri = "/pholio/inline/" + id + "/";
new JX.Request(inline_comments_uri, function(r) {
inline_comments[id] = r;
redraw_inlines(id);
}).send();
}
JX.Stratcom.listen(
'click',
'inline-delete',
function(e) {
var data = e.getNodeData('inline-delete');
e.kill();
interrupt_typing();
stage.removeInline(data.phid);
var deleteURI = '/pholio/inline/delete/' + data.id + '/';
var del = new JX.Request(deleteURI, function(r) {
});
del.send();
});
JX.Stratcom.listen(
'click',
'inline-edit',
function(e) {
var data = e.getNodeData('inline-edit');
e.kill();
interrupt_typing();
var editURI = "/pholio/inline/edit/" + data.id + '/';
var edit_dialog = new JX.Request(editURI, function(r) {
var dialog = JX.$N(
'div',
{
className: 'pholio-edit-inline-popup'
},
JX.$H(r));
JX.DOM.setContent(JX.$(data.phid + '_comment'), dialog);
});
edit_dialog.send();
});
JX.Stratcom.listen(
'click',
'inline-edit-cancel',
function(e) {
var data = e.getNodeData('inline-edit-cancel');
e.kill();
load_inline_comment(data.id);
});
JX.Stratcom.listen(
'click',
'inline-edit-submit',
function(e) {
var data = e.getNodeData('inline-edit-submit');
var editURI = "/pholio/inline/edit/" + data.id + '/';
e.kill();
var edit = new JX.Request(editURI, function(r) {
load_inline_comment(data.id);
});
edit.addData({
op: 'update',
content: JX.DOM.find(JX.$(data.phid + '_comment'), 'textarea').value
});
edit.send();
});
JX.Stratcom.listen(
'click',
'inline-save-cancel',
function(e) {
e.kill();
interrupt_typing();
}
);
JX.Stratcom.listen(
'click',
'inline-save-submit',
function(e) {
e.kill();
var form = JX.$('pholio-new-inline-comment-dialog');
var text = JX.DOM.find(form, 'textarea').value;
if (!text.length) {
interrupt_typing();
return;
}
var data = {
mockID: config.mockID,
imageID: active_image.id,
startX: Math.min(drag_begin.x, drag_end.x),
startY: Math.min(drag_begin.y, drag_end.y),
endX: Math.max(drag_begin.x, drag_end.x),
endY: Math.max(drag_begin.y, drag_end.y)
};
var handler = function(r) {
if (!inline_comments[active_image.id]) {
inline_comments[active_image.id] = [];
}
inline_comments[active_image.id].push(r);
interrupt_typing();
redraw_inlines(active_image.id);
};
JX.Workflow.newFromForm(form, data)
.setHandler(handler)
.start();
}
);
function load_inline_comment(id) {
var viewInlineURI = '/pholio/inline/view/' + id + '/';
var inline_comment = new JX.Request(viewInlineURI, function(r) {
JX.DOM.replace(JX.$(r.phid + '_comment'), JX.$H(r.contentHTML));
});
inline_comment.send();
}
function interrupt_typing() {
clear_selection();
try {
JX.DOM.remove(JX.$('pholio-new-inline-comment-dialog'));
} catch (x) {
// TODO: For now, ignore this.
}
drag_begin = null;
}
load_inline_comments();
JX.Stratcom.listen('resize', null, redraw_image);
redraw_image();
/* -( Keyboard Shortcuts )------------------------------------------------- */
new JX.KeyboardShortcut(['j', 'right'], 'Show next image.')
.setHandler(function() {
switch_image(1);
})
.register();
new JX.KeyboardShortcut(['k', 'left'], 'Show previous image.')
.setHandler(function() {
switch_image(-1);
})
.register();
JX.DOM.listen(panel, 'gesture.swipe.end', null, function(e) {
var data = e.getData();
if (data.length <= (JX.Vector.getDim(panel) / 2)) {
// If the user didn't move their finger far enough, don't switch.
return;
}
switch_image(data.direction == 'right' ? -1 : 1);
});
/* -( Render )------------------------------------------------------------- */
function render_image_info(image) {
var info = [];
var title = JX.$N(
'div',
{className: 'pholio-image-title'},
image.title);
info.push(title);
var desc = JX.$N(
'div',
{className: 'pholio-image-description'},
image.desc);
info.push(desc);
var embed = JX.$N(
'div',
{className: 'pholio-image-embedding'},
JX.$H('Embed this image:<br />{M' + config.mockID +
', image=' + image.id + '}'));
info.push(embed);
// Render image dimensions and visible size. If we have this infomation
// from the server we can display some of it immediately; otherwise, we need
// to wait for the image to load so we can read dimension information from
// it.
var image_x = image.width;
var image_y = image.height;
var display_x = null;
if (image.tag) {
image_x = image.tag.naturalWidth;
image_y = image.tag.naturalHeight;
display_x = image.tag.width;
}
var visible = [];
if (image_x) {
visible.push([image_x, '\u00d7', image_y, 'px']);
if (display_x) {
var area = Math.round(100 * (display_x / image_x));
visible.push(' ');
visible.push(
JX.$N(
'span',
{className: 'pholio-visible-size'},
['(', area, '%', ')']));
}
}
if (visible.length) {
info.push(visible);
}
var full_link = JX.$N(
'a',
{href: image.fullURI, target: '_blank'},
'View Full Image');
info.push(full_link);
for (var ii = 0; ii < info.length; ii++) {
info[ii] = JX.$N('div', {className: 'pholio-image-info-item'}, info[ii]);
}
info = JX.$N('div', {className: 'pholio-image-info'}, info);
return info;
}
function render_reticle_border() {
return JX.$N(
'div',
{className: 'pholio-mock-select-border'});
}
function render_reticle_fill() {
return JX.$N(
'div',
{className: 'pholio-mock-select-fill'});
}
/* -( Device Lightbox )---------------------------------------------------- */
// On devices, we show images full-size when the user taps them instead of
// attempting to implement inlines.
var lightbox = null;
JX.Stratcom.listen('click', 'mock-viewport', function(e) {
if (!e.isNormalMouseEvent()) {
return;
}
if (JX.Device.getDevice() == 'desktop') {
return;
}
lightbox_attach();
e.kill();
});
JX.Stratcom.listen('click', 'pholio-device-lightbox', lightbox_detach);
JX.Stratcom.listen('resize', null, lightbox_resize);
function lightbox_attach() {
JX.DOM.alterClass(document.body, 'lightbox-attached', true);
JX.Mask.show('jx-dark-mask');
lightbox = lightbox_render();
var image = JX.$N('img');
image.onload = lightbox_loaded;
setTimeout(function() {
image.src = active_image.fullURI;
}, 1000);
JX.DOM.setContent(lightbox, image);
JX.DOM.alterClass(lightbox, 'pholio-device-lightbox-loading', true);
lightbox_resize();
document.body.appendChild(lightbox);
}
function lightbox_detach() {
JX.DOM.remove(lightbox);
JX.Mask.hide();
JX.DOM.alterClass(document.body, 'lightbox-attached', false);
lightbox = null;
}
function lightbox_resize(e) {
if (!lightbox) {
return;
}
JX.Vector.getScroll().setPos(lightbox);
JX.Vector.getViewport().setDim(lightbox);
}
function lightbox_loaded() {
JX.DOM.alterClass(lightbox, 'pholio-device-lightbox-loading', false);
}
function lightbox_render() {
var el = JX.$N('div', {className: 'pholio-device-lightbox'});
JX.Stratcom.addSigil(el, 'pholio-device-lightbox');
return el;
}
/* -( Preload )------------------------------------------------------------ */
var preload = [];
for (var ii = 0; ii < config.images.length; ii++) {
preload.push(config.images[ii].fullURI);
}
function preload_next() {
next_src = preload[0];
if (!next_src) {
return;
}
preload.splice(0, 1);
var img = JX.$N('img');
img.onload = preload_next;
img.onerror = preload_next;
img.src = next_src;
}
preload_next();
});
diff --git a/webroot/rsrc/js/application/phriction/phriction-document-preview.js b/webroot/rsrc/js/application/phriction/phriction-document-preview.js
index 11649408f1..c806482d4e 100644
--- a/webroot/rsrc/js/application/phriction/phriction-document-preview.js
+++ b/webroot/rsrc/js/application/phriction/phriction-document-preview.js
@@ -1,29 +1,29 @@
/**
* @provides javelin-behavior-phriction-document-preview
* @requires javelin-behavior
* javelin-dom
* javelin-util
* phabricator-shaped-request
*/
JX.behavior('phriction-document-preview', function(config) {
var preview = JX.$(config.preview);
var textarea = JX.$(config.textarea);
var callback = function(r) {
JX.DOM.setContent(JX.$(config.preview), JX.$H(r));
};
var getdata = function() {
return {
document : textarea.value
};
- }
+ };
var request = new JX.PhabricatorShapedRequest(config.uri, callback, getdata);
var trigger = JX.bind(request, request.trigger);
JX.DOM.listen(textarea, 'keydown', null, trigger);
request.start();
});
diff --git a/webroot/rsrc/js/application/ponder/behavior-votebox.js b/webroot/rsrc/js/application/ponder/behavior-votebox.js
index 15c3197484..f72d17a1bf 100644
--- a/webroot/rsrc/js/application/ponder/behavior-votebox.js
+++ b/webroot/rsrc/js/application/ponder/behavior-votebox.js
@@ -1,55 +1,55 @@
/**
* @provides javelin-behavior-ponder-votebox
* @requires javelin-behavior
* javelin-dom
* javelin-util
* javelin-stratcom
* javelin-request
*/
JX.behavior('ponder-votebox', function(config) {
function handle_vote(e, vote) {
e.kill();
var root = e.getNode('ponder-votable');
var data = e.getNodeData('ponder-votable');
if (data.vote != vote) {
data.vote = vote;
data.count += vote;
} else {
// User is undoing their vote.
data.vote = 0;
data.count -= vote;
}
var upv = JX.DOM.find(root, 'a', 'upvote');
JX.DOM.alterClass(upv, 'ponder-vote-active', (data.vote > 0));
var downv = JX.DOM.find(root, 'a', 'downvote');
- JX.DOM.alterClass(downv, 'ponder-vote-active', (data.vote < 0))
+ JX.DOM.alterClass(downv, 'ponder-vote-active', (data.vote < 0));
JX.DOM.setContent(
JX.DOM.find(root, 'div', 'ponder-vote-count'),
data.count);
new JX.Request(e.getTarget().href, JX.bag)
.setData({vote: data.vote})
- .send()
+ .send();
}
JX.Stratcom.listen(
'click',
'downvote',
function(e) {
handle_vote(e, -1);
});
JX.Stratcom.listen(
'click',
'upvote',
function(e) {
handle_vote(e, 1);
});
});
diff --git a/webroot/rsrc/js/application/releeph/releeph-preview-branch.js b/webroot/rsrc/js/application/releeph/releeph-preview-branch.js
index 76e406bd73..269275c707 100644
--- a/webroot/rsrc/js/application/releeph/releeph-preview-branch.js
+++ b/webroot/rsrc/js/application/releeph/releeph-preview-branch.js
@@ -1,49 +1,48 @@
/**
* @provides javelin-behavior-releeph-preview-branch
* @requires javelin-behavior
* javelin-dom
- * javelin-stratcom
* javelin-uri
- * javelin-util
+ * javelin-request
*/
JX.behavior('releeph-preview-branch', function(config) {
var uri = JX.$U(config.uri);
- for (param_name in config.params.static) {
+ for (var param_name in config.params.static) {
var value = config.params.static[param_name];
uri.setQueryParam(param_name, value);
}
var output = JX.$(config.outputID);
var dynamics = config.params.dynamic;
function renderPreview() {
- for (param_name in dynamics) {
+ for (var param_name in dynamics) {
var node_id = dynamics[param_name];
var input = JX.$(node_id);
uri.setQueryParam(param_name, input.value);
}
var request = new JX.Request(uri, function(response) {
JX.DOM.setContent(output, JX.$H(response.markup));
});
request.send();
}
renderPreview();
- for (ii in dynamics) {
+ for (var ii in dynamics) {
var node_id = dynamics[ii];
var input = JX.$(node_id);
JX.DOM.listen(
input,
['keyup', 'click', 'change'],
null,
function(e) {
renderPreview();
}
);
}
});
diff --git a/webroot/rsrc/js/application/releeph/releeph-request-state-change.js b/webroot/rsrc/js/application/releeph/releeph-request-state-change.js
index 286d527b84..14cf5cbe49 100644
--- a/webroot/rsrc/js/application/releeph/releeph-request-state-change.js
+++ b/webroot/rsrc/js/application/releeph/releeph-request-state-change.js
@@ -1,145 +1,145 @@
/**
* @provides javelin-behavior-releeph-request-state-change
* @requires javelin-behavior
* javelin-dom
* javelin-stratcom
- * javelin-util
+ * javelin-request
* phabricator-keyboard-shortcut
* phabricator-notification
*/
JX.behavior('releeph-request-state-change', function(config) {
var root = JX.DOM.find(document, 'div', 'releeph-request-header-list');
function getRequestHeaderNodes() {
return JX.DOM.scry(root, 'div', 'releeph-request-header');
}
/**
* Keyboard navigation
*/
var keynav_cursor = -1;
var notification = new JX.Notification();
function keynavJump(manager, delta) {
// Calculate this everytime, because the DOM changes.
var headers = getRequestHeaderNodes();
keynav_cursor += delta;
if (keynav_cursor < 0) {
keynav_cursor = -1;
window.scrollTo(0);
keynavMarkup();
return;
}
if (keynav_cursor >= headers.length) {
keynav_cursor = headers.length - 1;
}
var focus = headers[keynav_cursor];
manager.scrollTo(focus);
keynavMarkup();
}
function keynavMarkup() {
var headers = getRequestHeaderNodes();
- for (ii in headers) {
- JX.DOM.alterClass(headers[ii], 'focus', ii == keynav_cursor);
+ for (var k in headers) {
+ JX.DOM.alterClass(headers[k], 'focus', k == keynav_cursor);
}
}
function keynavAction(manager, action_name) {
var headers = getRequestHeaderNodes();
var header = headers[keynav_cursor];
if (keynav_cursor < 0) {
return;
}
var sigil = action_name;
var button = JX.DOM.find(header, 'a', sigil);
if (button) {
button.click();
}
}
function keynavNavigateToRequestPage() {
var headers = getRequestHeaderNodes();
var header = headers[keynav_cursor];
JX.DOM.find(header, 'a', 'hidden-link').click();
}
new JX.KeyboardShortcut('j', 'Jump to next request.')
.setHandler(function(manager) {
keynavJump(manager, +1);
})
.register();
new JX.KeyboardShortcut('k', 'Jump to previous request.')
.setHandler(function(manager) {
keynavJump(manager, -1);
})
.register();
new JX.KeyboardShortcut('a', 'Approve the selected request.')
.setHandler(function(manager) {
keynavAction(manager, 'want');
})
.register();
new JX.KeyboardShortcut('r', 'Reject the selected request.')
.setHandler(function(manager) {
keynavAction(manager, 'pass');
})
.register();
new JX.KeyboardShortcut('g', "Open selected request's page in a new tab.")
.setHandler(function(manager) {
keynavNavigateToRequestPage();
})
.register();
/**
* AJAXy state changes for request buttons.
*/
function request_action(node, url) {
var request = new JX.Request(url, function(response) {
if (config.reload) {
window.location.reload();
} else {
var markup = JX.$H(response.markup);
JX.DOM.replace(node, markup);
keynavMarkup();
}
});
request.send();
}
JX.Stratcom.listen(
'click',
'releeph-request-state-change',
function(e) {
var button = e.getNode('releeph-request-state-change');
var node = e.getNode('releeph-request-header');
var url = e.getNodeData('releeph-request-state-change');
// If this button has no action, or we've already responded to the first
// click...
if (!url || button.disabled) {
return;
}
// There's a race condition here though :(
JX.DOM.alterClass(button, 'disabled', true);
button.disabled = true;
e.prevent();
request_action(node, url);
}
);
});
diff --git a/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js b/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js
index fd932dd73b..d8b8db7321 100644
--- a/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js
+++ b/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js
@@ -1,84 +1,79 @@
/**
* @provides javelin-behavior-releeph-request-typeahead
* @requires javelin-behavior
- * javelin-util
* javelin-dom
* javelin-typeahead
- * javelin-tokenizer
- * javelin-typeahead-preloaded-source
* javelin-typeahead-ondemand-source
* javelin-dom
- * javelin-stratcom
- * javelin-util
*/
JX.behavior('releeph-request-typeahead', function(config) {
var root = JX.$(config.id);
var datasource = new JX.TypeaheadOnDemandSource(config.src);
var callsign = config.aux.callsign;
datasource.setAuxiliaryData(config.aux);
datasource.setTransformer(
function(object) {
var full_commit_id = object[0];
var short_commit_id = object[1];
var author = object[2];
var ago = object[3];
var summary = object[4];
var callsign_commit_id = 'r' + callsign + short_commit_id;
var box =
JX.$N(
'div',
{},
[
JX.$N(
'div',
{ className: 'commit-id' },
callsign_commit_id
),
JX.$N(
'div',
{ className: 'author-info' },
ago + ' ago by ' + author
),
JX.$N(
'div',
{ className: 'summary' },
summary
- ),
+ )
]
);
return {
name: callsign_commit_id,
tokenizable: callsign_commit_id + ' '+ short_commit_id + ' ' + summary,
display: box,
uri: null,
id: full_commit_id
};
});
/**
* The default normalizer removes useful control characters that would help
* out search. For example, I was just trying to search for a commit with
* the string "a_file" in the message, which was normalized to "afile".
*/
datasource.setNormalizer(function(query) {
return query;
});
datasource.setMaximumResultCount(config.aux.limit);
var typeahead = new JX.Typeahead(root);
typeahead.setDatasource(datasource);
var placeholder = config.value || config.placeholder;
if (placeholder) {
typeahead.setPlaceholder(placeholder);
}
typeahead.start();
});
diff --git a/webroot/rsrc/js/application/slowvote/behavior-slowvote-embed.js b/webroot/rsrc/js/application/slowvote/behavior-slowvote-embed.js
index b35cdadd09..b762c1c74b 100644
--- a/webroot/rsrc/js/application/slowvote/behavior-slowvote-embed.js
+++ b/webroot/rsrc/js/application/slowvote/behavior-slowvote-embed.js
@@ -1,43 +1,43 @@
/**
* @provides javelin-behavior-slowvote-embed
* @requires javelin-behavior
- * javelin-util
+ * javelin-request
* javelin-stratcom
* javelin-dom
*/
JX.behavior('slowvote-embed', function(config) {
JX.Stratcom.listen(
['click'],
'slowvote-option',
function(e) {
if (!e.isNormalMouseEvent()) {
return;
}
e.kill();
var pollID = e.getNodeData('slowvote-embed').pollID;
var voteURI = '/vote/' + pollID + '/';
var request = new JX.Request(voteURI, function(r) {
var updated_poll = JX.$H(r.contentHTML);
var root = JX.$('base-page');
var polls = JX.DOM.scry(root, 'div', 'slowvote-embed');
for(var i = 0; i < polls.length; i++) {
var data = JX.Stratcom.getData(polls[i]);
if (data.pollID == pollID) {
JX.DOM.replace(polls[i], updated_poll);
}
}
});
request.addData({vote: e.getNodeData('slowvote-option').optionID});
request.send();
});
});
diff --git a/webroot/rsrc/js/application/transactions/behavior-transaction-comment-form.js b/webroot/rsrc/js/application/transactions/behavior-transaction-comment-form.js
index 2c740b8889..7203988df6 100644
--- a/webroot/rsrc/js/application/transactions/behavior-transaction-comment-form.js
+++ b/webroot/rsrc/js/application/transactions/behavior-transaction-comment-form.js
@@ -1,54 +1,54 @@
/**
* @provides javelin-behavior-phabricator-transaction-comment-form
* @requires javelin-behavior
* javelin-dom
* javelin-util
* phabricator-shaped-request
*/
JX.behavior('phabricator-transaction-comment-form', function(config) {
var form = JX.$(config.formID);
JX.DOM.listen(form, 'willClear', null, function(e) {
e.kill();
JX.$(config.commentID).value = '';
});
var getdata = function() {
var obj = JX.DOM.convertFormToDictionary(form);
obj.__preview__ = 1;
if (config.draftKey) {
obj.__draft__ = config.draftKey;
}
return obj;
};
var onresponse = function(response) {
var panel = JX.$(config.panelID);
if (!response.xactions.length) {
JX.DOM.hide(panel);
} else {
JX.DOM.setContent(
JX.$(config.timelineID),
[
JX.$H(response.spacer),
JX.$H(response.xactions.join(response.spacer)),
- JX.$H(response.spacer),
+ JX.$H(response.spacer)
]);
JX.DOM.show(panel);
}
};
var request = new JX.PhabricatorShapedRequest(
config.actionURI,
onresponse,
getdata);
var trigger = JX.bind(request, request.trigger);
JX.DOM.listen(form, 'keydown', null, trigger);
request.start();
});
diff --git a/webroot/rsrc/js/application/uiexample/JavelinViewExample.js b/webroot/rsrc/js/application/uiexample/JavelinViewExample.js
index 5f51185a2c..7967e20c8c 100644
--- a/webroot/rsrc/js/application/uiexample/JavelinViewExample.js
+++ b/webroot/rsrc/js/application/uiexample/JavelinViewExample.js
@@ -1,20 +1,18 @@
/**
* @provides phabricator-uiexample-javelin-view
* @requires javelin-install
- * javelin-view
- * javelin-util
* javelin-dom
*/
JX.install('JavelinViewExample', {
extend: 'View',
members: {
render: function(rendered_children) {
return JX.$N(
'div',
{ className: 'client-view' },
rendered_children
);
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/ReactorButtonExample.js b/webroot/rsrc/js/application/uiexample/ReactorButtonExample.js
index 36d3a7bea2..07ad129f65 100644
--- a/webroot/rsrc/js/application/uiexample/ReactorButtonExample.js
+++ b/webroot/rsrc/js/application/uiexample/ReactorButtonExample.js
@@ -1,38 +1,38 @@
/**
* @provides phabricator-uiexample-reactor-button
* @requires javelin-install
- * javelin-view
- * javelin-util
* javelin-dom
+ * javelin-util
+ * javelin-dynval
* javelin-reactor-dom
*/
JX.install('ReactorButtonExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var button = JX.$N('button', {}, "Fun");
var clicks = JX.RDOM.clickPulses(button);
var time = JX.RDOM.time();
// function snapshot(pulses, dynval) {
// return new DynVal(
// pulses.transform(JX.bind(dynval, dynval.getValueNow)),
// dynval.getValueNow()
// );
// }
//
// Below could be...
// time.snapshot(clicks)
// clicks.snapshot(time)
var snapshot_time = new JX.DynVal(
clicks.transform(JX.bind(time, time.getValueNow)),
time.getValueNow()
);
return [button, JX.RDOM.$DT(snapshot_time)];
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/ReactorCheckboxExample.js b/webroot/rsrc/js/application/uiexample/ReactorCheckboxExample.js
index 4845480b65..b308ee4dbe 100644
--- a/webroot/rsrc/js/application/uiexample/ReactorCheckboxExample.js
+++ b/webroot/rsrc/js/application/uiexample/ReactorCheckboxExample.js
@@ -1,19 +1,17 @@
/**
* @provides phabricator-uiexample-reactor-checkbox
* @requires javelin-install
- * javelin-view
- * javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorCheckboxExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var checkbox = JX.$N('input', {type: 'checkbox'});
return [checkbox, JX.RDOM.$DT(JX.RDOM.checkbox(checkbox))];
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/ReactorFocusExample.js b/webroot/rsrc/js/application/uiexample/ReactorFocusExample.js
index bba4151e18..af76b9624a 100644
--- a/webroot/rsrc/js/application/uiexample/ReactorFocusExample.js
+++ b/webroot/rsrc/js/application/uiexample/ReactorFocusExample.js
@@ -1,18 +1,16 @@
/**
* @provides phabricator-uiexample-reactor-focus
* @requires javelin-install
- * javelin-view
- * javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorFocusExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var input = JX.$N('input');
return [input, JX.RDOM.$DT(JX.RDOM.hasFocus(input))];
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/ReactorInputExample.js b/webroot/rsrc/js/application/uiexample/ReactorInputExample.js
index 1908801114..6b1a2c120f 100644
--- a/webroot/rsrc/js/application/uiexample/ReactorInputExample.js
+++ b/webroot/rsrc/js/application/uiexample/ReactorInputExample.js
@@ -1,35 +1,32 @@
/**
* @provides phabricator-uiexample-reactor-input
* @requires javelin-install
- * javelin-view
- * javelin-util
- * javelin-dom
* javelin-reactor-dom
* javelin-view-html
* javelin-view-interpreter
* javelin-view-renderer
*/
JX.install('ReactorInputExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var html = JX.HTMLView.registerToInterpreter(new JX.ViewInterpreter());
var raw_input = JX.ViewRenderer.render(
html.input({ value: this.getAttr('init') })
);
var input = JX.RDOM.input(raw_input);
return JX.ViewRenderer.render(
html.div(
raw_input,
html.br(),
html.span(JX.RDOM.$DT(input)),
html.br(),
html.span(JX.RDOM.$DT(input.calm(500)))
)
);
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/ReactorMouseoverExample.js b/webroot/rsrc/js/application/uiexample/ReactorMouseoverExample.js
index 5c37ae7628..05152d39d4 100644
--- a/webroot/rsrc/js/application/uiexample/ReactorMouseoverExample.js
+++ b/webroot/rsrc/js/application/uiexample/ReactorMouseoverExample.js
@@ -1,18 +1,16 @@
/**
* @provides phabricator-uiexample-reactor-mouseover
* @requires javelin-install
- * javelin-view
- * javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorMouseoverExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var target = JX.$N("span", "mouseover me ");
return [target, JX.RDOM.$DT(JX.RDOM.isMouseOver(target))];
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/ReactorRadioExample.js b/webroot/rsrc/js/application/uiexample/ReactorRadioExample.js
index 2c74217889..db74a2f022 100644
--- a/webroot/rsrc/js/application/uiexample/ReactorRadioExample.js
+++ b/webroot/rsrc/js/application/uiexample/ReactorRadioExample.js
@@ -1,26 +1,24 @@
/**
* @provides phabricator-uiexample-reactor-radio
* @requires javelin-install
- * javelin-view
- * javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorRadioExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var radio_one = JX.$N('input', {type: 'radio', name: 'n', value: 'one'});
var radio_two = JX.$N('input', {type: 'radio', name: 'n', value: 'two'});
radio_one.checked = true;
return [
radio_one,
radio_two,
JX.RDOM.$DT(JX.RDOM.radio([radio_one, radio_two]))
];
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/ReactorSelectExample.js b/webroot/rsrc/js/application/uiexample/ReactorSelectExample.js
index ef3c02cf76..b7bb30acb1 100644
--- a/webroot/rsrc/js/application/uiexample/ReactorSelectExample.js
+++ b/webroot/rsrc/js/application/uiexample/ReactorSelectExample.js
@@ -1,23 +1,21 @@
/**
* @provides phabricator-uiexample-reactor-select
* @requires javelin-install
- * javelin-view
- * javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorSelectExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var select = JX.$N('select', {}, [
JX.$N('option', { value: 'goat' }, 'Goat'),
JX.$N('option', { value: 'bat' }, 'Bat'),
- JX.$N('option', { value: 'duck' }, 'Duck'),
+ JX.$N('option', { value: 'duck' }, 'Duck')
]);
return [select, JX.RDOM.$DT(JX.RDOM.select(select))];
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/ReactorSendClassExample.js b/webroot/rsrc/js/application/uiexample/ReactorSendClassExample.js
index c97ebd279c..70615d9fec 100644
--- a/webroot/rsrc/js/application/uiexample/ReactorSendClassExample.js
+++ b/webroot/rsrc/js/application/uiexample/ReactorSendClassExample.js
@@ -1,20 +1,18 @@
/**
* @provides phabricator-uiexample-reactor-sendclass
* @requires javelin-install
- * javelin-view
- * javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorSendClassExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var input = JX.$N('input', { type: 'checkbox' });
var span = JX.$N('a', 'Hey');
JX.RDOM.sendClass(JX.RDOM.checkbox(input), span, 'disabled');
return [input, span];
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js b/webroot/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js
index 61478c84ea..eeae796c2a 100644
--- a/webroot/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js
+++ b/webroot/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js
@@ -1,28 +1,26 @@
/**
* @provides phabricator-uiexample-reactor-sendproperties
* @requires javelin-install
- * javelin-view
- * javelin-util
* javelin-dom
* javelin-reactor-dom
*/
JX.install('ReactorSendPropertiesExample', {
extend: 'View',
members: {
render: function(rendered_children) {
var color = JX.$N('input', {value: '#fff000'});
var title = JX.$N('input', {value: 'seen on hover'});
var target = JX.$N('span', 'Change my color and title');
JX.RDOM.sendProps(target, {
style: {
backgroundColor: JX.RDOM.input(color)
},
title: JX.RDOM.input(title)
});
return [color, title, target];
}
}
});
diff --git a/webroot/rsrc/js/application/uiexample/gesture-example.js b/webroot/rsrc/js/application/uiexample/gesture-example.js
index 8fdf8351ed..92495f97d1 100644
--- a/webroot/rsrc/js/application/uiexample/gesture-example.js
+++ b/webroot/rsrc/js/application/uiexample/gesture-example.js
@@ -1,85 +1,87 @@
/**
* @requires javelin-stratcom
* javelin-behavior
* javelin-vector
* javelin-dom
* @provides javelin-behavior-phabricator-gesture-example
*/
JX.behavior('phabricator-gesture-example', function(config) {
var strokes = [];
var current = [];
var root = JX.$(config.rootID);
var canvas = JX.$N('canvas');
var d = JX.Vector.getDim(root);
canvas.width = d.x;
canvas.height = d.y;
root.appendChild(canvas);
var cxt = canvas.getContext('2d');
JX.Stratcom.listen(
'gesture.swipe.end',
null,
function(e) {
var stroke = get_stroke(e);
strokes.push(stroke);
current = [];
redraw();
});
JX.Stratcom.listen(
'gesture.swipe.move',
null,
function(e) {
var stroke = get_stroke(e);
current = [stroke];
redraw();
});
JX.Stratcom.listen(
'gesture.swipe.cancel',
null,
function(e) {
current = [];
redraw();
});
function get_stroke(e) {
var data = e.getData();
var p = JX.$V(root);
return [
data.p0.x - p.x,
data.p0.y - p.y,
data.p1.x - p.x,
data.p1.y - p.y
];
}
function redraw() {
cxt.fillStyle = '#dfdfdf';
cxt.fillRect(0, 0, d.x, d.y);
- for (var ii = 0; ii < strokes.length; ii++) {
- var s = strokes[ii];
+ var s;
+ var ii;
+ for (ii = 0; ii < strokes.length; ii++) {
+ s = strokes[ii];
cxt.strokeStyle = 'rgba(0, 0, 0, 0.50)';
cxt.beginPath();
cxt.moveTo(s[0], s[1]);
cxt.lineTo(s[2], s[3]);
cxt.stroke();
}
- for (var ii = 0; ii < current.length; ii++) {
- var s = current[ii];
+ for (ii = 0; ii < current.length; ii++) {
+ s = current[ii];
cxt.strokeStyle = 'rgba(255, 0, 0, 1)';
cxt.beginPath();
cxt.moveTo(s[0], s[1]);
cxt.lineTo(s[2], s[3]);
cxt.stroke();
}
}
redraw();
});
diff --git a/webroot/rsrc/js/application/uiexample/notification-example.js b/webroot/rsrc/js/application/uiexample/notification-example.js
index 6767b43b64..631c4139a9 100644
--- a/webroot/rsrc/js/application/uiexample/notification-example.js
+++ b/webroot/rsrc/js/application/uiexample/notification-example.js
@@ -1,67 +1,66 @@
/**
* @requires phabricator-notification
* javelin-stratcom
* javelin-behavior
- * javelin-uri
* @provides javelin-behavior-phabricator-notification-example
*/
JX.behavior('phabricator-notification-example', function(config) {
var sequence = 0;
JX.Stratcom.listen(
'click',
'notification-example',
function(e) {
e.kill();
var notification = new JX.Notification();
switch (sequence % 4) {
case 0:
var update = function() {
notification.setContent('It is ' + new Date().toString());
};
update();
setInterval(update, 1000);
break;
case 1:
notification
.setContent('Permanent alert notification (until clicked).')
.setDuration(0)
.alterClassName('jx-notification-alert', true);
break;
case 2:
notification
.setContent('This notification reacts when you click it.');
notification.listen(
'activate',
function() {
if (!confirm("Close notification?")) {
JX.Stratcom.context().kill();
}
});
break;
case 3:
notification
.setDuration(2000)
.setContent('This notification will close after 2 seconds ' +
'unless you keep clicking it!');
notification.listen(
'activate',
function() {
notification.setDuration(2000);
JX.Stratcom.context().kill();
});
break;
}
notification.show();
sequence++;
});
});
diff --git a/webroot/rsrc/js/core/DragAndDropFileUpload.js b/webroot/rsrc/js/core/DragAndDropFileUpload.js
index 531d04ceda..25c6c1a723 100644
--- a/webroot/rsrc/js/core/DragAndDropFileUpload.js
+++ b/webroot/rsrc/js/core/DragAndDropFileUpload.js
@@ -1,213 +1,213 @@
/**
* @requires javelin-install
* javelin-util
* javelin-request
* javelin-dom
* javelin-uri
* phabricator-file-upload
* @provides phabricator-drag-and-drop-file-upload
* @javelin
*/
JX.install('PhabricatorDragAndDropFileUpload', {
construct : function(node) {
this._node = node;
},
events : [
'didBeginDrag',
'didEndDrag',
'willUpload',
'progress',
'didUpload',
'didError'],
statics : {
isSupported : function() {
// TODO: Is there a better capability test for this? This seems okay in
// Safari, Firefox and Chrome.
return !!window.FileList;
},
isPasteSupported : function() {
// TODO: Needs to check if event.clipboardData is available.
// Works in Chrome, doesn't work in Firefox 10.
return !!window.FileList;
}
},
members : {
_node : null,
_depth : 0,
_updateDepth : function(delta) {
- if (this._depth == 0 && delta > 0) {
+ if (this._depth === 0 && delta > 0) {
this.invoke('didBeginDrag');
}
this._depth += delta;
- if (this._depth == 0 && delta < 0) {
+ if (this._depth === 0 && delta < 0) {
this.invoke('didEndDrag');
}
},
start : function() {
// TODO: move this to JX.DOM.contains()?
function contains(container, child) {
do {
if (child === container) {
return true;
}
child = child.parentNode;
} while (child);
return false;
}
// We track depth so that the _node may have children inside of it and
// not become unselected when they are dragged over.
JX.DOM.listen(
this._node,
'dragenter',
null,
JX.bind(this, function(e) {
if (contains(this._node, e.getTarget())) {
this._updateDepth(1);
}
}));
JX.DOM.listen(
this._node,
'dragleave',
null,
JX.bind(this, function(e) {
if (contains(this._node, e.getTarget())) {
this._updateDepth(-1);
}
}));
JX.DOM.listen(
this._node,
'dragover',
null,
function(e) {
// NOTE: We must set this, or Chrome refuses to drop files from the
// download shelf.
e.getRawEvent().dataTransfer.dropEffect = 'copy';
e.kill();
});
JX.DOM.listen(
this._node,
'drop',
null,
JX.bind(this, function(e) {
e.kill();
var files = e.getRawEvent().dataTransfer.files;
for (var ii = 0; ii < files.length; ii++) {
this._sendRequest(files[ii]);
}
// Force depth to 0.
this._updateDepth(-this._depth);
}));
if (JX.PhabricatorDragAndDropFileUpload.isPasteSupported()) {
JX.DOM.listen(
this._node,
'paste',
null,
JX.bind(this, function(e) {
var clipboardData = e.getRawEvent().clipboardData;
if (!clipboardData) {
return;
}
for (var ii = 0; ii < clipboardData.items.length; ii++) {
var item = clipboardData.items[ii];
if (!/^image\//.test(item.type)) {
continue;
}
this._sendRequest(item.getAsFile());
}
}));
}
},
_sendRequest : function(spec) {
var file = new JX.PhabricatorFileUpload()
.setName(spec.name)
.setTotalBytes(spec.size)
.setStatus('uploading')
.update();
this.invoke('willUpload', file);
var up_uri = JX.$U(this.getURI())
.setQueryParam('name', file.getName())
.setQueryParam('__upload__', 1)
.toString();
var onupload = JX.bind(this, function(r) {
if (r.error) {
file
.setStatus('error')
.setError(r.error)
.update();
this.invoke('didError', file);
} else {
file
.setID(r.id)
.setPHID(r.phid)
.setURI(r.uri)
.setMarkup(r.html)
.setStatus('done')
.update();
this.invoke('didUpload', file);
}
});
var req = new JX.Request(up_uri, onupload);
var onerror = JX.bind(this, function(error) {
file.setStatus('error');
if (error) {
file.setError(error.code + ': ' + error.info);
} else {
var xhr = req.getTransport();
if (xhr.responseText) {
file.setError('Server responded: ' + xhr.responseText);
}
}
file.update();
this.invoke('didError', file);
});
var onprogress = JX.bind(this, function(progress) {
file
.setTotalBytes(progress.total)
.setUploadedBytes(progress.loaded)
.update();
this.invoke('progress', file);
});
req.listen('error', onerror);
req.listen('uploadprogress', onprogress);
req
.setRawData(spec)
.send();
}
},
properties: {
URI : null,
activatedClass : null
}
});
diff --git a/webroot/rsrc/js/core/FileUpload.js b/webroot/rsrc/js/core/FileUpload.js
index 05f33300a0..bdc28f427f 100644
--- a/webroot/rsrc/js/core/FileUpload.js
+++ b/webroot/rsrc/js/core/FileUpload.js
@@ -1,113 +1,114 @@
/**
* @requires javelin-install
* javelin-dom
* phabricator-notification
* @provides phabricator-file-upload
* @javelin
*/
JX.install('PhabricatorFileUpload', {
construct : function() {
this._notification = new JX.Notification();
},
properties : {
name : null,
totalBytes : null,
uploadedBytes : null,
ID : null,
PHID : null,
URI : null,
status : null,
markup : null,
error : null
},
members : {
_notification : null,
update : function() {
if (!this._notification) {
return;
}
this._notification
.setDuration(0)
.show();
+ var content;
switch (this.getStatus()) {
case 'done':
var link = JX.$N('a', {href: this.getURI()}, 'F' + this.getID());
- var content = [
+ content = [
JX.$N('strong', {}, ['Upload Complete (', link, ')']),
JX.$N('br'),
this.getName()
];
this._notification
.setContent(content)
.alterClassName('jx-notification-done', true)
.setDuration(12000);
this._notification = null;
break;
case 'error':
- var content = [
+ content = [
JX.$N('strong', {}, 'Upload Failure'),
JX.$N('br'),
this.getName(),
JX.$N('br'),
JX.$N('br'),
this.getError()
];
this._notification
.setContent(content)
.alterClassName('jx-notification-error', true);
this._notification = null;
break;
default:
var info = '';
if (this.getTotalBytes()) {
var p = this._renderPercentComplete();
var f = this._renderFileSize();
info = ' (' + p + ' of ' + f + ')';
}
info = 'Uploading "' + this.getName() + '"' + info + '...';
this._notification
.setContent(info);
break;
}
return this;
},
_renderPercentComplete : function() {
if (!this.getTotalBytes()) {
return null;
}
var ratio = this.getUploadedBytes() / this.getTotalBytes();
- return parseInt(100 * ratio) + '%';
+ return parseInt(100 * ratio, 10) + '%';
},
_renderFileSize : function() {
if (!this.getTotalBytes()) {
return null;
}
var s = 3;
var n = this.getTotalBytes();
while (s && n >= 1000) {
n = Math.round(n / 100);
n = n / 10;
s--;
}
s = ['GB', 'MB', 'KB', 'bytes'][s];
return n + ' ' + s;
}
}
});
diff --git a/webroot/rsrc/js/core/Hovercard.js b/webroot/rsrc/js/core/Hovercard.js
index 0a9db67615..5174a85b5a 100644
--- a/webroot/rsrc/js/core/Hovercard.js
+++ b/webroot/rsrc/js/core/Hovercard.js
@@ -1,158 +1,158 @@
/**
* @requires javelin-install
* javelin-dom
* javelin-vector
* javelin-request
* javelin-uri
* @provides phabricator-hovercard
* @javelin
*/
JX.install('Hovercard', {
statics : {
_node : null,
_activeRoot : null,
_visiblePHID : null,
fetchUrl : '/search/hovercard/retrieve/',
/**
* Hovercard storage. {"PHID-XXXX-YYYY":"<...>", ...}
*/
_cards : {},
getAnchor : function() {
return this._activeRoot;
},
getCard : function() {
var self = JX.Hovercard;
return self._node;
},
show : function(root, phid) {
var self = JX.Hovercard;
// Already displaying
if (self.getCard() && phid == self._visiblePHID) {
return;
}
self.hide();
self._visiblePHID = phid;
self._activeRoot = root;
if (!(phid in self._cards)) {
self._load([phid]);
} else {
self._drawCard(phid);
}
},
_drawCard : function(phid) {
var self = JX.Hovercard;
// card is loading...
if (self._cards[phid] === true) {
return;
}
// Not the current requested card
if (phid != self._visiblePHID) {
return;
}
// Not loaded
if (!(phid in self._cards)) {
return;
}
var root = self._activeRoot;
var node = JX.$N('div',
{ className: 'jx-hovercard-container' },
JX.$H(self._cards[phid]));
self._node = node;
// Append the card to the document, but offscreen, so we can measure it.
node.style.left = '-10000px';
document.body.appendChild(node);
// Retrieve size from child (wrapper), since node gives wrong dimensions?
var child = node.firstChild;
var p = JX.$V(root);
var d = JX.Vector.getDim(root);
var n = JX.Vector.getDim(child);
// Move the tip so it's nicely aligned.
// I'm just doing north/south alignment for now
// TODO: Fix southern graceful align
var margin = 20;
// We can't shift left by ~$margin or more here due to Pholio, Phriction
- var x = parseInt(p.x) - margin / 2;
- var y = parseInt(p.y - n.y) - margin;
+ var x = parseInt(p.x, 10) - margin / 2;
+ var y = parseInt(p.y - n.y, 10) - margin;
// If more in the center, we can safely center
if (x > (n.x / 2) + margin) {
- x = parseInt(p.x - (n.x / 2) + d.x);
+ x = parseInt(p.x - (n.x / 2) + d.x, 10);
}
// Temporarily disabled, since it gives weird results (you can only see
// a hovercard once, as soon as it's hidden, it cannot be shown again)
// if (y < n.y) {
// // Place it southern, since northern is not enough space
// y = p.y + d.y + margin;
// }
node.style.left = x + 'px';
node.style.top = y + 'px';
},
hide : function() {
var self = JX.Hovercard;
self._visiblePHID = null;
self._activeRoot = null;
if (self._node) {
JX.DOM.remove(self._node);
self._node = null;
}
},
/**
* Pass it an array of phids to load them into storage
*
* @param list phids
*/
_load : function(phids) {
var self = JX.Hovercard;
var uri = JX.$U(self.fetchUrl);
var send = false;
for (var ii = 0; ii < phids.length; ii++) {
var phid = phids[ii];
if (phid in self._cards) {
continue;
}
self._cards[phid] = true; // means "loading"
uri.setQueryParam("phids["+ii+"]", phids[ii]);
send = true;
}
if (!send) {
// already loaded / loading everything!
return;
}
new JX.Request(uri, function(r) {
for (var phid in r.cards) {
self._cards[phid] = r.cards[phid];
// Don't draw if the user is faster than the browser
// Only draw if the user is still requesting the original card
if (self.getCard() && phid != self._visiblePHID) {
continue;
}
self._drawCard(phid);
}
}).send();
}
}
});
diff --git a/webroot/rsrc/js/core/Prefab.js b/webroot/rsrc/js/core/Prefab.js
index b3388d723a..56bd70ac7f 100644
--- a/webroot/rsrc/js/core/Prefab.js
+++ b/webroot/rsrc/js/core/Prefab.js
@@ -1,144 +1,146 @@
/**
* @provides phabricator-prefab
* @requires javelin-install
* javelin-util
* javelin-dom
* javelin-typeahead
* javelin-tokenizer
* javelin-typeahead-preloaded-source
* javelin-typeahead-ondemand-source
* javelin-dom
* javelin-stratcom
* javelin-util
* @javelin
*/
/**
* Utilities for client-side rendering (the greatest thing in the world).
*/
JX.install('Prefab', {
statics : {
renderSelect : function(map, selected, attrs) {
var select = JX.$N('select', attrs || {});
for (var k in map) {
select.options[select.options.length] = new Option(map[k], k);
if (k == selected) {
select.value = k;
}
}
select.value = select.value || JX.keys(map)[0];
return select;
},
/**
* Build a Phabricator tokenizer out of a configuration with application
* sorting, datasource and placeholder rules.
*
* - `id` Root tokenizer ID (alternatively, pass `root`).
* - `root` Root tokenizer node (replaces `id`).
* - `src` Datasource URI.
* - `ondemand` Optional, use an ondemand source.
* - `value` Optional, initial value.
* - `limit` Optional, token limit.
* - `placeholder` Optional, placeholder text.
* - `username` Optional, username to sort first (i.e., viewer).
*
*/
buildTokenizer : function(config) {
+ var root;
+
try {
- var root = config.root || JX.$(config.id);
+ root = config.root || JX.$(config.id);
} catch (ex) {
// If the root element does not exist, just return without building
// anything. This happens in some cases -- like Conpherence -- where we
// may load a tokenizer but not put it in the document.
return;
}
var datasource;
if (config.ondemand) {
datasource = new JX.TypeaheadOnDemandSource(config.src);
} else {
datasource = new JX.TypeaheadPreloadedSource(config.src);
}
// Sort results so that the viewing user always comes up first; after
// that, prefer unixname matches to realname matches.
var sort_handler = function(value, list, cmp) {
var priority_hits = {};
var self_hits = {};
var tokens = this.tokenize(value);
for (var ii = 0; ii < list.length; ii++) {
var item = list[ii];
if (!item.priority) {
continue;
}
if (config.username && item.priority == config.username) {
self_hits[item.id] = true;
}
for (var jj = 0; jj < tokens.length; jj++) {
if (item.priority.substr(0, tokens[jj].length) == tokens[jj]) {
priority_hits[item.id] = true;
}
}
}
list.sort(function(u, v) {
if (self_hits[u.id] != self_hits[v.id]) {
return self_hits[v.id] ? 1 : -1;
}
if (priority_hits[u.id] != priority_hits[v.id]) {
return priority_hits[v.id] ? 1 : -1;
}
return cmp(u, v);
});
};
datasource.setSortHandler(JX.bind(datasource, sort_handler));
datasource.setTransformer(
function(object) {
return {
name: object[0],
display: object[0],
uri: object[1],
id: object[2],
priority: object[3]
};
});
var typeahead = new JX.Typeahead(
root,
JX.DOM.find(root, 'input', 'tokenizer-input'));
typeahead.setDatasource(datasource);
var tokenizer = new JX.Tokenizer(root);
tokenizer.setTypeahead(typeahead);
if (config.placeholder) {
tokenizer.setPlaceholder(config.placeholder);
}
if (config.limit) {
tokenizer.setLimit(config.limit);
}
if (config.value) {
tokenizer.setInitialValue(config.value);
}
JX.Stratcom.addData(root, {'tokenizer' : tokenizer});
return {
tokenizer: tokenizer
};
}
}
});
diff --git a/webroot/rsrc/js/core/ToolTip.js b/webroot/rsrc/js/core/ToolTip.js
index b7db7b0f7d..399c937d63 100644
--- a/webroot/rsrc/js/core/ToolTip.js
+++ b/webroot/rsrc/js/core/ToolTip.js
@@ -1,82 +1,82 @@
/**
* @requires javelin-install
* javelin-util
* javelin-dom
* javelin-vector
* @provides phabricator-tooltip
* @javelin
*/
JX.install('Tooltip', {
statics : {
_node : null,
show : function(root, scale, align, content) {
if (__DEV__) {
switch (align) {
case 'N':
case 'E':
case 'S':
case 'W':
break;
default:
JX.$E(
"Only alignments 'N' (north), 'E' (east), 'S' (south), " +
"and 'W' (west) are supported."
);
break;
}
}
var node = JX.$N(
'div',
{ className: 'jx-tooltip-container jx-tooltip-align-' + align },
[
JX.$N('div', { className: 'jx-tooltip' }, content),
JX.$N('div', { className: 'jx-tooltip-anchor' })
]);
node.style.maxWidth = scale + 'px';
JX.Tooltip.hide();
this._node = node;
// Append the tip to the document, but offscreen, so we can measure it.
node.style.left = '-10000px';
document.body.appendChild(node);
var p = JX.$V(root);
var d = JX.Vector.getDim(root);
var n = JX.Vector.getDim(node);
// Move the tip so it's nicely aligned.
switch (align) {
case 'N':
- node.style.left = parseInt(p.x - ((n.x - d.x) / 2)) + 'px';
- node.style.top = parseInt(p.y - n.y) + 'px';
+ node.style.left = parseInt(p.x - ((n.x - d.x) / 2), 10) + 'px';
+ node.style.top = parseInt(p.y - n.y, 10) + 'px';
break;
case 'E':
- node.style.left = parseInt(p.x + d.x) + 'px';
- node.style.top = parseInt(p.y - ((n.y - d.y) / 2)) + 'px';
+ node.style.left = parseInt(p.x + d.x, 10) + 'px';
+ node.style.top = parseInt(p.y - ((n.y - d.y) / 2), 10) + 'px';
break;
case 'S':
- node.style.left = parseInt(p.x - ((n.x - d.x) / 2)) + 'px';
- node.style.top = parseInt(p.y + d.y + 5) + 'px';
+ node.style.left = parseInt(p.x - ((n.x - d.x) / 2), 10) + 'px';
+ node.style.top = parseInt(p.y + d.y + 5, 10) + 'px';
break;
case 'W':
- node.style.left = parseInt(p.x - n.x - 5) + 'px';
- node.style.top = parseInt(p.y - ((n.y - d.y) / 2)) + 'px';
+ node.style.left = parseInt(p.x - n.x - 5, 10) + 'px';
+ node.style.top = parseInt(p.y - ((n.y - d.y) / 2), 10) + 'px';
break;
}
},
hide : function() {
if (this._node) {
JX.DOM.remove(this._node);
this._node = null;
}
}
}
});
diff --git a/webroot/rsrc/js/core/behavior-active-nav.js b/webroot/rsrc/js/core/behavior-active-nav.js
index 7a2f83bb89..c0bc40b2a9 100644
--- a/webroot/rsrc/js/core/behavior-active-nav.js
+++ b/webroot/rsrc/js/core/behavior-active-nav.js
@@ -1,86 +1,87 @@
/**
* @provides javelin-behavior-phabricator-active-nav
* @requires javelin-behavior
* javelin-stratcom
* javelin-vector
* javelin-dom
* javelin-uri
*/
JX.behavior('phabricator-active-nav', function(config) {
var local = JX.$(config.localID);
/**
* Select the navigation item corresponding to a given anchor.
*/
var selectnav = function(anchor) {
var links = JX.DOM.scry(local, 'a');
var link;
var link_anchor;
var selected;
for (var ii = 0; ii < links.length; ii++) {
link = links[ii];
link_anchor = JX.$U(link.href).getFragment();
selected = (link_anchor == anchor);
JX.DOM.alterClass(
link,
'phabricator-active-nav-focus',
selected);
}
- }
+ };
/**
* Identify the current anchor based on the document scroll position.
*/
var updateposition = function() {
// Find all the markers in the document.
var scroll_position = JX.Vector.getScroll().y;
var document_size = JX.Vector.getDocument();
var viewport_size = JX.Vector.getViewport();
// If we're scrolled all the way down, we always want to select the last
// anchor.
var is_at_bottom = (viewport_size.y + scroll_position >= document_size.y);
var markers = JX.DOM.scry(document.body, 'legend', 'marker');
// Sort the markers by Y position, descending.
var markinfo = [];
- for (var ii = 0; ii < markers.length; ii++) {
+ var ii;
+ for (ii = 0; ii < markers.length; ii++) {
markinfo.push({
marker: markers[ii],
position: JX.$V(markers[ii]).y - 15
});
}
markinfo.sort(function(u, v) { return (v.position - u.position); });
// Find the first marker above the current scroll position, or the first
// marker in the document if we're above all the markers.
var active = null;
- for (var ii = 0; ii < markinfo.length; ii++) {
+ for (ii = 0; ii < markinfo.length; ii++) {
active = markinfo[ii].marker;
if (markinfo[ii].position <= scroll_position) {
break;
}
if (is_at_bottom) {
break;
}
}
// If we get above the first marker, select it.
selectnav(active && JX.Stratcom.getData(active).anchor);
- }
+ };
var pending = null;
var onviewportchange = function(e) {
pending && clearTimeout(pending);
pending = setTimeout(updateposition, 100);
- }
+ };
JX.Stratcom.listen('scroll', null, onviewportchange);
JX.Stratcom.listen('resize', null, onviewportchange);
JX.Stratcom.listen('hashchange', null, onviewportchange);
});
diff --git a/webroot/rsrc/js/core/behavior-fancy-datepicker.js b/webroot/rsrc/js/core/behavior-fancy-datepicker.js
index 7dab7e2c88..cd5ffb3b08 100644
--- a/webroot/rsrc/js/core/behavior-fancy-datepicker.js
+++ b/webroot/rsrc/js/core/behavior-fancy-datepicker.js
@@ -1,242 +1,243 @@
/**
* @provides javelin-behavior-fancy-datepicker
* @requires javelin-behavior
* javelin-util
* javelin-dom
* javelin-stratcom
* javelin-vector
*/
JX.behavior('fancy-datepicker', function(config) {
var picker;
var button;
var root;
var value_y;
var value_m;
var value_d;
var onopen = function(e) {
e.kill();
// If you click the calendar icon while the date picker is open, close it
// without writing the change.
if (picker) {
if (root == e.getNode('phabricator-date-control')) {
// If the user clicked the same control, just close it.
onclose(e);
return;
} else {
// If the user clicked a different control, close the old one but then
// open the new one.
onclose(e);
}
}
root = e.getNode('phabricator-date-control');
picker = JX.$N(
'div',
{className: 'fancy-datepicker', sigil: 'phabricator-datepicker'},
JX.$N('div', {className: 'fancy-datepicker-core'}));
document.body.appendChild(picker);
var button = e.getNode('calendar-button');
var p = JX.$V(button);
var d = JX.Vector.getDim(picker);
picker.style.left = (p.x - d.x + 2) + 'px';
picker.style.top = (p.y - 10) + 'px';
JX.DOM.alterClass(root, 'picker-open', true);
read_date();
render();
};
var onclose = function(e) {
if (!picker) {
return;
}
JX.DOM.remove(picker);
picker = null;
JX.DOM.alterClass(root, 'picker-open', false);
e.kill();
root = null;
};
var get_inputs = function() {
return {
y: JX.DOM.find(root, 'select', 'year-input'),
m: JX.DOM.find(root, 'select', 'month-input'),
d: JX.DOM.find(root, 'select', 'day-input')
};
- }
+ };
var read_date = function() {
var i = get_inputs();
value_y = +i.y.value;
value_m = +i.m.value;
value_d = +i.d.value;
};
var write_date = function() {
var i = get_inputs();
i.y.value = value_y;
i.m.value = value_m;
i.d.value = value_d;
};
var render = function() {
JX.DOM.setContent(
picker.firstChild,
[
render_month(),
- render_day(),
+ render_day()
]);
};
// Render a cell for the date picker.
var cell = function(label, value, selected, class_name) {
class_name = class_name || '';
if (selected) {
class_name += ' datepicker-selected';
}
if (!value) {
class_name += ' novalue';
}
return JX.$N('td', {meta: {value: value}, className: class_name}, label);
- }
+ };
// Render the top bar which allows you to pick a month and year.
var render_month = function() {
var months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'];
var buttons = [
cell("\u25C0", 'm:-1', false, 'lrbutton'),
cell(months[value_m - 1] + ' ' + value_y, null),
cell("\u25B6", 'm:1', false, 'lrbutton')];
return JX.$N(
'table',
{className: 'month-table'},
JX.$N('tr', {}, buttons));
};
// Render the day-of-week and calendar views.
var render_day = function() {
var weeks = [];
// First, render the weekday names.
var weekdays = 'SMTWTFS';
var weekday_names = [];
- for (var ii = 0; ii < weekdays.length; ii++) {
+ var ii;
+ for (ii = 0; ii < weekdays.length; ii++) {
weekday_names.push(cell(weekdays.charAt(ii), null, false, 'day-name'));
}
weeks.push(JX.$N('tr', {}, weekday_names));
// Render the calendar itself. NOTE: Javascript uses 0-based month indexes
// while we use 1-based month indexes, so we have to adjust for that.
var days = [];
var start = new Date(value_y, value_m - 1, 1).getDay();
while (start--) {
days.push(cell('', null, false, 'day-placeholder'));
}
var today = new Date();
- for (var ii = 1; ii <= 31; ii++) {
+ for (ii = 1; ii <= 31; ii++) {
var date = new Date(value_y, value_m - 1, ii);
if (date.getMonth() != (value_m - 1)) {
// We've spilled over into the next month, so stop rendering.
break;
}
var is_today = (today.getYear() == date.getYear() &&
today.getMonth() == date.getMonth() &&
today.getDate() == date.getDate());
var classes = [];
if (is_today) {
classes.push('today');
}
- if (date.getDay() == 0 || date.getDay() == 6) {
+ if (date.getDay() === 0 || date.getDay() == 6) {
classes.push('weekend');
}
days.push(cell(ii, 'd:'+ii, value_d == ii, classes.join(' ')));
}
// Slice the days into weeks.
- for (var ii = 0; ii < days.length; ii += 7) {
+ for (ii = 0; ii < days.length; ii += 7) {
weeks.push(JX.$N('tr', {}, days.slice(ii, ii + 7)));
}
return JX.$N('table', {className: 'day-table'}, weeks);
};
JX.Stratcom.listen('click', 'calendar-button', onopen);
JX.Stratcom.listen(
'click',
['phabricator-datepicker', 'tag:td'],
function(e) {
e.kill();
var data = e.getNodeData('tag:td');
if (!data.value) {
return;
}
var p = data.value.split(':');
switch (p[0]) {
case 'm':
// User clicked left or right month selection buttons.
- value_m = value_m + parseInt(p[1]);
+ value_m = value_m + parseInt(p[1], 10);
if (value_m > 12) {
value_m -= 12;
value_y++;
} else if (value_m <= 0) {
value_m += 12;
value_y--;
}
break;
case 'd':
// User clicked a day.
- value_d = parseInt(p[1]);
+ value_d = parseInt(p[1], 10);
write_date();
// Wait a moment to close the selector so they can see the effect
// of their action.
setTimeout(JX.bind(null, onclose, e), 150);
break;
}
render();
});
});
diff --git a/webroot/rsrc/js/core/behavior-global-drag-and-drop.js b/webroot/rsrc/js/core/behavior-global-drag-and-drop.js
index 8d4b7a443b..ad66625599 100644
--- a/webroot/rsrc/js/core/behavior-global-drag-and-drop.js
+++ b/webroot/rsrc/js/core/behavior-global-drag-and-drop.js
@@ -1,68 +1,68 @@
/**
* @provides javelin-behavior-global-drag-and-drop
* @requires javelin-behavior
* javelin-dom
* javelin-uri
* javelin-mask
* phabricator-drag-and-drop-file-upload
*/
JX.behavior('global-drag-and-drop', function(config) {
if (!JX.PhabricatorDragAndDropFileUpload.isSupported()) {
return;
}
var pending = 0;
var files = [];
var errors = false;
if (config.ifSupported) {
JX.$(config.ifSupported).style.display = '';
}
var drop = new JX.PhabricatorDragAndDropFileUpload(document.documentElement)
.setURI(config.uploadURI);
drop.listen('didBeginDrag', function(f) {
JX.Mask.show();
JX.DOM.show(JX.$(config.instructions));
});
drop.listen('didEndDrag', function(f) {
JX.Mask.hide();
JX.DOM.hide(JX.$(config.instructions));
});
drop.listen('willUpload', function(f) {
pending++;
});
drop.listen('didUpload', function(f) {
files.push(f);
pending--;
- if (pending == 0 && !errors) {
+ if (pending === 0 && !errors) {
// If whatever the user dropped in has finished uploading, send them to
// their uploads.
var uri;
uri = JX.$U(config.browseURI);
var ids = [];
for (var ii = 0; ii < files.length; ii++) {
ids.push(files[ii].getID());
}
uri.setQueryParam('h', ids.join(','));
files = [];
uri.go();
}
});
drop.listen('didError', function(f) {
pending--;
errors = true;
});
drop.start();
});
diff --git a/webroot/rsrc/js/core/behavior-hovercard.js b/webroot/rsrc/js/core/behavior-hovercard.js
index 86a9ef8f5c..6303d3c3bd 100644
--- a/webroot/rsrc/js/core/behavior-hovercard.js
+++ b/webroot/rsrc/js/core/behavior-hovercard.js
@@ -1,85 +1,85 @@
/**
* @provides javelin-behavior-phabricator-hovercards
* @requires javelin-behavior
* javelin-behavior-device
* javelin-stratcom
* javelin-vector
* phabricator-hovercard
* @javelin
*/
JX.behavior('phabricator-hovercards', function(config) {
// We listen for mousemove instead of mouseover to handle the case when user
// scrolls with keyboard. We don't want to display hovercard if node gets
// under the mouse cursor randomly placed somewhere on the screen. This
- // unfortunatelly doesn't work in Google Chrome which triggers both mousemove
+ // unfortunately doesn't work in Google Chrome which triggers both mousemove
// and mouseover in this case but works in other browsers.
JX.Stratcom.listen(
'mousemove',
'hovercard',
function (e) {
if (JX.Device.getDevice() != 'desktop') {
return;
}
var data = e.getNodeData('hovercard');
JX.Hovercard.show(
e.getNode('hovercard'),
data.hoverPHID);
});
JX.Stratcom.listen(
'mousemove',
null,
function (e) {
if (!JX.Hovercard.getCard()) {
return;
}
var root = JX.Hovercard.getAnchor();
var node = JX.Hovercard.getCard();
// TODO: Add southern cases here, too
var mouse = JX.$V(e);
var node_pos = JX.$V(node);
var node_dim = JX.Vector.getDim(node);
var root_pos = JX.$V(root);
var root_dim = JX.Vector.getDim(root);
var margin = 20;
// Cursor is above the node.
if (mouse.y < node_pos.y - margin) {
JX.Hovercard.hide();
}
// Cursor is below the root.
if (mouse.y > root_pos.y + root_dim.y + margin) {
JX.Hovercard.hide();
}
// Cursor is too far to the left.
if (mouse.x < Math.min(root_pos.x, node_pos.x) - margin) {
JX.Hovercard.hide();
}
// Cursor is too far to the right.
if (mouse.x >
Math.max(root_pos.x + root_dim.x, node_pos.x + node_dim.x) + margin) {
JX.Hovercard.hide();
}
});
// When we leave the page, hide any visible hovercards. If we don't do this,
// clicking a link with a hovercard and then hitting "back" will give you a
// phantom card. We also hide cards if the window resizes.
JX.Stratcom.listen(
['unload', 'onresize'],
null,
function(e) {
JX.Hovercard.hide();
});
});
diff --git a/webroot/rsrc/js/core/behavior-lightbox-attachments.js b/webroot/rsrc/js/core/behavior-lightbox-attachments.js
index 55d6bb4d22..477febd0ec 100644
--- a/webroot/rsrc/js/core/behavior-lightbox-attachments.js
+++ b/webroot/rsrc/js/core/behavior-lightbox-attachments.js
@@ -1,247 +1,247 @@
/**
* @provides javelin-behavior-lightbox-attachments
* @requires javelin-behavior
* javelin-stratcom
* javelin-dom
* javelin-mask
* javelin-util
* phabricator-busy
*/
JX.behavior('lightbox-attachments', function (config) {
var lightbox = null;
var prev = null;
var next = null;
var x_margin = 40;
var y_margin = 100;
var downloadForm = JX.$H(config.downloadForm).getFragment().firstChild;
function loadLightBox(e) {
if (!e.isNormalClick()) {
return;
}
if (JX.Stratcom.pass()) {
return;
}
e.prevent();
var links = JX.DOM.scry(document, 'a', 'lightboxable');
var phids = {};
var data;
for (var i = 0; i < links.length; i++) {
data = JX.Stratcom.getData(links[i]);
phids[data.phid] = links[i];
}
// Now that we have the big picture phid situation sorted out, figure
// out how the actual node the user clicks fits into that big picture
// and build some pretty UI to show the attachment.
var target = e.getNode('lightboxable');
var target_data = JX.Stratcom.getData(target);
var total = JX.keys(phids).length;
var current = 1;
var past_target = false;
for (var phid in phids) {
if (past_target) {
next = phids[phid];
break;
} else if (phid == target_data.phid) {
past_target = true;
} else {
prev = phids[phid];
current++;
}
}
var img_uri = '';
var extra_status = '';
var name_element = '';
// for now, this conditional is always true
// revisit if / when we decide to add non-images to lightbox view
if (target_data.viewable) {
img_uri = target_data.uri;
} else {
img_uri = config.defaultImageUri;
extra_status = ' Image may not be representative of actual attachment.';
name_element = JX.$N('div',
{ className : 'attachment-name' },
target_data.name
);
}
var img = JX.$N('img',
{
className : 'loading',
alt : target_data.name,
title : target_data.name
}
);
lightbox = JX.$N('div',
{
className : 'lightbox-attachment',
sigil: 'lightbox-attachment'
},
img
);
JX.DOM.appendContent(lightbox, name_element);
var closeIcon = JX.$N('a',
{
className : 'lightbox-close',
href : '#'
}
);
JX.DOM.listen(closeIcon, 'click', null, closeLightBox);
JX.DOM.appendContent(lightbox, closeIcon);
var leftIcon = '';
if (next) {
leftIcon = JX.$N('a',
{
className : 'lightbox-right',
href : '#'
}
);
JX.DOM.listen(leftIcon,
'click',
null,
JX.bind(null, loadAnotherLightBox, next)
);
}
JX.DOM.appendContent(lightbox, leftIcon);
var rightIcon = '';
if (prev) {
rightIcon = JX.$N('a',
{
className : 'lightbox-left',
href : '#'
}
);
JX.DOM.listen(rightIcon,
'click',
null,
JX.bind(null, loadAnotherLightBox, prev)
);
}
JX.DOM.appendContent(lightbox, rightIcon);
var statusSpan = JX.$N('span',
{
className: 'lightbox-status-txt'
},
'Image '+current+' of '+total+'.'+extra_status
);
var downloadSpan = JX.$N('span',
{
className : 'lightbox-download'
});
var statusHTML = JX.$N('div',
{
className : 'lightbox-status'
},
[statusSpan, downloadSpan]
);
JX.DOM.appendContent(lightbox, statusHTML);
JX.DOM.alterClass(document.body, 'lightbox-attached', true);
JX.Mask.show('jx-dark-mask');
downloadForm.action = target_data.dUri;
downloadSpan.appendChild(downloadForm);
document.body.appendChild(lightbox);
JX.Busy.start();
img.onload = function() {
JX.DOM.alterClass(img, 'loading', false);
JX.Busy.done();
- }
+ };
img.src = img_uri;
}
// TODO - make this work with KeyboardShortcut, which means
// making an uninstall / de-register for KeyboardShortcut
function lightBoxHandleKeyDown(e) {
if (!lightbox) {
return;
}
var raw = e.getRawEvent();
if (raw.altKey || raw.ctrlKey || raw.metaKey) {
return;
}
if (JX.Stratcom.pass()) {
return;
}
var handler = JX.bag;
switch (e.getSpecialKey()) {
case 'esc':
handler = closeLightBox;
break;
case 'right':
if (next) {
handler = JX.bind(null, loadAnotherLightBox, next);
}
break;
case 'left':
if (prev) {
handler = JX.bind(null, loadAnotherLightBox, prev);
}
break;
}
return handler(e);
}
function closeLightBox(e) {
if (!lightbox) {
return;
}
e.prevent();
JX.DOM.remove(lightbox);
JX.Mask.hide();
JX.DOM.alterClass(document.body, 'lightbox-attached', false);
lightbox = null;
prev = null;
next = null;
}
function loadAnotherLightBox(el, e) {
if (!el) {
return;
}
e.prevent();
closeLightBox(e);
el.click();
}
JX.Stratcom.listen(
'click',
['lightboxable', 'tag:a'],
loadLightBox);
JX.Stratcom.listen(
'keydown',
null,
lightBoxHandleKeyDown);
// When the user clicks the background, close the lightbox.
JX.Stratcom.listen(
'click',
'lightbox-attachment',
function (e) {
if (!lightbox) {
return;
}
if (e.getTarget() != e.getNode('lightbox-attachment')) {
// Don't close if they clicked some other element, like the image
// itself or the next/previous arrows.
return;
}
closeLightBox(e);
e.kill();
});
});
diff --git a/webroot/rsrc/js/core/behavior-object-selector.js b/webroot/rsrc/js/core/behavior-object-selector.js
index e897df857e..8affe37c43 100644
--- a/webroot/rsrc/js/core/behavior-object-selector.js
+++ b/webroot/rsrc/js/core/behavior-object-selector.js
@@ -1,191 +1,191 @@
/**
* @provides javelin-behavior-phabricator-object-selector
* @requires javelin-behavior
* javelin-dom
* javelin-request
* javelin-util
*/
JX.behavior('phabricator-object-selector', function(config) {
var n = 0;
var phids = {};
var handles = config.handles;
for (var k in handles) {
phids[k] = true;
}
var button_list = {};
var query_timer = null;
var query_delay = 50;
var phid_input = JX.DOM.find(
JX.$(config.form),
'input',
'aphront-dialog-application-input');
var last_value = JX.$(config.query).value;
function onreceive(seq, r) {
if (seq != n) {
return;
}
var display = [];
button_list = {};
for (var k in r) {
handles[r[k].phid] = r[k];
display.push(renderHandle(r[k], true));
}
if (!display.length) {
display = renderNote('No results.');
}
JX.DOM.setContent(JX.$(config.results), display);
}
function redrawAttached() {
var display = [];
for (var k in phids) {
display.push(renderHandle(handles[k], false));
}
if (!display.length) {
display = renderNote('Nothing attached.');
}
JX.DOM.setContent(JX.$(config.current), display);
phid_input.value = JX.keys(phids).join(';');
}
function renderHandle(h, attach) {
var view_object_link = JX.$N(
'a',
{href: h.uri, target: '_blank'},
"\u2197");
var select_object_link = JX.$N(
'a',
{href: '#', sigil: 'object-attacher'},
h.name);
var select_object_button = JX.$N(
'a',
{href: '#', sigil: 'object-attacher', className: 'button small grey'},
attach ? 'Select' : 'Remove');
var cells = [
JX.$N('td', {}, view_object_link),
JX.$N('th', {}, select_object_link),
- JX.$N('td', {}, select_object_button),
+ JX.$N('td', {}, select_object_button)
];
var table = JX.$N(
'table',
{className: 'phabricator-object-selector-handle'});
table.appendChild(
JX.$N(
'tr',
{sigil: 'object-attach-row', meta: {handle: h, table:table}},
cells));
if (attach) {
button_list[h.phid] = select_object_button;
if (h.phid in phids) {
JX.DOM.alterClass(select_object_button, 'disabled', true);
select_object_button.disabled = true;
}
}
return table;
}
function renderNote(note) {
return JX.$N('div', {className : 'object-selector-nothing'}, note);
}
function sendQuery() {
query_timer = null;
- JX.DOM.setContent(JX.$(config.results), renderNote('Loading...'))
+ JX.DOM.setContent(JX.$(config.results), renderNote('Loading...'));
new JX.Request(config.uri, JX.bind(null, onreceive, ++n))
.setData({
filter: JX.$(config.filter).value,
exclude: config.exclude,
query: JX.$(config.query).value
})
.send();
}
JX.DOM.listen(
JX.$(config.results),
'click',
'object-attacher',
function(e) {
e.kill();
var data = e.getNodeData('object-attach-row');
var phid = data.handle.phid;
if (phids[phid]) {
return;
}
phids[phid] = true;
JX.DOM.alterClass(button_list[phid], 'disabled', true);
button_list[phid].disabled = true;
redrawAttached();
});
JX.DOM.listen(
JX.$(config.current),
'click',
'object-attacher',
function(e) {
e.kill();
var data = e.getNodeData('object-attach-row');
var phid = data.handle.phid;
delete phids[phid];
// NOTE: We may not have a button in the button list, if this result is
// not visible in the current search results.
if (button_list[phid]) {
JX.DOM.alterClass(button_list[phid], 'disabled', false);
button_list[phid].disabled = false;
}
redrawAttached();
});
JX.DOM.listen(
JX.$(config.filter),
'change',
null,
function(e) {
e.kill();
sendQuery();
});
JX.DOM.listen(
JX.$(config.query),
['change', 'keydown', 'keyup', 'keypress'],
null,
function(e) {
var cur_value = JX.$(config.query).value;
if (last_value == cur_value) {
return;
}
last_value = cur_value;
clearTimeout(query_timer);
query_timer = setTimeout(sendQuery, query_delay);
});
sendQuery();
redrawAttached();
});
diff --git a/webroot/rsrc/js/core/behavior-oncopy.js b/webroot/rsrc/js/core/behavior-oncopy.js
index 7580a914b7..e048c442b5 100644
--- a/webroot/rsrc/js/core/behavior-oncopy.js
+++ b/webroot/rsrc/js/core/behavior-oncopy.js
@@ -1,80 +1,80 @@
/**
* @provides javelin-behavior-phabricator-oncopy
* @requires javelin-behavior
* javelin-dom
*/
/**
* Tools like Paste and Differential don't normally respond to the clipboard
* 'copy' operation well, because when a user copies text they'll get line
* numbers and other metadata.
*
* To improve this behavior, applications can embed markers that delimit
* metadata (left of the marker) from content (right of the marker). When
* we get a copy event, we strip out all the metadata and just copy the
* actual text.
*/
JX.behavior('phabricator-oncopy', function() {
var zws = "\u200B"; // Unicode Zero-Width Space
document.body.oncopy = function(e) {
var selection = window.getSelection();
var text = selection.toString();
if (text.indexOf(zws) == -1) {
// If there's no marker in the text, just let it copy normally.
return;
}
var result = [];
// Strip everything before the marker (and the marker itself) out of the
// text. If a line doesn't have the marker, throw it away (the assumption
// is that it's a line number or part of some other meta-text).
var lines = text.split("\n");
var pos;
for (var ii = 0; ii < lines.length; ii++) {
pos = lines[ii].indexOf(zws);
- if (pos == -1 && ii != 0) {
+ if (pos == -1 && ii !== 0) {
continue;
}
result.push(lines[ii].substring(pos + 1));
}
result = result.join("\n");
if (e.clipboardData) {
// Safari and Chrome support this easy, straightforward mechanism.
e.clipboardData.setData('Text', result);
e.preventDefault();
} else {
// In Firefox, we have to create a <pre> and select the text in it, then
// let the copy event fire. It has to be a <pre> because Firefox won't
// copy returns properly out of a div, even if it has 'whitespace: pre'.
// There's been a bug open for 10 (!) years:
//
// https://bugzilla.mozilla.org/show_bug.cgi?id=116083
var style = {
position: 'absolute',
left: '-10000px'
};
var pre = JX.$N('pre', {style: style}, result);
document.body.appendChild(pre);
// Select the text in the <pre>.
var range = document.createRange();
range.selectNodeContents(pre);
selection.removeAllRanges();
selection.addRange(range);
setTimeout(function() { JX.DOM.remove(pre); }, 0);
// TODO: I tried to restore the old selection range but it doesn't seem
// to work or give me any errors. So you lose your selection when you
// copy. Oh well?
}
- }
+ };
});
diff --git a/webroot/rsrc/js/core/behavior-phabricator-nav.js b/webroot/rsrc/js/core/behavior-phabricator-nav.js
index 0df0967279..99cbe127c2 100644
--- a/webroot/rsrc/js/core/behavior-phabricator-nav.js
+++ b/webroot/rsrc/js/core/behavior-phabricator-nav.js
@@ -1,154 +1,156 @@
/**
* @provides javelin-behavior-phabricator-nav
* @requires javelin-behavior
* javelin-behavior-device
* javelin-stratcom
* javelin-dom
* javelin-magical-init
* javelin-vector
+ * javelin-request
+ * javelin-util
* @javelin
*/
JX.behavior('phabricator-nav', function(config) {
var content = JX.$(config.contentID);
var local = JX.$(config.localID);
var main = JX.$(config.mainID);
var drag = JX.$(config.dragID);
var background = JX.$(config.backgroundID);
// - Flexible Navigation Column ------------------------------------------------
var dragging;
var track;
JX.enableDispatch(document.body, 'mousemove');
JX.DOM.listen(drag, 'mousedown', null, function(e) {
dragging = JX.$V(e);
// Show the "col-resize" cursor on the whole document while we're
// dragging, since the mouse will slip off the actual bar fairly often and
// we don't want it to flicker.
JX.DOM.alterClass(document.body, 'jx-drag-col', true);
track = [
{
element: local,
parameter: 'width',
start: JX.Vector.getDim(local).x,
width: JX.Vector.getDim(local).x,
minWidth: 1
},
{
element: background,
parameter: 'width',
start: JX.Vector.getDim(background).x,
- start: JX.Vector.getDim(background).x,
minWidth: 1
},
{
element: drag,
parameter: 'left',
start: JX.$V(drag).x
},
{
element: content,
parameter: 'marginLeft',
start: parseInt(getComputedStyle(content).marginLeft, 10),
width: JX.Vector.getDim(content).x,
minWidth: 300,
minScale: -1
}
];
e.kill();
});
JX.Stratcom.listen('mousemove', null, function(e) {
if (!dragging) {
return;
}
var dx = JX.$V(e).x - dragging.x;
var panel;
+ var k;
- for (var k = 0; k < track.length; k++) {
+ for (k = 0; k < track.length; k++) {
panel = track[k];
if (!panel.minWidth) {
continue;
}
var new_width = panel.width + (dx * (panel.minScale || 1));
if (new_width < panel.minWidth) {
dx = (panel.minWidth - panel.width) * panel.minScale;
}
}
- for (var k = 0; k < track.length; k++) {
+ for (k = 0; k < track.length; k++) {
panel = track[k];
var v = (panel.start + (dx * (panel.scale || 1)));
panel.element.style[panel.parameter] = v + 'px';
}
});
JX.Stratcom.listen('mouseup', null, function(e) {
if (!dragging) {
return;
}
JX.DOM.alterClass(document.body, 'jx-drag-col', false);
dragging = false;
});
function resetdrag() {
local.style.width = '';
background.style.width = '';
drag.style.left = '';
content.style.marginLeft = '';
}
var collapsed = config.collapsed;
JX.Stratcom.listen('differential-filetree-toggle', null, function(e) {
collapsed = !collapsed;
JX.DOM.alterClass(main, 'has-local-nav', !collapsed);
JX.DOM.alterClass(main, 'has-drag-nav', !collapsed);
resetdrag();
- new JX.Request('/settings/adjust/', JX.Bag)
+ new JX.Request('/settings/adjust/', JX.bag)
.setData({ key : 'nav-collapsed', value : (collapsed ? 1 : 0) })
.send();
});
// - Scroll --------------------------------------------------------------------
// When the user scrolls or resizes the window, anchor the menu to to the top
// of the navigation bar.
function onresize(e) {
if (JX.Device.getDevice() != 'desktop') {
return;
}
local.style.top = Math.max(
0,
JX.$V(content).y - Math.max(0, JX.Vector.getScroll().y)) + 'px';
}
local.style.position = 'fixed';
local.style.bottom = 0;
local.style.left = 0;
JX.Stratcom.listen(['scroll', 'resize'], null, onresize);
onresize();
// - Navigation Reset ----------------------------------------------------------
JX.Stratcom.listen('phabricator-device-change', null, function(event) {
resetdrag();
onresize();
});
});
diff --git a/webroot/rsrc/js/core/behavior-phabricator-remarkup-assist.js b/webroot/rsrc/js/core/behavior-phabricator-remarkup-assist.js
index 1eeb507530..1152bedd6a 100644
--- a/webroot/rsrc/js/core/behavior-phabricator-remarkup-assist.js
+++ b/webroot/rsrc/js/core/behavior-phabricator-remarkup-assist.js
@@ -1,211 +1,211 @@
/**
* @provides javelin-behavior-phabricator-remarkup-assist
* @requires javelin-behavior
* javelin-stratcom
* javelin-dom
* phabricator-textareautils
* javelin-workflow
* phabricator-notification
* javelin-vector
*/
JX.behavior('phabricator-remarkup-assist', function(config) {
var edit_mode = 'normal';
var edit_root = null;
function set_edit_mode(root, mode) {
if (mode == edit_mode) {
return;
}
// First, disable any active mode.
if (edit_root) {
if (edit_mode == 'order') {
JX.DOM.alterClass(edit_root, 'remarkup-control-order-mode', false);
}
if (edit_mode == 'chaos') {
JX.DOM.alterClass(edit_root, 'remarkup-control-chaos-mode', false);
}
JX.DOM.find(edit_root, 'textarea').style.height = '';
}
edit_root = root;
edit_mode = mode;
// Now, apply the new mode.
if (mode == 'order') {
JX.DOM.alterClass(edit_root, 'remarkup-control-order-mode', true);
resizearea();
}
if (mode == 'chaos') {
JX.DOM.alterClass(edit_root, 'remarkup-control-chaos-mode', true);
}
JX.DOM.focus(JX.DOM.find(edit_root, 'textarea'));
}
function resizearea() {
if (!edit_root) {
return;
}
if (edit_mode != 'order') {
return;
}
// In Firefox, a textarea with position "absolute" or "fixed", anchored
// "top" and "bottom", and height "auto" renders as two lines high. Force
// it to the correct height with Javascript.
var area = JX.DOM.find(edit_root, 'textarea');
var v = JX.Vector.getViewport();
v.x = null;
v.y -= 26;
v.setDim(area);
}
JX.Stratcom.listen('resize', null, resizearea);
JX.Stratcom.listen('keydown', null, function(e) {
if (edit_mode == 'chaos') {
cause_chaos();
}
if (e.getSpecialKey() != 'esc') {
return;
}
if (edit_mode != 'order') {
return;
}
e.kill();
set_edit_mode(edit_root, 'normal');
});
var chaos_states = [];
function cause_chaos() {
for (var ii = 0; ii <= 13; ii++) {
if (Math.random() > 0.98) {
chaos_states[ii] = !chaos_states[ii];
}
JX.DOM.alterClass(
edit_root,
'remarkup-control-chaos-mode-' + ii,
!!chaos_states[ii]);
}
if (Math.random() > 0.98) {
var n = new JX.Notification()
.setContent("Hey, listen!")
.setDuration(1000 + Math.random() * 6000);
if (Math.random() > 0.75) {
n.alterClassName('jx-notification-alert', true);
}
n.show();
}
}
function update(area, l, m, r) {
// Replace the selection with the entire assisted text.
JX.TextAreaUtils.setSelectionText(area, l + m + r);
// Now, select just the middle part. For instance, if the user clicked
// "B" to create bold text, we insert '**bold**' but just select the word
// "bold" so if they type stuff they'll be editing the bold text.
- var r = JX.TextAreaUtils.getSelectionRange(area);
+ var range = JX.TextAreaUtils.getSelectionRange(area);
JX.TextAreaUtils.setSelectionRange(
area,
- r.start + l.length,
- r.start + l.length + m.length);
+ range.start + l.length,
+ range.start + l.length + m.length);
}
function assist(area, action, root) {
// If the user has some text selected, we'll try to use that (for example,
// if they have a word selected and want to bold it). Otherwise we'll insert
// generic text.
var sel = JX.TextAreaUtils.getSelectionText(area);
var r = JX.TextAreaUtils.getSelectionRange(area);
switch (action) {
case 'b':
update(area, '**', sel || 'bold text', '**');
break;
case 'i':
update(area, '//', sel || 'italic text', '//');
break;
case 'tt':
update(area, '`', sel || 'monospaced text', '`');
break;
case 'ul':
case 'ol':
var ch = (action == 'ol') ? ' # ' : ' - ';
if (sel) {
sel = sel.split("\n");
} else {
sel = ["List Item"];
}
sel = sel.join("\n" + ch);
- update(area, ((r.start == 0) ? "" : "\n\n") + ch, sel, "\n\n");
+ update(area, ((r.start === 0) ? "" : "\n\n") + ch, sel, "\n\n");
break;
case 'code':
sel = sel || "foreach ($list as $item) {\n work_miracles($item);\n}";
sel = sel.split("\n");
sel = " " + sel.join("\n ");
- update(area, ((r.start == 0) ? "" : "\n\n"), sel, "\n\n");
+ update(area, ((r.start === 0) ? "" : "\n\n"), sel, "\n\n");
break;
case 'table':
- update(area, (r.start == 0 ? '' : '\n\n') + '| ', sel || 'data', ' |');
+ update(area, (r.start === 0 ? '' : '\n\n') + '| ', sel || 'data', ' |');
break;
case 'meme':
new JX.Workflow('/macro/meme/create/')
.setHandler(function(response) {
update(
area,
'',
sel,
- (r.start == 0 ? '' : '\n\n') + response.text + '\n\n');
+ (r.start === 0 ? '' : '\n\n') + response.text + '\n\n');
})
.start();
break;
case 'chaos':
if (edit_mode == 'chaos') {
set_edit_mode(root, 'normal');
} else {
set_edit_mode(root, 'chaos');
}
break;
case 'order':
if (edit_mode == 'order') {
set_edit_mode(root, 'normal');
} else {
set_edit_mode(root, 'order');
}
break;
}
}
JX.Stratcom.listen(
['click'],
'remarkup-assist',
function(e) {
var data = e.getNodeData('remarkup-assist');
if (!data.action) {
return;
}
e.kill();
var root = e.getNode('remarkup-assist-control');
var area = JX.DOM.find(root, 'textarea');
assist(area, data.action, root);
});
});
diff --git a/webroot/rsrc/js/core/behavior-refresh-csrf.js b/webroot/rsrc/js/core/behavior-refresh-csrf.js
index 8e3d18953f..bd236838ab 100644
--- a/webroot/rsrc/js/core/behavior-refresh-csrf.js
+++ b/webroot/rsrc/js/core/behavior-refresh-csrf.js
@@ -1,58 +1,59 @@
/**
* @provides javelin-behavior-refresh-csrf
* @requires javelin-request
* javelin-behavior
* javelin-dom
* phabricator-busy
*/
/**
* We cycle CSRF tokens every hour but accept the last 6, which means that if
* you leave a page open for more than 6 hours before submitting it you may hit
* CSRF protection. This is a super confusing workflow which potentially
* discards data, and we can't recover from it by re-issuing a CSRF token
* since that would leave us vulnerable to CSRF attacks.
*
* Our options basically boil down to:
*
* - Increase the CSRF window to something like 24 hours. This makes the CSRF
* implementation vaguely less secure and only mitigates the problem.
* - Code all forms to understand GET, POST and POST-with-invalid-CSRF. This
* is a huge undertaking and difficult to test properly since it is hard
* to remember to test the third phantom state.
* - Use JS to refresh the CSRF token.
*
* Since (1) mitigates rather than solving and (2) is a huge mess, this
* behavior implements (3) and refreshes all the CSRF tokens on the page every
* 55 minutes. This allows forms to remain valid indefinitely.
*/
JX.behavior('refresh-csrf', function(config) {
var current_token = config.current;
function refresh_csrf() {
new JX.Request('/login/refresh/', function(r) {
current_token = r.token;
var inputs = JX.DOM.scry(document.body, 'input');
for (var ii = 0; ii < inputs.length; ii++) {
if (inputs[ii].name == config.tokenName) {
inputs[ii].value = r.token;
}
}
})
.send();
}
// Refresh the CSRF tokens every 55 minutes.
setInterval(refresh_csrf, 1000 * 60 * 55);
// Additionally, add the CSRF token as an HTTP header to every AJAX request.
JX.Request.listen('open', function(r) {
r.getTransport().setRequestHeader(config.header, current_token);
JX.Busy.start();
});
JX.Request.listen('finally', function(r) {
JX.Busy.done();
- })
+ });
+
});
diff --git a/webroot/rsrc/js/core/behavior-reveal-content.js b/webroot/rsrc/js/core/behavior-reveal-content.js
index 58ab087970..06ae482efa 100644
--- a/webroot/rsrc/js/core/behavior-reveal-content.js
+++ b/webroot/rsrc/js/core/behavior-reveal-content.js
@@ -1,23 +1,24 @@
/**
* @provides javelin-behavior-phabricator-reveal-content
* @requires javelin-behavior
* javelin-stratcom
* javelin-dom
* @javelin
*/
JX.behavior('phabricator-reveal-content', function(config) {
JX.Stratcom.listen(
'click',
'reveal-content',
function(e) {
e.kill();
var nodes = e.getNodeData('reveal-content');
- for (var ii = 0; ii < nodes.showIDs.length; ii++) {
+ var ii;
+ for (ii = 0; ii < nodes.showIDs.length; ii++) {
JX.DOM.show(JX.$(nodes.showIDs[ii]));
}
- for (var ii = 0; ii < nodes.hideIDs.length; ii++) {
+ for (ii = 0; ii < nodes.hideIDs.length; ii++) {
JX.DOM.hide(JX.$(nodes.hideIDs[ii]));
}
});
});
diff --git a/webroot/rsrc/js/core/behavior-search-typeahead.js b/webroot/rsrc/js/core/behavior-search-typeahead.js
index 3b28807496..e6decc47b1 100644
--- a/webroot/rsrc/js/core/behavior-search-typeahead.js
+++ b/webroot/rsrc/js/core/behavior-search-typeahead.js
@@ -1,125 +1,126 @@
/**
* @provides javelin-behavior-phabricator-search-typeahead
* @requires javelin-behavior
* javelin-typeahead-ondemand-source
* javelin-typeahead
* javelin-dom
* javelin-uri
* javelin-util
* javelin-stratcom
*/
JX.behavior('phabricator-search-typeahead', function(config) {
var datasource = new JX.TypeaheadOnDemandSource(config.src);
function transform(object) {
var attr = {
className: 'phabricator-main-search-typeahead-result'
- }
+ };
if (object[6]) {
attr.style = {backgroundImage: 'url('+object[6]+')'};
}
var render = JX.$N(
'span',
attr,
[
JX.$N('span', {className: 'result-name'}, object[4] || object[0]),
JX.$N('span', {className: 'result-type'}, object[5])
]);
return {
name: object[0],
display: render,
uri: object[1],
id: object[2],
priority: object[3],
type: object[7]
};
}
datasource.setTransformer(transform);
// Sort handler that orders results by type (e.g., applications, users)
// and then selects for good matches on the "priority" substrings if they
// exist (for instance, username matches are preferred over real name
// matches, and application name matches are preferred over application
// flavor text matches).
var sort_handler = function(value, list, cmp) {
var priority_hits = {};
var type_priority = {
// TODO: Put jump nav hits like "D123" first.
'apps' : 2,
'user' : 3,
'symb' : 4
};
var tokens = this.tokenize(value);
- for (var ii = 0; ii < list.length; ii++) {
+ var ii;
+ for (ii = 0; ii < list.length; ii++) {
var item = list[ii];
if (!item.priority) {
continue;
}
for (var jj = 0; jj < tokens.length; jj++) {
if (item.priority.substr(0, tokens[jj].length) == tokens[jj]) {
priority_hits[item.id] = true;
}
}
}
list.sort(function(u, v) {
var u_type = type_priority[u.type] || 999;
var v_type = type_priority[v.type] || 999;
if (u_type != v_type) {
return u_type - v_type;
}
if (priority_hits[u.id] != priority_hits[v.id]) {
return priority_hits[v.id] ? 1 : -1;
}
return cmp(u, v);
});
// If we have more results than fit, limit each type of result to 3, so
// we show 3 applications, then 3 users, etc.
var type_count = 0;
var current_type = null;
- for (var ii = 0; ii < list.length; ii++) {
+ for (ii = 0; ii < list.length; ii++) {
if (list.length <= config.limit) {
break;
}
if (list[ii].type != current_type) {
current_type = list[ii].type;
type_count = 1;
} else {
type_count++;
if (type_count > 3) {
list.splice(ii, 1);
ii--;
}
}
}
};
datasource.setSortHandler(JX.bind(datasource, sort_handler));
datasource.setMaximumResultCount(config.limit);
var typeahead = new JX.Typeahead(JX.$(config.id), JX.$(config.input));
typeahead.setDatasource(datasource);
typeahead.setPlaceholder(config.placeholder);
typeahead.listen('choose', function(r) {
JX.$U(r.href).go();
JX.Stratcom.context().kill();
});
typeahead.start();
});
diff --git a/webroot/rsrc/js/core/phtize.js b/webroot/rsrc/js/core/phtize.js
index a48970c411..f97cf6ccaf 100644
--- a/webroot/rsrc/js/core/phtize.js
+++ b/webroot/rsrc/js/core/phtize.js
@@ -1,21 +1,22 @@
/**
* @provides phabricator-phtize
* @requires javelin-util
+ * @javelin-installs JX.phtize
* @javelin
*/
JX.phtize = function(config) {
return function(text) {
if (!(text in config)) {
if (__DEV__) {
JX.$E('pht("' + text + '"): translation was not configured.');
}
return text;
}
return config[text];
};
};

File Metadata

Mime Type
text/x-diff
Expires
Thu, Nov 6, 12:06 PM (4 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
322009
Default Alt Text
(635 KB)

Event Timeline