Compare commits
37 commits
alternate_
...
master
Author | SHA1 | Date | |
---|---|---|---|
7326c98996 | |||
f7b0cf4739 | |||
5037361052 | |||
b5bfa2dc5a | |||
53137ab8a2 | |||
7827439085 | |||
b95ead015c | |||
a92b72f485 | |||
bc53505c16 | |||
90a77b20e8 | |||
21d184d671 | |||
31b0d36abc | |||
5a4ad87273 | |||
0f07e6e475 | |||
3ab33e8624 | |||
654fa9ffce | |||
5e59f3dea8 | |||
eecbc71b53 | |||
fa43efa937 | |||
0c400e05fb | |||
9ab51a3599 | |||
80624a9cca | |||
0eb8c0956c | |||
2f0068b047 | |||
b94b99c7f7 | |||
e330b429da | |||
86a051b290 | |||
9575411593 | |||
46e474d383 | |||
29a6eed349 | |||
f9b3b05854 | |||
c1001ba0fe | |||
e9ad69cb79 | |||
dfc2605895 | |||
3b9f80f6cf | |||
324533a8a5 | |||
fbc0f89c91 |
32 changed files with 2423 additions and 7384 deletions
14
README.md
14
README.md
|
@ -183,7 +183,19 @@ You will have 50 love gems on 01/16/2016. Good things come to those who wait!
|
|||
|
||||
## The Web App
|
||||
|
||||
You asked for a web app, and here it is! The [web_app](web_app) directory contains a (mostly) fully featured web app version of SIF Tools. The best part is, you don't need a web server to run it. You should just be able to open the [sif_tools.html](web_app/sif_tools.html) file in your local web browser and run it right on your own computer. You will need to have JavaScript enabled in your browser however. (Of course you can host these files on a web server just like any other website, if you happen to have access to a web server.)
|
||||
You asked for a web app, and here it is! The [web_app](web_app) directory contains a fully featured web app version of SIF Tools. In fact, the web app actually does some things that the original Python scripts don't! (yet.) The best part is, you don't need a web server to run it. You should just be able to open the [sif_tools.html](web_app/sif_tools.html) file in your local web browser and run it right on your own computer. You will need to have JavaScript enabled in your browser however. (Of course you can host these files on a web server just like any other website, if you happen to have access to a web server.) Or you can run the copy hosted on my own web server [here](https://beta.DonaldBurr.com/sif_tools/sif_tools.html).
|
||||
|
||||
## Credits
|
||||
|
||||
The web app uses the following third-party Javascript libraries:
|
||||
|
||||
* [jQuery](https://jquery.com) ([License](https://jquery.org/license/))
|
||||
* [jQuery UI](https://jqueryui.com) ([License](https://github.com/jquery/jquery-ui/blob/master/LICENSE.txt))
|
||||
* [jQuery Keypad](http://keith-wood.name/keypad.html) ([License](http://keith-wood.name/licence.html))
|
||||
* [Moment.js](http://momentjs.com) ([License](https://github.com/moment/moment/blob/develop/LICENSE))
|
||||
* [jquery.timepicker](http://jonthornton.github.io/jquery-timepicker/) ([License](https://opensource.org/licenses/MIT))
|
||||
* [node-sprintf](https://github.com/maritz/node-sprintf) ([License](https://github.com/maritz/node-sprintf#copyrightlicense))
|
||||
* [twitterFetcher](https://github.com/jasonmayes/Twitter-Post-Fetcher) ([License](https://github.com/jasonmayes/Twitter-Post-Fetcher/blob/master/License.txt))
|
||||
|
||||
## Bugs? Need help? Got any suggestions/ideas for new features? Or want to chat?
|
||||
|
||||
|
|
3
web_app/css/external/images/disabled.svg
vendored
3
web_app/css/external/images/disabled.svg
vendored
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="#111">
|
||||
<path d="M7.4 4.4V2.5c0-1.4-1.1-2.5-2.5-2.5c-1.4 0-2.5 1.1-2.5 2.5v1.9 c-0.7 0-1.2 0.5-1.2 1.2v3.1C1.3 9.4 1.8 10 2.5 10h4.9c0.7 0 1.2-0.6 1.2-1.2V5.6 C8.7 4.9 8.1 4.4 7.4 4.4z M5.3 7.4v1.0c0 0.2-0.1 0.3-0.3 0.3c-0.2 0-0.3-0.1-0.3-0.3V7.4 c-0.2-0.1-0.3-0.3-0.3-0.5c0-0.3 0.3-0.6 0.6-0.6c0.3 0 0.6 0.3 0.6 0.6 C5.6 7.1 5.5 7.3 5.3 7.4z M6.2 4.4H3.7V2.5c0-0.7 0.5-1.2 1.2-1.2c0.7 0 1.2 0.6 1.2 1.2 V4.4z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 489 B |
3
web_app/css/external/images/enabled.svg
vendored
3
web_app/css/external/images/enabled.svg
vendored
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="#111">
|
||||
<path d="M8.7,4.4H7.5H5.0v-1.9c0-1.4-1.1-2.5-2.5-2.5c-1.4,0-2.5,1.1-2.5,2.5v1.9h1.2 v-1.9c0-0.7,0.6-1.2,1.2-1.2s1.2,0.6,1.2,1.2v1.9c-0.7,0-1.2,0.6-1.2,1.2V8.8 c0,0.7,0.6,1.2,1.2,1.2h5.0C9.4,10,10,9.4,10,8.8V5.6C10,5.0,9.4,4.4,8.8,4.4z M6.6,7.4v1.0 c0,0.2-0.1,0.3-0.3,0.3S6.0,8.6,6.0,8.4V7.4c-0.2-0.1-0.3-0.3-0.3-0.5c0-0.3,0.3-0.6,0.6-0.6 S6.9,6.6,6.9,6.9C6.9,7.1,6.8,7.3,6.6,7.4z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 468 B |
15
web_app/css/external/images/keyboard.svg
vendored
15
web_app/css/external/images/keyboard.svg
vendored
|
@ -1,15 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" style="fill:#888">
|
||||
<g>
|
||||
<path style="fill:none;stroke:#888" d="M 0.5,4.5 15.5,4.5 15.5,15.5 0.5,15.5 Z"></path>
|
||||
<rect width="2" height="2" x="2" y="6"></rect>
|
||||
<rect width="2" height="2" x="5" y="6"></rect>
|
||||
<rect width="2" height="2" x="8" y="6"></rect>
|
||||
<path d="m 11,6 3,0 0,5 -2,0 0,-3 -1,0 z"></path>
|
||||
<rect width="2" height="2" x="12" y="12"></rect>
|
||||
<rect width="6" height="2" x="5" y="12"></rect>
|
||||
<rect width="2" height="2" x="9" y="9"></rect>
|
||||
<rect width="2" height="2" x="6" y="9"></rect>
|
||||
<rect width="2" height="2" x="2" y="12"></rect>
|
||||
<rect width="3" height="2" x="2" y="9"></rect>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 686 B |
|
@ -1,27 +0,0 @@
|
|||
.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
|
||||
.ui-timepicker-div dl { text-align: left; }
|
||||
.ui-timepicker-div dl dt { float: left; clear:left; padding: 0 0 0 5px; }
|
||||
.ui-timepicker-div dl dd { margin: 0 10px 10px 40%; }
|
||||
.ui-timepicker-div td { font-size: 90%; }
|
||||
.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
|
||||
.ui-timepicker-div .ui_tpicker_unit_hide{ display: none; }
|
||||
|
||||
.ui-timepicker-rtl{ direction: rtl; }
|
||||
.ui-timepicker-rtl dl { text-align: right; padding: 0 5px 0 0; }
|
||||
.ui-timepicker-rtl dl dt{ float: right; clear: right; }
|
||||
.ui-timepicker-rtl dl dd { margin: 0 40% 10px 10px; }
|
||||
|
||||
/* Shortened version style */
|
||||
.ui-timepicker-div.ui-timepicker-oneLine { padding-right: 2px; }
|
||||
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,
|
||||
.ui-timepicker-div.ui-timepicker-oneLine dt { display: none; }
|
||||
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label { display: block; padding-top: 2px; }
|
||||
.ui-timepicker-div.ui-timepicker-oneLine dl { text-align: right; }
|
||||
.ui-timepicker-div.ui-timepicker-oneLine dl dd,
|
||||
.ui-timepicker-div.ui-timepicker-oneLine dl dd > div { display:inline-block; margin:0; }
|
||||
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,
|
||||
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before { content:':'; display:inline-block; }
|
||||
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,
|
||||
.ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before { content:'.'; display:inline-block; }
|
||||
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,
|
||||
.ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{ display: none; }
|
106
web_app/css/external/jquery.keypad.css
vendored
Normal file
106
web_app/css/external/jquery.keypad.css
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* Main style sheet for jQuery Keypad v2.0.0 */
|
||||
button.keypad-trigger {
|
||||
width: 25px;
|
||||
padding: 0px;
|
||||
}
|
||||
img.keypad-trigger {
|
||||
margin: 2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.keypad-popup, .keypad-inline, .keypad-key, .keypad-special {
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
font-size: 24px;
|
||||
}
|
||||
.keypad-popup {
|
||||
display: none;
|
||||
z-index: 10;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
border: 1px solid #888;
|
||||
-moz-border-radius: 0.25em;
|
||||
-webkit-border-radius: 0.25em;
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
.keypad-keyentry {
|
||||
display: none;
|
||||
}
|
||||
.keypad-inline {
|
||||
background-color: #fff;
|
||||
border: 1px solid #888;
|
||||
-moz-border-radius: 0.25em;
|
||||
-webkit-border-radius: 0.25em;
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
.keypad-disabled {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
background-color: white;
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
.keypad-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
.keypad-prompt {
|
||||
clear: both;
|
||||
text-align: center;
|
||||
}
|
||||
.keypad-prompt.ui-widget-header {
|
||||
margin: 0.125em;
|
||||
}
|
||||
.keypad-row {
|
||||
width: 100%;
|
||||
}
|
||||
.keypad-space {
|
||||
display: inline-block;
|
||||
margin: 0.125em;
|
||||
width: 2em;
|
||||
}
|
||||
.keypad-half-space {
|
||||
display: inline-block;
|
||||
margin: 0.125em 0.0625em;
|
||||
width: 1em;
|
||||
}
|
||||
.keypad-key, .keypad-special {
|
||||
margin: 0.125em;
|
||||
padding: 0em;
|
||||
width: 2em;
|
||||
background-color: #f4f4f4;
|
||||
-moz-border-radius: 0.25em;
|
||||
-webkit-border-radius: 0.25em;
|
||||
border-radius: 0.25em;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.keypad-key[disabled] {
|
||||
border: 0.125em outset;
|
||||
}
|
||||
.keypad-key-down {
|
||||
}
|
||||
.keypad-special {
|
||||
width: 4.25em;
|
||||
}
|
||||
.keypad-spacebar {
|
||||
width: 13.25em;
|
||||
}
|
||||
.keypad-tab {
|
||||
width: 2em;
|
||||
}
|
||||
.keypad-clear, .keypad-back, .keypad-close, .keypad-shift {
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
.keypad-clear {
|
||||
background-color: #a00;
|
||||
}
|
||||
.keypad-back {
|
||||
background-color: #00a;
|
||||
}
|
||||
.keypad-close {
|
||||
background-color: #0a0;
|
||||
}
|
||||
.keypad-shift {
|
||||
background-color: #0aa;
|
||||
}
|
0
web_app/css/external/jquery.timepicker.css
vendored
Executable file → Normal file
0
web_app/css/external/jquery.timepicker.css
vendored
Executable file → Normal file
170
web_app/css/external/keyboard-basic.css
vendored
170
web_app/css/external/keyboard-basic.css
vendored
|
@ -1,170 +0,0 @@
|
|||
/* *** keyboard light theme ***
|
||||
for when jQuery UI themes are not being used
|
||||
See http://jsfiddle.net/Mottie/jsh0377k/
|
||||
*/
|
||||
.ui-keyboard {
|
||||
/* adjust overall keyboard size using "font-size" */
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
/* include the following setting to place the
|
||||
keyboard at the bottom of the browser window */
|
||||
width: 100%;
|
||||
height: auto;
|
||||
left: 0px;
|
||||
top: auto;
|
||||
bottom: 0px;
|
||||
position: fixed;
|
||||
}
|
||||
.ui-keyboard {
|
||||
background: #fefefe;
|
||||
border: 1px solid #aaa;
|
||||
padding: 4px;
|
||||
}
|
||||
.ui-keyboard-button {
|
||||
border: 1px solid #aaa;
|
||||
padding: 0 0.5em;
|
||||
margin: 1px;
|
||||
min-width: 3em;
|
||||
height: 3em;
|
||||
line-height: 3em;
|
||||
vertical-align: top;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.5);
|
||||
-moz-box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.5);
|
||||
background: white;
|
||||
background-image: -moz-linear-gradient(-90deg, white 0%, #e3e3e3 100%);
|
||||
background-image: -webkit-linear-gradient(-90deg, white 0%, #e3e3e3 100%);
|
||||
background-image: -o-linear-gradient(-90deg, white 0%, #e3e3e3 100%);
|
||||
background-image: -ms-linear-gradient(-90deg, white 0%, #e3e3e3 100%);
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
-moz-user-focus: ignore;
|
||||
}
|
||||
.ui-keyboard-button span {
|
||||
/* padding: 0; margin: 0; white-space:nowrap; display: inline-block; */
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
/* make action keys extra-wide */
|
||||
.ui-keyboard-actionkey:not(.ui-keyboard-dec) {
|
||||
min-width: 6em;
|
||||
}
|
||||
.ui-keyboard-space {
|
||||
width: 15em;
|
||||
}
|
||||
.ui-keyboard-actionkey:not(.ui-keyboard-dec) span {
|
||||
font-size: 0.8em;
|
||||
position: relative;
|
||||
top: -1em;
|
||||
left: -1.6em;
|
||||
}
|
||||
.ui-keyboard-placeholder {
|
||||
color: #888;
|
||||
}
|
||||
/* disabled or readonly inputs, or use input[disabled='disabled'] { color: #f00; } */
|
||||
.ui-keyboard-nokeyboard {
|
||||
color: #888;
|
||||
border-color: #888;
|
||||
}
|
||||
|
||||
/* combo key styling - toggles diacritics on/off */
|
||||
.ui-keyboard-button.ui-keyboard-combo.ui-state-default {
|
||||
border-color: #375a7f;
|
||||
}
|
||||
/* (in)valid inputs */
|
||||
button.ui-keyboard-accept.ui-keyboard-valid-input {
|
||||
background: #008966;
|
||||
border-color: #007f5e;
|
||||
color: #fff;
|
||||
}
|
||||
button.ui-keyboard-accept.ui-keyboard-valid-input:hover {
|
||||
background: #00bc8c;
|
||||
border-color: #00bc8c;
|
||||
}
|
||||
button.ui-keyboard-accept.ui-keyboard-invalid-input {
|
||||
background: #d62c1a;
|
||||
border-color: #cd2a19;;
|
||||
color: #fff;
|
||||
}
|
||||
button.ui-keyboard-accept.ui-keyboard-invalid-input:hover {
|
||||
background: #e74c3c;
|
||||
border-color: #e74c3c;
|
||||
}
|
||||
/* unlocked icon (keyboard enabled) */
|
||||
button.ui-keyboard-toggle span {
|
||||
width: .9em;
|
||||
height: .9em;
|
||||
display: inline-block;
|
||||
margin-bottom: 3px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: contain;
|
||||
/* light theme unlocked icon - fill: #111 */
|
||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iIzExMSI+PHBhdGggZD0iTTguNyw0LjRINy41SDUuMHYtMS45YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41djEuOWgxLjIgdi0xLjljMC0wLjcsMC42LTEuMiwxLjItMS4yczEuMiwwLjYsMS4yLDEuMnYxLjljLTAuNywwLTEuMiwwLjYtMS4yLDEuMlY4LjggYzAsMC43LDAuNiwxLjIsMS4yLDEuMmg1LjBDOS40LDEwLDEwLDkuNCwxMCw4LjhWNS42QzEwLDUuMCw5LjQsNC40LDguOCw0LjR6IE02LjYsNy40djEuMCBjMCwwLjItMC4xLDAuMy0wLjMsMC4zUzYuMCw4LjYsNi4wLDguNFY3LjRjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zLDAuMy0wLjYsMC42LTAuNiBTNi45LDYuNiw2LjksNi45QzYuOSw3LjEsNi44LDcuMyw2LjYsNy40eiIvPjwvc3ZnPg==');
|
||||
}
|
||||
.ui-keyboard-dark-theme button.ui-keyboard-toggle span {
|
||||
/* dark theme unlocked icon - fill: #eee */
|
||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iI2VlZSI+PHBhdGggZD0iTTguNyw0LjRINy41SDUuMHYtMS45YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41djEuOWgxLjIgdi0xLjljMC0wLjcsMC42LTEuMiwxLjItMS4yczEuMiwwLjYsMS4yLDEuMnYxLjljLTAuNywwLTEuMiwwLjYtMS4yLDEuMlY4LjggYzAsMC43LDAuNiwxLjIsMS4yLDEuMmg1LjBDOS40LDEwLDEwLDkuNCwxMCw4LjhWNS42QzEwLDUuMCw5LjQsNC40LDguOCw0LjR6IE02LjYsNy40djEuMCBjMCwwLjItMC4xLDAuMy0wLjMsMC4zUzYuMCw4LjYsNi4wLDguNFY3LjRjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zLDAuMy0wLjYsMC42LTAuNiBTNi45LDYuNiw2LjksNi45QzYuOSw3LjEsNi44LDcuMyw2LjYsNy40eiIvPjwvc3ZnPg==');
|
||||
}
|
||||
/* locked icon (keyboard disabled) */
|
||||
button.ui-keyboard-toggle.ui-keyboard-disabled span {
|
||||
/* light theme locked icon - fill: #111 */
|
||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iIzExMSI+PHBhdGggZD0iTTcuNCA0LjRWMi41YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40IDAtMi41IDEuMS0yLjUgMi41djEuOSBjLTAuNyAwLTEuMiAwLjUtMS4yIDEuMnYzLjFDMS4zIDkuNCAxLjggMTAgMi41IDEwaDQuOWMwLjcgMCAxLjItMC42IDEuMi0xLjJWNS42IEM4LjcgNC45IDguMSA0LjQgNy40IDQuNHogTTUuMyA3LjR2MS4wYzAgMC4yLTAuMSAwLjMtMC4zIDAuM2MtMC4yIDAtMC4zLTAuMS0wLjMtMC4zVjcuNCBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zIDAuMy0wLjYgMC42LTAuNmMwLjMgMCAwLjYgMC4zIDAuNiAwLjYgQzUuNiA3LjEgNS41IDcuMyA1LjMgNy40eiBNNi4yIDQuNEgzLjdWMi41YzAtMC43IDAuNS0xLjIgMS4yLTEuMmMwLjcgMCAxLjIgMC42IDEuMiAxLjIgVjQuNHoiLz48L3N2Zz4=');
|
||||
}
|
||||
.ui-keyboard-dark-theme button.ui-keyboard-toggle.ui-keyboard-disabled span {
|
||||
/* dark theme locked icon - fill: #eee */
|
||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iI2VlZSI+PHBhdGggZD0iTTcuNCA0LjRWMi41YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40IDAtMi41IDEuMS0yLjUgMi41djEuOSBjLTAuNyAwLTEuMiAwLjUtMS4yIDEuMnYzLjFDMS4zIDkuNCAxLjggMTAgMi41IDEwaDQuOWMwLjcgMCAxLjItMC42IDEuMi0xLjJWNS42IEM4LjcgNC45IDguMSA0LjQgNy40IDQuNHogTTUuMyA3LjR2MS4wYzAgMC4yLTAuMSAwLjMtMC4zIDAuM2MtMC4yIDAtMC4zLTAuMS0wLjMtMC4zVjcuNCBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zIDAuMy0wLjYgMC42LTAuNmMwLjMgMCAwLjYgMC4zIDAuNiAwLjYgQzUuNiA3LjEgNS41IDcuMyA1LjMgNy40eiBNNi4yIDQuNEgzLjdWMi41YzAtMC43IDAuNS0xLjIgMS4yLTEuMmMwLjcgMCAxLjIgMC42IDEuMiAxLjIgVjQuNHoiLz48L3N2Zz4=');
|
||||
}
|
||||
.ui-keyboard.ui-keyboard-disabled button:not(.ui-keyboard-toggle), .ui-keyboard.ui-keyboard-disabled input {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/*** Alt-Keys Popup extension ***/
|
||||
/* clickable overlay on top of keyboard to hide the popup */
|
||||
.ui-keyboard-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
/* the actual popup styling, class names from the css.container option are also added */
|
||||
.ui-keyboard-popup {
|
||||
display: inline-block;
|
||||
/* default buttons are 2em wide + .1em margin on either side (set in .ui-keyboard-button definition);
|
||||
so use multiples of 2.2em for a max-width if you don't want any extra white space on the sides,
|
||||
e.g. 5 buttons * 2.2em = 11em, 6 buttons * 2.2em = 13.2em, etc */
|
||||
max-width: 22em;
|
||||
/* 10 buttons */
|
||||
}
|
||||
|
||||
/*** Extender keyboard extension ***/
|
||||
div.ui-keyboard-extender {
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
button.ui-keyboard-extender span {
|
||||
width: .9em;
|
||||
height: .9em;
|
||||
display: inline-block;
|
||||
margin-bottom: 3px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: contain;
|
||||
/* light theme extender icon - fill: #111 */
|
||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgc3R5bGU9ImZpbGw6IzExMSI+PGc+PHBhdGggc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzExMSIgZD0iTSAwLjUsNC41IDE1LjUsNC41IDE1LjUsMTUuNSAwLjUsMTUuNSBaIj48L3BhdGg+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iMiIgeT0iNiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjYiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSI4IiB5PSI2Ij48L3JlY3Q+PHBhdGggZD0ibSAxMSw2IDMsMCAwLDUgLTIsMCAwLC0zIC0xLDAgeiI+PC9wYXRoPjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjEyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSI2IiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjEyIj48L3JlY3Q+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iOSIgeT0iOSI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjYiIHk9IjkiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSIyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIzIiBoZWlnaHQ9IjIiIHg9IjIiIHk9IjkiPjwvcmVjdD48L2c+PC9zdmc+');
|
||||
}
|
||||
.ui-keyboard-dark-theme button.ui-keyboard-extender span {
|
||||
/* dark theme extender icon - fill: #eee */
|
||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgc3R5bGU9ImZpbGw6I2VlZSI+PGc+PHBhdGggc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2VlZSIgZD0iTSAwLjUsNC41IDE1LjUsNC41IDE1LjUsMTUuNSAwLjUsMTUuNSBaIj48L3BhdGg+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iMiIgeT0iNiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjYiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSI4IiB5PSI2Ij48L3JlY3Q+PHBhdGggZD0ibSAxMSw2IDMsMCAwLDUgLTIsMCAwLC0zIC0xLDAgeiI+PC9wYXRoPjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjEyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSI2IiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjEyIj48L3JlY3Q+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iOSIgeT0iOSI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjYiIHk9IjkiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSIyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIzIiBoZWlnaHQ9IjIiIHg9IjIiIHk9IjkiPjwvcmVjdD48L2c+PC9zdmc+');
|
||||
}
|
44
web_app/css/external/keyboard-previewkeyset.css
vendored
44
web_app/css/external/keyboard-previewkeyset.css
vendored
|
@ -1,44 +0,0 @@
|
|||
/* basic previewKeyset setup - modify as desired */
|
||||
.ui-keyboard-keyset .ui-keyboard-button {
|
||||
position: relative;
|
||||
}
|
||||
/* show mini-shift keyset with normal keyset */
|
||||
.ui-keyboard-keyset-normal .ui-keyboard-button::after {
|
||||
content: attr(data-shift);
|
||||
font-size: 0.6em;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
left: 2px;
|
||||
z-index: 200;
|
||||
}
|
||||
/* show mini-normal keyset with shift keyset */
|
||||
.ui-keyboard-keyset-shift .ui-keyboard-button::after {
|
||||
content: attr(data-normal);
|
||||
font-size: 0.6em;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
left: 2px;
|
||||
z-index: 200;
|
||||
}
|
||||
/* show mini-normal keyset with alt keyset */
|
||||
.ui-keyboard-keyset-alt .ui-keyboard-button::after {
|
||||
content: attr(data-alt-shift);
|
||||
font-size: 0.6em;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
left: 2px;
|
||||
z-index: 200;
|
||||
}
|
||||
/* show mini-alt-shift keyset with alt-shift keyset */
|
||||
.ui-keyboard-keyset-alt-shift .ui-keyboard-button::after {
|
||||
content: attr(data-alt);
|
||||
font-size: 0.6em;
|
||||
color: #999;
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
left: 2px;
|
||||
z-index: 200;
|
||||
}
|
161
web_app/css/external/keyboard.css
vendored
161
web_app/css/external/keyboard.css
vendored
|
@ -1,161 +0,0 @@
|
|||
/* keyboard - jQuery UI Widget */
|
||||
.ui-keyboard { padding: .3em; position: absolute; left: 0; top: 0; z-index: 16000; }
|
||||
.ui-keyboard-has-focus { z-index: 16001; }
|
||||
.ui-keyboard div { font-size: 1.1em; }
|
||||
.ui-keyboard-button { height: 2em; min-width: 2em; margin: .1em; cursor: pointer; overflow: hidden; line-height: 2em; -moz-user-focus: ignore; }
|
||||
.ui-keyboard-button span { padding: 0; margin: 0; white-space:nowrap; display: inline-block; }
|
||||
.ui-keyboard-button-endrow { clear: left; }
|
||||
.ui-keyboard-space { width: 15em; }
|
||||
/* see http://nicolasgallagher.com/another-css-image-replacement-technique/ */
|
||||
.ui-keyboard-space span, .ui-keyboard-empty span { font: 0/0 a; text-shadow: none; color: transparent; }
|
||||
.ui-keyboard-preview-wrapper { text-align: center; position: relative; overflow: hidden; }
|
||||
/* width is calculated in IE, since 99% = 99% full browser width =( */
|
||||
.ui-keyboard-preview { text-align: left; margin: 0 0 3px 0; display: inline; width: 99%;}
|
||||
.ui-keyboard-keyset { text-align: center; white-space: nowrap; }
|
||||
.ui-keyboard-input { text-align: left; }
|
||||
.ui-keyboard-input-current { -moz-box-shadow: 0 0 5px #4d90fe; -webkit-box-shadow: 0 0 5px #4d90fe; box-shadow: 0 0 5px #4d90fe; }
|
||||
.ui-keyboard-placeholder { color: #888; }
|
||||
/* disabled or readonly inputs, or use input[disabled='disabled'] { color: #f00; } */
|
||||
.ui-keyboard-nokeyboard { color: #888; border-color: #888; }
|
||||
.ui-keyboard-spacer { display: inline-block; width: 1px; height: 0; cursor: default; }
|
||||
|
||||
.ui-keyboard-NBSP span, .ui-keyboard-ZWSP span, .ui-keyboard-ZWNJ span, .ui-keyboard-ZWJ span, .ui-keyboard-LRM span, .ui-keyboard-RLM span {
|
||||
font-size: 0.5em;
|
||||
line-height: 1.5em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* combo key styling - toggles diacritics on/off */
|
||||
.ui-keyboard-button.ui-keyboard-combo.ui-state-default { border-color: #ffaf0f; }
|
||||
|
||||
/* (in)valid inputs */
|
||||
button.ui-keyboard-accept.ui-keyboard-valid-input { border-color: #0c0; background: #080; color: #fff; }
|
||||
button.ui-keyboard-accept.ui-keyboard-valid-input:hover { background: #0a0; }
|
||||
button.ui-keyboard-accept.ui-keyboard-invalid-input { border-color: #c00; background: #800; color: #fff; opacity: 0.5; filter: alpha(opacity=50); }
|
||||
button.ui-keyboard-accept.ui-keyboard-invalid-input:hover { background: #a00; }
|
||||
|
||||
/*** Caret extension definition ***/
|
||||
/* margin-top => is added to the caret height (top & bottom) */
|
||||
.ui-keyboard-caret { background: #c00; width: 1px; margin-top: 3px; }
|
||||
|
||||
/*** jQuery Mobile definitions ***/
|
||||
/* jQuery Mobile styles - need wider buttons because of font size and text-overflow:ellipsis */
|
||||
div.ui-body.ui-keyboard button.ui-keyboard-button.ui-btn { padding: 0.5em 1em; border-color: transparent; }
|
||||
.ui-body .ui-keyboard-button { width: 3em; height: 3em; display: inline-block; }
|
||||
.ui-body .ui-keyboard-widekey { width: 5.5em; }
|
||||
.ui-body .ui-keyboard-space { width: 15em; }
|
||||
.ui-body .ui-keyboard-space span { visibility: hidden; } /* hides the ellipsis */
|
||||
.ui-body .ui-keyboard-keyset { line-height: 0.5em; }
|
||||
.ui-body input.ui-input-text, .ui-body textarea.ui-input-text { width: 95%; }
|
||||
|
||||
/* over-ride padding set by mobile ui theme - needed because the mobile script wraps button text with several more spans */
|
||||
.ui-body .ui-btn-inner { height: 2em; padding: 0.2em 0; margin: 0; }
|
||||
.ui-body .ui-btn { margin: 0; font-size: 13px; } /* mobile default size is 13px */
|
||||
|
||||
/* override Bootstrap excessive button padding */
|
||||
button.ui-keyboard-button.btn { padding: 1px 6px; }
|
||||
|
||||
/* enable/disable icons */
|
||||
button.ui-keyboard-toggle span {
|
||||
width: .8em;
|
||||
height: .8em;
|
||||
display: inline-block;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: contain;
|
||||
}
|
||||
/* unlocked icon (keyboard enabled) */
|
||||
button.ui-keyboard-toggle span {
|
||||
/* light theme unlocked icon - fill: #111 */
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iIzExMSI+PHBhdGggZD0iTTguNyw0LjRINy41SDUuMHYtMS45YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41djEuOWgxLjIgdi0xLjljMC0wLjcsMC42LTEuMiwxLjItMS4yczEuMiwwLjYsMS4yLDEuMnYxLjljLTAuNywwLTEuMiwwLjYtMS4yLDEuMlY4LjggYzAsMC43LDAuNiwxLjIsMS4yLDEuMmg1LjBDOS40LDEwLDEwLDkuNCwxMCw4LjhWNS42QzEwLDUuMCw5LjQsNC40LDguOCw0LjR6IE02LjYsNy40djEuMCBjMCwwLjItMC4xLDAuMy0wLjMsMC4zUzYuMCw4LjYsNi4wLDguNFY3LjRjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zLDAuMy0wLjYsMC42LTAuNiBTNi45LDYuNiw2LjksNi45QzYuOSw3LjEsNi44LDcuMyw2LjYsNy40eiIvPjwvc3ZnPg==);
|
||||
}
|
||||
.ui-keyboard-dark-theme button.ui-keyboard-toggle span {
|
||||
/* dark theme unlocked icon - fill: #eee */
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iI2VlZSI+PHBhdGggZD0iTTguNyw0LjRINy41SDUuMHYtMS45YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40LDAtMi41LDEuMS0yLjUsMi41djEuOWgxLjIgdi0xLjljMC0wLjcsMC42LTEuMiwxLjItMS4yczEuMiwwLjYsMS4yLDEuMnYxLjljLTAuNywwLTEuMiwwLjYtMS4yLDEuMlY4LjggYzAsMC43LDAuNiwxLjIsMS4yLDEuMmg1LjBDOS40LDEwLDEwLDkuNCwxMCw4LjhWNS42QzEwLDUuMCw5LjQsNC40LDguOCw0LjR6IE02LjYsNy40djEuMCBjMCwwLjItMC4xLDAuMy0wLjMsMC4zUzYuMCw4LjYsNi4wLDguNFY3LjRjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zLDAuMy0wLjYsMC42LTAuNiBTNi45LDYuNiw2LjksNi45QzYuOSw3LjEsNi44LDcuMyw2LjYsNy40eiIvPjwvc3ZnPg==);
|
||||
}
|
||||
|
||||
/* locked icon (keyboard disabled) */
|
||||
button.ui-keyboard-toggle.ui-keyboard-disabled span {
|
||||
/* light theme locked icon - fill: #111 */
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iIzExMSI+PHBhdGggZD0iTTcuNCA0LjRWMi41YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40IDAtMi41IDEuMS0yLjUgMi41djEuOSBjLTAuNyAwLTEuMiAwLjUtMS4yIDEuMnYzLjFDMS4zIDkuNCAxLjggMTAgMi41IDEwaDQuOWMwLjcgMCAxLjItMC42IDEuMi0xLjJWNS42IEM4LjcgNC45IDguMSA0LjQgNy40IDQuNHogTTUuMyA3LjR2MS4wYzAgMC4yLTAuMSAwLjMtMC4zIDAuM2MtMC4yIDAtMC4zLTAuMS0wLjMtMC4zVjcuNCBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zIDAuMy0wLjYgMC42LTAuNmMwLjMgMCAwLjYgMC4zIDAuNiAwLjYgQzUuNiA3LjEgNS41IDcuMyA1LjMgNy40eiBNNi4yIDQuNEgzLjdWMi41YzAtMC43IDAuNS0xLjIgMS4yLTEuMmMwLjcgMCAxLjIgMC42IDEuMiAxLjIgVjQuNHoiLz48L3N2Zz4=);
|
||||
}
|
||||
.ui-keyboard-dark-theme button.ui-keyboard-toggle.ui-keyboard-disabled span {
|
||||
/* dark theme locked icon - fill: #eee */
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgZmlsbD0iI2VlZSI+PHBhdGggZD0iTTcuNCA0LjRWMi41YzAtMS40LTEuMS0yLjUtMi41LTIuNWMtMS40IDAtMi41IDEuMS0yLjUgMi41djEuOSBjLTAuNyAwLTEuMiAwLjUtMS4yIDEuMnYzLjFDMS4zIDkuNCAxLjggMTAgMi41IDEwaDQuOWMwLjcgMCAxLjItMC42IDEuMi0xLjJWNS42IEM4LjcgNC45IDguMSA0LjQgNy40IDQuNHogTTUuMyA3LjR2MS4wYzAgMC4yLTAuMSAwLjMtMC4zIDAuM2MtMC4yIDAtMC4zLTAuMS0wLjMtMC4zVjcuNCBjLTAuMi0wLjEtMC4zLTAuMy0wLjMtMC41YzAtMC4zIDAuMy0wLjYgMC42LTAuNmMwLjMgMCAwLjYgMC4zIDAuNiAwLjYgQzUuNiA3LjEgNS41IDcuMyA1LjMgNy40eiBNNi4yIDQuNEgzLjdWMi41YzAtMC43IDAuNS0xLjIgMS4yLTEuMmMwLjcgMCAxLjIgMC42IDEuMiAxLjIgVjQuNHoiLz48L3N2Zz4=);
|
||||
}
|
||||
|
||||
.ui-keyboard.ui-keyboard-disabled button:not(.ui-keyboard-toggle),
|
||||
.ui-keyboard.ui-keyboard-disabled input {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/*** Alt-Keys Popup extension ***/
|
||||
/* clickable overlay on top of keyboard to hide the popup */
|
||||
.ui-keyboard-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
/* the actual popup styling, class names from the css.container option are also added */
|
||||
.ui-keyboard-popup {
|
||||
display: inline-block;
|
||||
/* default buttons are 2em wide + .1em margin on either side (set in .ui-keyboard-button definition);
|
||||
so use multiples of 2.2em for a max-width if you don't want any extra white space on the sides,
|
||||
e.g. 5 buttons * 2.2em = 11em, 6 buttons * 2.2em = 13.2em, etc */
|
||||
max-width: 22em; /* 10 buttons */
|
||||
}
|
||||
|
||||
/*** Extender keyboard extension ***/
|
||||
div.ui-keyboard-extender { float: right; margin-left: 5px; }
|
||||
button.ui-keyboard-extender span {
|
||||
width: .9em;
|
||||
height: .9em;
|
||||
display: inline-block;
|
||||
margin-bottom: 3px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: contain;
|
||||
/* light theme extender icon - fill: #111 */
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgc3R5bGU9ImZpbGw6IzExMSI+PGc+PHBhdGggc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6IzExMSIgZD0iTSAwLjUsNC41IDE1LjUsNC41IDE1LjUsMTUuNSAwLjUsMTUuNSBaIj48L3BhdGg+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iMiIgeT0iNiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjYiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSI4IiB5PSI2Ij48L3JlY3Q+PHBhdGggZD0ibSAxMSw2IDMsMCAwLDUgLTIsMCAwLC0zIC0xLDAgeiI+PC9wYXRoPjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjEyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSI2IiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjEyIj48L3JlY3Q+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iOSIgeT0iOSI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjYiIHk9IjkiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSIyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIzIiBoZWlnaHQ9IjIiIHg9IjIiIHk9IjkiPjwvcmVjdD48L2c+PC9zdmc+);
|
||||
}
|
||||
.ui-keyboard-dark-theme button.ui-keyboard-extender span {
|
||||
/* dark theme extender icon - fill: #eee */
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgc3R5bGU9ImZpbGw6I2VlZSI+PGc+PHBhdGggc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6I2VlZSIgZD0iTSAwLjUsNC41IDE1LjUsNC41IDE1LjUsMTUuNSAwLjUsMTUuNSBaIj48L3BhdGg+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iMiIgeT0iNiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjYiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSI4IiB5PSI2Ij48L3JlY3Q+PHBhdGggZD0ibSAxMSw2IDMsMCAwLDUgLTIsMCAwLC0zIC0xLDAgeiI+PC9wYXRoPjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjEyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSI2IiBoZWlnaHQ9IjIiIHg9IjUiIHk9IjEyIj48L3JlY3Q+PHJlY3Qgd2lkdGg9IjIiIGhlaWdodD0iMiIgeD0iOSIgeT0iOSI+PC9yZWN0PjxyZWN0IHdpZHRoPSIyIiBoZWlnaHQ9IjIiIHg9IjYiIHk9IjkiPjwvcmVjdD48cmVjdCB3aWR0aD0iMiIgaGVpZ2h0PSIyIiB4PSIyIiB5PSIxMiI+PC9yZWN0PjxyZWN0IHdpZHRoPSIzIiBoZWlnaHQ9IjIiIHg9IjIiIHk9IjkiPjwvcmVjdD48L2c+PC9zdmc+);
|
||||
}
|
||||
|
||||
/* Media Queries (optimized for jQuery UI themes; may be slightly off in jQuery Mobile themes) */
|
||||
/* 240 x 320 (small phone) */
|
||||
@media all and (max-width: 319px) {
|
||||
.ui-keyboard div { font-size: 9px; }
|
||||
.ui-keyboard .ui-keyboard-input { font-size: 12px; }
|
||||
/* I don't own an iPhone so I have no idea how small this really is... is it even clickable with your finger? */
|
||||
.ui-body .ui-btn { margin: 0; font-size: 9px; }
|
||||
.ui-body .ui-keyboard-button { width: 1.8em; height: 2.5em; }
|
||||
.ui-body .ui-keyboard-widekey { width: 4em; }
|
||||
.ui-body .ui-keyboard-space { width: 8em; }
|
||||
.ui-body .ui-btn-inner { height: 2.5em; padding: 0.3em 0; }
|
||||
}
|
||||
|
||||
/* 320 x 480 (iPhone) */
|
||||
@media all and (min-width: 320px) and (max-width: 479px) {
|
||||
.ui-keyboard div { font-size: 9px; }
|
||||
.ui-keyboard .ui-keyboard-input { font-size: 14px; }
|
||||
/* I don't own an iPhone so I have no idea how small this really is... is it even clickable with your finger? */
|
||||
.ui-body .ui-btn { margin: 0; font-size: 11px; }
|
||||
.ui-body .ui-keyboard-button { width: 1.8em; height: 3em; }
|
||||
.ui-body .ui-keyboard-widekey { width: 4.5em; }
|
||||
.ui-body .ui-keyboard-space { width: 10em; }
|
||||
.ui-body .ui-btn-inner { height: 3em; padding: 0.7em 0; }
|
||||
}
|
||||
|
||||
/* 480 x 640 (small tablet) */
|
||||
@media all and (min-width: 480px) and (max-width: 767px) {
|
||||
.ui-keyboard div { font-size: 13px; }
|
||||
.ui-keyboard .ui-keyboard-input { font-size: 14px; }
|
||||
.ui-body .ui-btn { margin: 0; font-size: 10px; }
|
||||
.ui-body .ui-keyboard-button { height: 2.5em; }
|
||||
.ui-body .ui-btn-inner { height: 2.5em; padding: 0.5em 0; }
|
||||
}
|
|
@ -1,13 +1,12 @@
|
|||
body {
|
||||
font: 100% "Trebuchet MS", sans-serif;
|
||||
margin: 50px;
|
||||
font-family: Verdana,Arial,sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0px;
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Verdana,Arial,sans-serif;
|
||||
font-size: 14px;
|
||||
/*height: 100%;*/
|
||||
/*min-height: 480px;*/
|
||||
}
|
||||
|
||||
p {
|
|
@ -1,10 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>SIFTools</title>
|
||||
<META http-equiv="refresh" content="5;URL=sif_tools.html">
|
||||
</head>
|
||||
<body bgcolor="#ffffff">
|
||||
<center>This is not the web page you're looking for... <A HREF="sif_tools.html">move along, move along</a>
|
||||
</center>
|
||||
</body>
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy for HTML5 for Mac OS X version 5.0.0">
|
||||
<title>SIFTools</title>
|
||||
<meta http-equiv="refresh" content="5;URL=sif_tools.html">
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF">
|
||||
<center>
|
||||
This is not the web page you're looking for... <a href="sif_tools.html">move along, move along</a>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
|
|
104
web_app/js/external/date.js
vendored
104
web_app/js/external/date.js
vendored
|
@ -1,104 +0,0 @@
|
|||
/**
|
||||
* Version: 1.0 Alpha-1
|
||||
* Build Date: 13-Nov-2007
|
||||
* Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
|
||||
* License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/.
|
||||
* Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
|
||||
*/
|
||||
Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|after|from)/i,subtract:/^(\-|before|ago)/i,yesterday:/^yesterday/i,today:/^t(oday)?/i,tomorrow:/^tomorrow/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^min(ute)?s?/i,hour:/^h(ou)?rs?/i,week:/^w(ee)?k/i,month:/^m(o(nth)?s?)?/i,day:/^d(ays?)?/i,year:/^y((ea)?rs?)?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a|p)/i},abbreviatedTimeZoneStandard:{GMT:"-000",EST:"-0400",CST:"-0500",MST:"-0600",PST:"-0700"},abbreviatedTimeZoneDST:{GMT:"-000",EDT:"-0500",CDT:"-0600",MDT:"-0700",PDT:"-0800"}};
|
||||
Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
|
||||
return-1;};Date.getDayNumberFromName=function(name){var n=Date.CultureInfo.dayNames,m=Date.CultureInfo.abbreviatedDayNames,o=Date.CultureInfo.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}}
|
||||
return-1;};Date.isLeapYear=function(year){return(((year%4===0)&&(year%100!==0))||(year%400===0));};Date.getDaysInMonth=function(year,month){return[31,(Date.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};Date.getTimezoneOffset=function(s,dst){return(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()]:Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];};Date.getTimezoneAbbreviation=function(offset,dst){var n=(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST:Date.CultureInfo.abbreviatedTimeZoneStandard,p;for(p in n){if(n[p]===offset){return p;}}
|
||||
return null;};Date.prototype.clone=function(){return new Date(this.getTime());};Date.prototype.compareTo=function(date){if(isNaN(this)){throw new Error(this);}
|
||||
if(date instanceof Date&&!isNaN(date)){return(this>date)?1:(this<date)?-1:0;}else{throw new TypeError(date);}};Date.prototype.equals=function(date){return(this.compareTo(date)===0);};Date.prototype.between=function(start,end){var t=this.getTime();return t>=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMonth()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;}
|
||||
var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);}
|
||||
if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);}
|
||||
if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);}
|
||||
if(x.hour||x.hours){this.addHours(x.hour||x.hours);}
|
||||
if(x.month||x.months){this.addMonths(x.month||x.months);}
|
||||
if(x.year||x.years){this.addYears(x.year||x.years);}
|
||||
if(x.day||x.days){this.addDays(x.day||x.days);}
|
||||
return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(value<min||value>max){throw new RangeError(value+" is not a valid value for "+name+".");}
|
||||
return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;}
|
||||
if(!x.second&&x.second!==0){x.second=-1;}
|
||||
if(!x.minute&&x.minute!==0){x.minute=-1;}
|
||||
if(!x.hour&&x.hour!==0){x.hour=-1;}
|
||||
if(!x.day&&x.day!==0){x.day=-1;}
|
||||
if(!x.month&&x.month!==0){x.month=-1;}
|
||||
if(!x.year&&x.year!==0){x.year=-1;}
|
||||
if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());}
|
||||
if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());}
|
||||
if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());}
|
||||
if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());}
|
||||
if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());}
|
||||
if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());}
|
||||
if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());}
|
||||
if(x.timezone){this.setTimezone(x.timezone);}
|
||||
if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);}
|
||||
return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor((this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;}
|
||||
var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}}
|
||||
return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M":return self.getMonth()+1;case"t":return self.getHours()<12?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();};
|
||||
Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;}
|
||||
return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i<dx.length;i++){$D[dx[i]]=$D[dx[i].substring(0,3)]=df(i);}
|
||||
var mf=function(n){return function(){if(this._is){this._is=false;return this.getMonth()===n;}
|
||||
return this.moveToMonth(n,this._orient);};};for(var j=0;j<mx.length;j++){$D[mx[j]]=$D[mx[j].substring(0,3)]=mf(j);}
|
||||
var ef=function(j){return function(){if(j.substring(j.length-1)!="s"){j+="s";}
|
||||
return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$D[de]=$D[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}}());Date.prototype.toJSONString=function(){return this.toString("yyyy-MM-ddThh:mm:ssZ");};Date.prototype.toShortDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortDatePattern);};Date.prototype.toLongDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.longDatePattern);};Date.prototype.toShortTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortTimePattern);};Date.prototype.toLongTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.longTimePattern);};Date.prototype.getOrdinal=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};
|
||||
(function(){Date.Parsing={Exception:function(s){this.message="Parse error at '"+s.substring(0,10)+" ...'";}};var $P=Date.Parsing;var _=$P.Operators={rtoken:function(r){return function(s){var mx=s.match(r);if(mx){return([mx[0],s.substring(mx[0].length)]);}else{throw new $P.Exception(s);}};},token:function(s){return function(s){return _.rtoken(new RegExp("^\s*"+s+"\s*"))(s);};},stoken:function(s){return _.rtoken(new RegExp("^"+s));},until:function(p){return function(s){var qx=[],rx=null;while(s.length){try{rx=p.call(this,s);}catch(e){qx.push(rx[0]);s=rx[1];continue;}
|
||||
break;}
|
||||
return[qx,s];};},many:function(p){return function(s){var rx=[],r=null;while(s.length){try{r=p.call(this,s);}catch(e){return[rx,s];}
|
||||
rx.push(r[0]);s=r[1];}
|
||||
return[rx,s];};},optional:function(p){return function(s){var r=null;try{r=p.call(this,s);}catch(e){return[null,s];}
|
||||
return[r[0],r[1]];};},not:function(p){return function(s){try{p.call(this,s);}catch(e){return[null,s];}
|
||||
throw new $P.Exception(s);};},ignore:function(p){return p?function(s){var r=null;r=p.call(this,s);return[null,r[1]];}:null;},product:function(){var px=arguments[0],qx=Array.prototype.slice.call(arguments,1),rx=[];for(var i=0;i<px.length;i++){rx.push(_.each(px[i],qx));}
|
||||
return rx;},cache:function(rule){var cache={},r=null;return function(s){try{r=cache[s]=(cache[s]||rule.call(this,s));}catch(e){r=cache[s]=e;}
|
||||
if(r instanceof $P.Exception){throw r;}else{return r;}};},any:function(){var px=arguments;return function(s){var r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
|
||||
try{r=(px[i].call(this,s));}catch(e){r=null;}
|
||||
if(r){return r;}}
|
||||
throw new $P.Exception(s);};},each:function(){var px=arguments;return function(s){var rx=[],r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;}
|
||||
try{r=(px[i].call(this,s));}catch(e){throw new $P.Exception(s);}
|
||||
rx.push(r[0]);s=r[1];}
|
||||
return[rx,s];};},all:function(){var px=arguments,_=_;return _.each(_.optional(px));},sequence:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;if(px.length==1){return px[0];}
|
||||
return function(s){var r=null,q=null;var rx=[];for(var i=0;i<px.length;i++){try{r=px[i].call(this,s);}catch(e){break;}
|
||||
rx.push(r[0]);try{q=d.call(this,r[1]);}catch(ex){q=null;break;}
|
||||
s=q[1];}
|
||||
if(!r){throw new $P.Exception(s);}
|
||||
if(q){throw new $P.Exception(q[1]);}
|
||||
if(c){try{r=c.call(this,r[1]);}catch(ey){throw new $P.Exception(r[1]);}}
|
||||
return[rx,(r?r[1]:s)];};},between:function(d1,p,d2){d2=d2||d1;var _fn=_.each(_.ignore(d1),p,_.ignore(d2));return function(s){var rx=_fn.call(this,s);return[[rx[0][0],r[0][2]],rx[1]];};},list:function(p,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return(p instanceof Array?_.each(_.product(p.slice(0,-1),_.ignore(d)),p.slice(-1),_.ignore(c)):_.each(_.many(_.each(p,_.ignore(d))),px,_.ignore(c)));},set:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return function(s){var r=null,p=null,q=null,rx=null,best=[[],s],last=false;for(var i=0;i<px.length;i++){q=null;p=null;r=null;last=(px.length==1);try{r=px[i].call(this,s);}catch(e){continue;}
|
||||
rx=[[r[0]],r[1]];if(r[1].length>0&&!last){try{q=d.call(this,r[1]);}catch(ex){last=true;}}else{last=true;}
|
||||
if(!last&&q[1].length===0){last=true;}
|
||||
if(!last){var qx=[];for(var j=0;j<px.length;j++){if(i!=j){qx.push(px[j]);}}
|
||||
p=_.set(qx,d).call(this,q[1]);if(p[0].length>0){rx[0]=rx[0].concat(p[0]);rx[1]=p[1];}}
|
||||
if(rx[1].length<best[1].length){best=rx;}
|
||||
if(best[1].length===0){break;}}
|
||||
if(best[0].length===0){return best;}
|
||||
if(c){try{q=c.call(this,best[1]);}catch(ey){throw new $P.Exception(best[1]);}
|
||||
best[1]=q[1];}
|
||||
return best;};},forward:function(gr,fname){return function(s){return gr[fname].call(this,s);};},replace:function(rule,repl){return function(s){var r=rule.call(this,s);return[repl,r[1]];};},process:function(rule,fn){return function(s){var r=rule.call(this,s);return[fn.call(this,r[0]),r[1]];};},min:function(min,rule){return function(s){var rx=rule.call(this,s);if(rx[0].length<min){throw new $P.Exception(s);}
|
||||
return rx;};}};var _generator=function(op){return function(){var args=null,rx=[];if(arguments.length>1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];}
|
||||
if(args){for(var i=0,px=args.shift();i<px.length;i++){args.unshift(px[i]);rx.push(op.apply(null,args));args.shift();return rx;}}else{return op.apply(null,arguments);}};};var gx="optional not ignore cache".split(/\s/);for(var i=0;i<gx.length;i++){_[gx[i]]=_generator(_[gx[i]]);}
|
||||
var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}}
|
||||
return rx;};Date.Grammar={};Date.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=((s.length==3)?Date.getMonthNumberFromName(s):(Number(s)-1));};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<Date.CultureInfo.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;break;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];var now=new Date();this.year=now.getFullYear();this.month=now.getMonth();this.day=1;this.hour=0;this.minute=0;this.second=0;for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}}
|
||||
this.hour=(this.meridian=="p"&&this.hour<13)?this.hour+12:this.hour;if(this.day>Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");}
|
||||
var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});}
|
||||
return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;}
|
||||
for(var i=0;i<x.length;i++){if(typeof x[i]=="function"){x[i].call(this);}}
|
||||
if(this.now){return new Date();}
|
||||
var today=Date.today();var method=null;var expression=!!(this.days!=null||this.orient||this.operator);if(expression){var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(this.weekday){this.unit="day";gap=(Date.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);}
|
||||
if(this.month){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;}
|
||||
if(!this.unit){this.unit="day";}
|
||||
if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;}
|
||||
if(this.unit=="week"){this.unit="day";this.value=this.value*7;}
|
||||
this[this.unit+"s"]=this.value*orient;}
|
||||
return today.add(this);}else{if(this.meridian&&this.hour){this.hour=(this.hour<13&&this.meridian=="p")?this.hour+12:this.hour;}
|
||||
if(this.weekday&&!this.day){this.day=(today.addDays((Date.getDayNumberFromName(this.weekday)-today.getDay()))).getDate();}
|
||||
if(this.month&&!this.day){this.day=1;}
|
||||
return today.set(this);}}};var _=Date.Parsing.Operators,g=Date.Grammar,t=Date.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=Date.CultureInfo.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));}
|
||||
fn=_C[keys]=_.any.apply(null,px);}
|
||||
return fn;};g.ctoken2=function(key){return _.rtoken(Date.CultureInfo.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.mm,g.ss],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^(\+|\-)?\s*\d\d\d\d?/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^(\+|\-)\s*\d\d\d\d/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.timeSuffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("timeContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.year=_fn(g.yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[Date.CultureInfo.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}else{throw Date.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));}
|
||||
return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["yyyy-MM-ddTHH:mm:ss","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){}
|
||||
return g._start.call({},s);};}());Date._parse=Date.parse;Date.parse=function(s){var r=null;if(!s){return null;}
|
||||
try{r=Date.Grammar.start.call({},s);}catch(e){return null;}
|
||||
return((r[1].length===0)?r[0]:null);};Date.getParseFunction=function(fx){var fn=Date.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;}
|
||||
return((r[1].length===0)?r[0]:null);};};Date.parseExact=function(s,fx){return Date.getParseFunction(fx)(s);};
|
117
web_app/js/external/jquery.cookie.js
vendored
Normal file
117
web_app/js/external/jquery.cookie.js
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*!
|
||||
* jQuery Cookie Plugin v1.4.1
|
||||
* https://github.com/carhartl/jquery-cookie
|
||||
*
|
||||
* Copyright 2013 Klaus Hartl
|
||||
* Released under the MIT license
|
||||
*/
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// CommonJS
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
|
||||
var pluses = /\+/g;
|
||||
|
||||
function encode(s) {
|
||||
return config.raw ? s : encodeURIComponent(s);
|
||||
}
|
||||
|
||||
function decode(s) {
|
||||
return config.raw ? s : decodeURIComponent(s);
|
||||
}
|
||||
|
||||
function stringifyCookieValue(value) {
|
||||
return encode(config.json ? JSON.stringify(value) : String(value));
|
||||
}
|
||||
|
||||
function parseCookieValue(s) {
|
||||
if (s.indexOf('"') === 0) {
|
||||
// This is a quoted cookie as according to RFC2068, unescape...
|
||||
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
||||
}
|
||||
|
||||
try {
|
||||
// Replace server-side written pluses with spaces.
|
||||
// If we can't decode the cookie, ignore it, it's unusable.
|
||||
// If we can't parse the cookie, ignore it, it's unusable.
|
||||
s = decodeURIComponent(s.replace(pluses, ' '));
|
||||
return config.json ? JSON.parse(s) : s;
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
function read(s, converter) {
|
||||
var value = config.raw ? s : parseCookieValue(s);
|
||||
return $.isFunction(converter) ? converter(value) : value;
|
||||
}
|
||||
|
||||
var config = $.cookie = function (key, value, options) {
|
||||
|
||||
// Write
|
||||
|
||||
if (value !== undefined && !$.isFunction(value)) {
|
||||
options = $.extend({}, config.defaults, options);
|
||||
|
||||
if (typeof options.expires === 'number') {
|
||||
var days = options.expires, t = options.expires = new Date();
|
||||
t.setTime(+t + days * 864e+5);
|
||||
}
|
||||
|
||||
return (document.cookie = [
|
||||
encode(key), '=', stringifyCookieValue(value),
|
||||
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
|
||||
options.path ? '; path=' + options.path : '',
|
||||
options.domain ? '; domain=' + options.domain : '',
|
||||
options.secure ? '; secure' : ''
|
||||
].join(''));
|
||||
}
|
||||
|
||||
// Read
|
||||
|
||||
var result = key ? undefined : {};
|
||||
|
||||
// To prevent the for loop in the first place assign an empty array
|
||||
// in case there are no cookies at all. Also prevents odd result when
|
||||
// calling $.cookie().
|
||||
var cookies = document.cookie ? document.cookie.split('; ') : [];
|
||||
|
||||
for (var i = 0, l = cookies.length; i < l; i++) {
|
||||
var parts = cookies[i].split('=');
|
||||
var name = decode(parts.shift());
|
||||
var cookie = parts.join('=');
|
||||
|
||||
if (key && key === name) {
|
||||
// If second argument (value) is a function it's a converter...
|
||||
result = read(cookie, value);
|
||||
break;
|
||||
}
|
||||
|
||||
// Prevent storing a cookie that we couldn't decode.
|
||||
if (!key && (cookie = read(cookie)) !== undefined) {
|
||||
result[name] = cookie;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
config.defaults = {};
|
||||
|
||||
$.removeCookie = function (key, options) {
|
||||
if ($.cookie(key) === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Must not alter options, thus extending a fresh object...
|
||||
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
|
||||
return !$.cookie(key);
|
||||
};
|
||||
|
||||
}));
|
1959
web_app/js/external/jquery.keyboard.extension-all.js
vendored
1959
web_app/js/external/jquery.keyboard.extension-all.js
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,209 +0,0 @@
|
|||
/*! jQuery UI Virtual Keyboard Alt Key Popup v1.0.1 *//*
|
||||
* for Keyboard v1.18+ only (7/7/2015)
|
||||
*
|
||||
* By Rob Garrison (aka Mottie)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
*/
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global require:false, define:false, module:false */
|
||||
;( function( factory ) {
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
define( [ 'jquery' ], factory );
|
||||
} else if ( typeof module === 'object' && typeof module.exports === 'object' ) {
|
||||
module.exports = factory( require( 'jquery' ) );
|
||||
} else {
|
||||
factory( jQuery );
|
||||
}
|
||||
}( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
var $keyboard = $.keyboard;
|
||||
|
||||
$.extend( $keyboard.css, {
|
||||
altKeyPopup : 'ui-keyboard-popup',
|
||||
altKeyOverlay : 'ui-keyboard-overlay'
|
||||
});
|
||||
|
||||
$keyboard.altKeys = $.extend({
|
||||
a : '\u00e5 \u00e6 \u0101 \u0103 \u0105 \u00e0 \u00e1 \u00e2 \u00e3 \u00e4', // å æ ā ă ą à á â ã ä
|
||||
A : '\u00c5 \u00c6 \u0100 \u0102 \u0104 \u00c0 \u00c1 \u00c2 \u00c3 \u00c4', // Å Æ Ā Ă Ą À Á Â Ã Ä
|
||||
c : '\u00e7 \u0107 \u0109 \u010b \u010d', // ç ć ĉ ċ č
|
||||
C : '\u00c7 \u0106 \u0108 \u010a \u010c', // Ç Ć Ĉ Ċ Č
|
||||
d : '\u010f \u00f0 \u010f', // ď ð ď
|
||||
D : '\u010e \u00d0 \u010e', // Ď Ð Ď
|
||||
e : '\u0117 \u0119 \u0115 \u011b \u0259 \u00e8 \u00e9 \u00ea \u00eb \u0113', // ė ę ĕ ě ə è é ê ë ē
|
||||
E : '\u0116 \u0118 \u0114 \u011a \u018e \u00c8 \u00c9 \u00ca \u00cb \u0112', // Ė Ę Ĕ Ě Ǝ È É Ê Ë Ē
|
||||
g : '\u0123 \u011f \u011d \u0121', // ģ ğ ĝ ġ
|
||||
G : '\u0122 \u011e \u011c \u0120', // Ģ Ğ Ĝ Ġ
|
||||
h : '\u0125 \u0127', // ĥ ħ
|
||||
H : '\u0124 \u0126', // Ĥ Ħ
|
||||
i : '\u0131 \u012f \u012b \u00ef \u00ee \u00ed \u00ec \u0129 \u012d', // ı į ī ï î í ì ĩ ĭ
|
||||
I : '\u0130 \u012e \u012a \u00cf \u00ce \u00cd \u00cc \u0128 \u012c', // İ Į Ī Ï Î Í Ì Ĩ Ĭ
|
||||
j : '\u0135', // ĵ
|
||||
J : '\u0134', // Ĵ
|
||||
k : '\u0137', // ķ
|
||||
K : '\u0136', // Ķ
|
||||
l : '\u0141 \u013d \u013b \u0139 \u013f', // Ł Ľ Ļ Ĺ Ŀ
|
||||
L : '\u0142 \u013e \u013c \u013a \u0140', // ł ľ ļ ĺ ŀ
|
||||
n : '\u0149 \u0148 \u0146 \u0144 \u00f1', // ʼn ň ņ ń ñ
|
||||
N : '\u0149 \u0147 \u0145 \u0143 \u00d1', // ʼn Ň Ņ Ń Ñ
|
||||
o : '\u0153 \u0151 \u00f8 \u00f6 \u00f5 \u00f4 \u00f3 \u00f2 \u014d \u014f', // œ ő ø ö õ ô ó ò ō ŏ
|
||||
O : '\u0152 \u0150 \u00d8 \u00d6 \u00d5 \u00d4 \u00d3 \u00d2 \u014c \u014e', // Œ Ő Ø Ö Õ Ô Ó Ò Ō Ŏ
|
||||
r : '\u0155 \u0159 \u0157', // ŕ ř ŗ
|
||||
R : '\u0154 \u0158 \u0156', // Ŕ Ř Ŗ
|
||||
s : '\u015b \u0161 \u015f \u00df \u00a7 \u015d', // ś š ş ß § ŝ
|
||||
S : '\u015a \u0160 \u015e \u1e9e \u00a7 \u015c', // Ś Š Ş ẞ § Ŝ
|
||||
t : '\u00fe \u0165 \u021b \u0163 \u0167', // þ ť ț ţ ŧ
|
||||
T : '\u00de \u0164 \u021a \u0162 \u0166', // Þ Ť Ț Ţ Ŧ
|
||||
u : '\u0173 \u0171 \u016f \u016b \u00fc \u00fb \u00fa \u00f9 \u0169 \u016d', // ų ű ů ū ü û ú ù ũ ŭ
|
||||
U : '\u0172 \u0170 \u016e \u016a \u00dc \u00db \u00da \u00d9 \u0168 \u016c', // Ų Ű Ů Ū Ü Û Ú Ù Ũ Ŭ
|
||||
w : '\u0175', // ŵ
|
||||
W : '\u0174', // Ŵ
|
||||
y : '\u00fd', // ý
|
||||
Y : '\u00dd', // Ý
|
||||
z : '\u017a \u017c \u017e', // ź ż ž
|
||||
Z : '\u0179 \u017b \u017d', // Ź Ż Ž
|
||||
'!' : '\u00a1', // ¡
|
||||
'$' : '\u20ac \u00a3 \u00a4 \u00a5 \u00a2 \u20a1 \u20b1 \u20a9 \u20b9 \u20aa \u20ad \u20ae \u20a6 \u20a4', // €£¤¥¢₡₱₩₹₪₭₮₦₤
|
||||
'?' : '\u00bf', // ¿
|
||||
"'" : '\u3008 \u300c \u300e \u201c', // 〈 「 『 “
|
||||
'"' : '\u3009 \u300d \u300f \u201d', // 〉 」 』 ”
|
||||
'(' : '\u300a \u3010 \u3014', // « 【 〔
|
||||
')' : '\u300b \u3011 \u3015' // » 】 〕
|
||||
}, $keyboard.altKeys );
|
||||
|
||||
$.fn.addAltKeyPopup = function( options ) {
|
||||
//Set the default values, use comma to separate the settings, example:
|
||||
var defaults = {
|
||||
// time to hold down a button in ms to trigger a popup
|
||||
holdTime : 500,
|
||||
// event triggered when popup is visible
|
||||
popupVisible : 'popup-visible'
|
||||
};
|
||||
return this.each( function() {
|
||||
// make sure a keyboard is attached
|
||||
var namespace,
|
||||
base = $( this ).data( 'keyboard' );
|
||||
if (!base) { return; }
|
||||
|
||||
// variables
|
||||
base.altkeypopup_options = $.extend( {}, defaults, options );
|
||||
namespace = base.altkeypopup_namespace = base.namespace + 'AltKeyPopup';
|
||||
base.extensionNamespace.push( namespace );
|
||||
|
||||
base.altkeypopup_setup = function() {
|
||||
var timer,
|
||||
start = 'mousedown touchstart '.split( ' ' ).join( namespace + ' ' ),
|
||||
end = 'mouseup touchend touchcancel '.split( ' ' ).join( namespace + ' ' );
|
||||
|
||||
// force disable repeat keys
|
||||
base.options.repeatRate = 0;
|
||||
|
||||
// add hold key functionality for popups
|
||||
base.$allKeys
|
||||
.bind( start, function() {
|
||||
clearTimeout( timer );
|
||||
var $key = $( this ),
|
||||
key = $key.attr( 'data-action' ) || '';
|
||||
if ( key in $keyboard.altKeys ) {
|
||||
timer = setTimeout( function() {
|
||||
base.altKeyPopup_popup( key, $key );
|
||||
}, base.altkeypopup_options.holdTime );
|
||||
}
|
||||
})
|
||||
.bind( end, function() {
|
||||
clearTimeout( timer );
|
||||
});
|
||||
};
|
||||
|
||||
base.altKeyPopup_popup = function( key, $key ) {
|
||||
var keys, $keys, positionHoriz, positionVert, top,
|
||||
kbcss = $keyboard.css,
|
||||
kbWidth = base.$keyboard.outerWidth(),
|
||||
kbHeight = base.$keyboard.outerHeight();
|
||||
// overlay keyboard
|
||||
base.altKeyPopup_$overlay = $( '<div class="' + kbcss.altKeyOverlay + '" />' )
|
||||
.css({
|
||||
width : kbWidth,
|
||||
height: kbHeight
|
||||
})
|
||||
.appendTo( base.$keyboard )
|
||||
.bind( 'click touchstart', function() {
|
||||
base.altKeyPopup_$overlay.remove();
|
||||
});
|
||||
|
||||
// remove character added when key was initially pressed, unless it was a backspace key
|
||||
if ( key !== 'bksp' ) {
|
||||
$keyboard.keyaction.bksp( base );
|
||||
}
|
||||
|
||||
// make popup; use the same classes as the keyboard container
|
||||
$keys = $( '<div class="' + kbcss.altKeyPopup + ' ' + base.options.css.container + '" />' );
|
||||
keys = $keyboard.altKeys[ key ].split( /\s+/ );
|
||||
// make popup keys
|
||||
base.buildRow( $keys, 0, keys, [] );
|
||||
// add popup & add bindings
|
||||
$keys
|
||||
.appendTo( base.altKeyPopup_$overlay )
|
||||
.children()
|
||||
.bind( 'mousedown touchstart', function( event ) {
|
||||
var action = $( this ).attr( 'data-action' );
|
||||
// make action keys work in popup
|
||||
if ( action in $keyboard.keyaction && $.isFunction($keyboard.keyaction[ action ] ) ) {
|
||||
$keyboard.keyaction[ action ]( base, this, event );
|
||||
} else {
|
||||
base.insertText( action );
|
||||
}
|
||||
base.altKeyPopup_$overlay.remove();
|
||||
})
|
||||
.bind( 'mouseover mouseleave', function( event ){
|
||||
$( this ).toggleClass( base.options.css.buttonHover, event.type === 'mouseover' );
|
||||
});
|
||||
|
||||
// position popup within $keyboard container
|
||||
positionHoriz = $key.position().left - ( $keys.outerWidth() / 2 ) + ( $key.outerWidth() / 2 );
|
||||
if ( positionHoriz + $keys.outerWidth() > kbWidth ) {
|
||||
positionHoriz = kbWidth - $keys.outerWidth();
|
||||
if ( positionHoriz < 0 ) {
|
||||
$keys.css({
|
||||
width : kbWidth,
|
||||
height : 'auto'
|
||||
});
|
||||
}
|
||||
}
|
||||
positionVert = $key.position().top - $key.outerHeight() - 5;
|
||||
top = base.$keyboard.find( '.' + kbcss.keySet ).position().top;
|
||||
if ( positionVert + $keys.outerHeight() > kbHeight ) {
|
||||
positionVert = kbHeight - $keys.outerHeight();
|
||||
if ( positionVert < top ) {
|
||||
$keys.css({
|
||||
height : kbHeight - top,
|
||||
width : 'auto'
|
||||
});
|
||||
}
|
||||
}
|
||||
$keys.css({
|
||||
position : 'relative',
|
||||
top : positionVert < top ? top : positionVert,
|
||||
left : positionHoriz < 0 ? 0 : positionHoriz
|
||||
});
|
||||
// trigger popup visible event
|
||||
base.$el.trigger( base.altkeypopup_options.popupVisible, [ base ] );
|
||||
};
|
||||
|
||||
// visible event is fired before this extension is initialized, so check!
|
||||
if ( base.options.alwaysOpen && base.isVisible() ) {
|
||||
base.altkeypopup_setup();
|
||||
}
|
||||
// setup altkey popup
|
||||
base.$el
|
||||
.unbind( $keyboard.events.kbBeforeVisible + namespace )
|
||||
.bind( $keyboard.events.kbBeforeVisible + namespace, function() {
|
||||
base.altkeypopup_setup();
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
|
@ -1,147 +0,0 @@
|
|||
/*! jQuery UI Virtual Keyboard Autocomplete v1.9.2 *//*
|
||||
* for Keyboard v1.18+ only (8/17/2015)
|
||||
*
|
||||
* By Rob Garrison (aka Mottie & Fudgey)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* Use this extension with the Virtual Keyboard to get
|
||||
* the jQuery UI Autocomplete widget to work seamlessly
|
||||
*
|
||||
* Requires:
|
||||
* jQuery
|
||||
* jQuery UI & css
|
||||
* Keyboard plugin : https://github.com/Mottie/Keyboard
|
||||
*
|
||||
* Setup:
|
||||
* $('.ui-keyboard-input')
|
||||
* .keyboard(options)
|
||||
* .autocomplete(options)
|
||||
* .addAutoComplete();
|
||||
*
|
||||
* // or if targeting a specific keyboard
|
||||
* $('#keyboard1')
|
||||
* .keyboard(options) // keyboard plugin
|
||||
* .autocomplete(options) // jQuery UI autocomplete
|
||||
* .addAutoComplete(); // this keyboard extension
|
||||
*
|
||||
*/
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global require:false, define:false, module:false */
|
||||
;(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
'use strict';
|
||||
$.fn.addAutocomplete = function(options){
|
||||
var defaults = {
|
||||
position : {
|
||||
of : null,
|
||||
my : 'right top',
|
||||
at : 'left top',
|
||||
collision: 'flip'
|
||||
}
|
||||
};
|
||||
|
||||
return this.each(function(){
|
||||
// make sure a keyboard is attached
|
||||
var o, base = $(this).data('keyboard');
|
||||
if (!base) { return; }
|
||||
|
||||
base.autocomplete_namespace = base.namespace + 'Autocomplete';
|
||||
base.extensionNamespace.push( base.autocomplete_namespace );
|
||||
|
||||
// Setup
|
||||
base.autocomplete_init = function(){
|
||||
|
||||
// variables
|
||||
o = base.autocomplete_options = $.extend( true, {}, defaults, options );
|
||||
|
||||
// visible event is fired before this extension is initialized, so check!
|
||||
if (base.options.alwaysOpen && base.isVisible()) {
|
||||
base.autocomplete_setup();
|
||||
}
|
||||
|
||||
base.$el
|
||||
.unbind(base.autocomplete_namespace)
|
||||
.bind($.keyboard.events.kbVisible + base.autocomplete_namespace,function(){
|
||||
base.autocomplete_setup();
|
||||
})
|
||||
.bind($.keyboard.events.kbChange + base.autocomplete_namespace,function(){
|
||||
if (base.hasAutocomplete && base.isVisible()) {
|
||||
base.$el
|
||||
.val(base.$preview.val())
|
||||
.trigger('keydown.autocomplete');
|
||||
}
|
||||
})
|
||||
.bind($.keyboard.events.kbHidden + base.autocomplete_namespace, function(){
|
||||
base.$el.autocomplete('close');
|
||||
})
|
||||
.bind('autocompleteopen' + base.autocomplete_namespace, function() {
|
||||
if (base.hasAutocomplete){
|
||||
// default to $keyboard if no position.of defined
|
||||
var position = $.extend( {}, o.position );
|
||||
// refresh base.$keyboard (it gets destroyed after use); fixes #382
|
||||
position.of = position.of || base.$keyboard;
|
||||
// reposition autocomplete window next to the keyboard
|
||||
base.$autocomplete.menu.element.position( position );
|
||||
}
|
||||
})
|
||||
.bind('autocompleteselect' + base.autocomplete_namespace, function(e, ui){
|
||||
var v = ui.item && ui.item.value || '';
|
||||
if (base.hasAutocomplete && v !== ''){
|
||||
base.$preview
|
||||
.val( v )
|
||||
.focus();
|
||||
// see issue #95 - thanks banku!
|
||||
base.last.start = v.length;
|
||||
base.last.end = v.length;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// set up after keyboard is visible
|
||||
base.autocomplete_setup = function(){
|
||||
// look for autocomplete
|
||||
base.$autocomplete = base.$el.data('autocomplete') || base.$el.data('uiAutocomplete') || base.$el.data('ui-autocomplete');
|
||||
base.hasAutocomplete = (typeof(base.$autocomplete) === 'undefined') ? false : (base.$autocomplete.options.disabled) ? false : true;
|
||||
// only bind to keydown once
|
||||
if (base.hasAutocomplete) {
|
||||
base.$preview.bind('keydown' + base.autocomplete_namespace, function(e){
|
||||
// send keys to the autocomplete widget (arrow, pageup/down, etc)
|
||||
base.$el.val( base.$preview.val() ).triggerHandler(e);
|
||||
});
|
||||
base.$allKeys.bind('mouseup mousedown mouseleave touchstart touchend touchcancel '.split(' ').join(base.autocomplete_namespace + ' '),function(event){
|
||||
clearTimeout( base.$autocomplete.searching );
|
||||
var evt = event;
|
||||
base.$autocomplete.searching = setTimeout(function() {
|
||||
// only search if the value has changed
|
||||
if ( base.$autocomplete.term !== base.$autocomplete.element.val() ) {
|
||||
base.$autocomplete.selectedItem = null;
|
||||
base.$autocomplete.search( null, evt );
|
||||
}
|
||||
}, base.$autocomplete.options.delay );
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
base.origEscClose = base.escClose;
|
||||
|
||||
// replace original function with this one
|
||||
base.escClose = function(e){
|
||||
// prevent selecting an item in autocomplete from closing keyboard
|
||||
if ( base.hasAutocomplete && (e.target.id === 'ui-active-menuitem' || $(e.target).closest('ul').hasClass('ui-autocomplete')) ) { return; }
|
||||
base.origEscClose(e);
|
||||
};
|
||||
|
||||
base.autocomplete_init();
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
|
@ -1,197 +0,0 @@
|
|||
/*! jQuery UI Virtual Keyboard Virtual Caret v1.1.3 (beta) *//*
|
||||
* for Keyboard v1.18+ only (9/24/2015)
|
||||
* modified from https://github.com/component/textarea-caret-position
|
||||
*
|
||||
* By Rob Garrison (aka Mottie)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* CSS changes
|
||||
* NOTE: caret margin-top => is added to the caret height (top & bottom)
|
||||
* .ui-keyboard-preview-wrapper { position: relative; overflow: hidden; }
|
||||
* .ui-keyboard-caret { background: red; width: 1px; margin-top: 3px; }
|
||||
*/
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global require:false, define:false, module:false */
|
||||
;( function( factory ) {
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
define( [ 'jquery' ], factory );
|
||||
} else if ( typeof module === 'object' && typeof module.exports === 'object' ) {
|
||||
module.exports = factory( require( 'jquery' ) );
|
||||
} else {
|
||||
factory( jQuery );
|
||||
}
|
||||
}( function( $ ) {
|
||||
'use strict';
|
||||
var $keyboard = $.keyboard;
|
||||
|
||||
$keyboard.firefox = typeof window.mozInnerScreenX !== 'undefined';
|
||||
|
||||
$.extend( $keyboard.css, {
|
||||
caret : 'ui-keyboard-caret'
|
||||
});
|
||||
|
||||
$.fn.addCaret = function( options ) {
|
||||
var defaults = {
|
||||
caretClass : '',
|
||||
// *** for future use ***
|
||||
// data-attribute containing the character(s) next to the caret
|
||||
charAttr : 'data-character',
|
||||
// # character(s) next to the caret (can be negative for RTL)
|
||||
charIndex : 1,
|
||||
offsetX : 0,
|
||||
offsetY : 0,
|
||||
adjustHt : 0
|
||||
};
|
||||
return this.each( function() {
|
||||
// make sure a keyboard is attached
|
||||
var o, namespace,
|
||||
kbevents = $keyboard.events,
|
||||
base = $( this ).data( 'keyboard' );
|
||||
if ( !base ) { return; }
|
||||
|
||||
// variables
|
||||
o = base.caret_options = $.extend( {}, defaults, options );
|
||||
namespace = base.caret_namespace = base.namespace + 'caret';
|
||||
base.extensionNamespace.push( namespace );
|
||||
|
||||
// modified from https://github.com/component/textarea-caret-position
|
||||
// The properties that we copy into a mirrored div.
|
||||
// Note that some browsers, such as Firefox,
|
||||
// do not concatenate properties, i.e. padding-top, bottom etc. -> padding,
|
||||
// so we have to do every single property specifically.
|
||||
base.textareaCaretProperties = [
|
||||
'direction', 'boxSizing', 'width', 'height', 'overflowX', 'overflowY',
|
||||
'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'borderStyle',
|
||||
'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',
|
||||
'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust',
|
||||
'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration',
|
||||
'letterSpacing', 'wordSpacing', 'tabSize', 'MozTabSize'
|
||||
];
|
||||
|
||||
base.caret_setup = function() {
|
||||
var events = 'keyup keypress mouseup mouseleave '.split( ' ' ).join( namespace + ' ' ),
|
||||
style = 'position:absolute;visibility:hidden;top:-9999em;left:-9999em;' +
|
||||
'white-space:pre-wrap;' +
|
||||
( base.preview.nodeName === 'INPUT' ? '' : 'word-wrap:break-word;' );
|
||||
// add mirrored div
|
||||
base.caret_$div = $( '<div class="ui-keyboard-mirror-div" style="' + style + '">' )
|
||||
.appendTo( base.$keyboard );
|
||||
|
||||
// remove caret, just-in-case
|
||||
if (base.$caret) { base.$caret.remove(); }
|
||||
base.$caret = $( '<div class="ui-keyboard-caret ' + o.caretClass + '" style="position:absolute;">' )
|
||||
.insertAfter( base.$preview );
|
||||
|
||||
base.$el
|
||||
.unbind( kbevents.kbChange + namespace )
|
||||
.bind( kbevents.kbChange + namespace, function() {
|
||||
base.findCaretPos();
|
||||
});
|
||||
base.$preview
|
||||
.unbind( events )
|
||||
.bind( events, function() {
|
||||
base.findCaretPos();
|
||||
});
|
||||
};
|
||||
|
||||
// getCaretCoordinatesFn = function (element, position, recalculate) {
|
||||
base.findCaretPos = function() {
|
||||
if ( !base.caret_$div ) { return; }
|
||||
var style, computed, margin, pos, position, txt, span, offset,
|
||||
element = base.preview,
|
||||
isInput = element.nodeName === 'INPUT',
|
||||
div = base.caret_$div[0];
|
||||
|
||||
style = div.style;
|
||||
// getComputedStyle with null - fixes #384
|
||||
computed = window.getComputedStyle ? getComputedStyle( element, null ) : element.currentStyle;
|
||||
// get caret position based on text-direction
|
||||
pos = $keyboard.caret( base.$preview );
|
||||
position = Math[ computed.direction === 'ltr' ? 'max' : 'min' ]( pos.start, pos.end );
|
||||
|
||||
// transfer the element's properties to the div
|
||||
base.textareaCaretProperties.forEach(function ( prop ) {
|
||||
style[ prop ] = computed[ prop ];
|
||||
});
|
||||
|
||||
if ( $keyboard.firefox ) {
|
||||
// Firefox adds 2 pixels to the padding - https://bugzilla.mozilla.org/show_bug.cgi?id=753662
|
||||
style.width = parseInt( computed.width, 10 ) - 2 + 'px';
|
||||
// Firefox lies about the overflow property for textareas:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=984275
|
||||
if ( element.scrollHeight > parseInt( computed.height, 10 ) ) {
|
||||
style.overflowY = 'scroll';
|
||||
}
|
||||
} else {
|
||||
// for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
|
||||
// style.overflow = 'hidden';
|
||||
style.width = parseInt( isInput ? element.scrollWidth : computed.width, 10 ) +
|
||||
// add 50 extra px if it's an input to prevent wrap
|
||||
( isInput ? 50 : 0 ) + 'px';
|
||||
}
|
||||
|
||||
div.textContent = element.value.substring( 0, position );
|
||||
// the second special handling for input type="text" vs textarea:
|
||||
// spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
|
||||
if ( element.nodeName === 'INPUT' ) {
|
||||
div.textContent = div.textContent.replace( /\x20/g, '\xa0' );
|
||||
}
|
||||
|
||||
span = document.createElement( 'span' );
|
||||
// Wrapping must be replicated *exactly*, including when a long word gets
|
||||
// onto the next line, with whitespace at the end of the line before (#7).
|
||||
// The *only* reliable way to do that is to copy the *entire* rest of the
|
||||
// textarea's content into the <span> created at the caret position.
|
||||
// for inputs, just '.' would be enough, but why bother?
|
||||
// || because a completely empty faux span doesn't render at all
|
||||
span.textContent = element.value.substring( position ) || '.';
|
||||
div.appendChild( span );
|
||||
|
||||
offset = $(span).position();
|
||||
base.caretPos = {
|
||||
top: offset.top + parseInt( computed.borderTopWidth, 10 ) + o.offsetY,
|
||||
left: offset.left + parseInt( computed.borderLeftWidth, 10 ) + o.offsetX
|
||||
};
|
||||
|
||||
// make caret height = font-size + any margin-top x2 added by the css
|
||||
margin = parseInt( base.$caret.css( 'margin-top' ), 10 );
|
||||
style = Math.round( parseFloat( base.$preview.css( 'font-size' ) ) + margin * 2 ) + o.adjustHt;
|
||||
offset = base.$preview.position();
|
||||
|
||||
base.$caret.css({
|
||||
top: offset.top - element.scrollTop + base.caretPos.top - margin,
|
||||
left: offset.left - element.scrollLeft + base.caretPos.left,
|
||||
height: style
|
||||
});
|
||||
txt = element.value.substring( position, position + o.charIndex ).replace(/\s/, '\xa0' ) || '\xa0';
|
||||
base.$caret.attr( o.charAttr, txt );
|
||||
};
|
||||
|
||||
// setup caret when keyboard is visible
|
||||
base.$el
|
||||
.unbind( namespace )
|
||||
.bind( kbevents.kbBeforeVisible + namespace, function() {
|
||||
base.caret_setup();
|
||||
})
|
||||
.bind( kbevents.kbVisible + namespace, function() {
|
||||
base.findCaretPos();
|
||||
})
|
||||
.bind( kbevents.kbHidden + namespace, function() {
|
||||
// unbind events in case usePreview: false; see #376
|
||||
var events = 'keyup keypress mouseup mouseleave '.split( ' ' ).join( namespace + ' ' );
|
||||
base.$preview.unbind( events );
|
||||
base.$caret.remove();
|
||||
base.$caret = null;
|
||||
base.caret_$div = null;
|
||||
});
|
||||
|
||||
// visible event is fired before this extension is initialized, so check!
|
||||
if ( base.options.alwaysOpen && base.isVisible() ) {
|
||||
base.caret_setup();
|
||||
base.findCaretPos();
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
|
@ -1,119 +0,0 @@
|
|||
/*! jQuery UI Virtual Keyboard Extender v1.0.1 *//*
|
||||
* for Keyboard v1.18+ only (7/7/2015)
|
||||
*
|
||||
* By Rob Garrison (aka Mottie)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
*/
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global require:false, define:false, module:false */
|
||||
;(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
'use strict';
|
||||
|
||||
var $keyboard = $.keyboard;
|
||||
|
||||
$.extend( $keyboard.css, {
|
||||
extender : 'ui-keyboard-extender'
|
||||
});
|
||||
|
||||
$.extend( $keyboard.layouts, {
|
||||
'numpad' : {
|
||||
'normal' : [
|
||||
'{clear} / * -',
|
||||
'7 8 9 +',
|
||||
'4 5 6 %',
|
||||
'1 2 3 =',
|
||||
'0 {dec} {left} {right}'
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
// add {extender} keyaction
|
||||
$.extend( $keyboard.keyaction, {
|
||||
extender: function( base, el ) {
|
||||
base.extender_toggle();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.addExtender = function(options) {
|
||||
//Set the default values, use comma to separate the settings, example:
|
||||
var defaults = {
|
||||
layout : 'numpad',
|
||||
showing : false,
|
||||
reposition : true
|
||||
};
|
||||
return this.each( function() {
|
||||
// make sure a keyboard is attached
|
||||
var o, base = $( this ).data( 'keyboard' );
|
||||
if (!base) { return; }
|
||||
|
||||
// variables
|
||||
o = base.extender_options = $.extend( {}, defaults, options );
|
||||
$.extend( true, $keyboard.language.en, {
|
||||
display : {
|
||||
'extender' : ' '
|
||||
}
|
||||
});
|
||||
base.extender_namespace = base.namespace + 'extender';
|
||||
base.extensionNamespace.push( base.extender_namespace );
|
||||
|
||||
base.extender_setup = function() {
|
||||
var $kb,
|
||||
layout = o.layout;
|
||||
if ( typeof $keyboard.builtLayouts[ layout ] === 'undefined' ) {
|
||||
base.buildKeyboard( layout );
|
||||
}
|
||||
$kb = $keyboard.builtLayouts[ layout ].$keyboard.find( '.' + $keyboard.css.keySet + '-normal' ).clone();
|
||||
$kb
|
||||
.removeClass()
|
||||
.removeAttr('name')
|
||||
.addClass( $keyboard.css.extender )
|
||||
.toggle( o.showing )
|
||||
.children('button')
|
||||
.removeAttr('data-pos');
|
||||
base.$keyboard.append( $kb );
|
||||
base.extender_toggle( base.extender_options.showing );
|
||||
base.bindKeys();
|
||||
};
|
||||
|
||||
base.extender_toggle = function(set) {
|
||||
base.extender_options.showing = typeof set === 'undefined' ? !base.extender_options.showing : set;
|
||||
base.$keyboard
|
||||
.find( 'div.' + $keyboard.css.extender )
|
||||
.toggle( base.extender_options.showing )
|
||||
.end()
|
||||
.find( '.' + $keyboard.css.keySet )
|
||||
.css('float', base.extender_options.showing ? 'left' : 'none')
|
||||
.end()
|
||||
.find( 'button.' + $keyboard.css.extender )
|
||||
.toggleClass( base.options.css.buttonActive, base.extender_options.showing );
|
||||
// force keyboard reposition
|
||||
if (base.extender_options.reposition) {
|
||||
$(window).trigger('resize');
|
||||
}
|
||||
};
|
||||
|
||||
// visible event is fired before this extension is initialized, so check!
|
||||
if (base.options.alwaysOpen && base.isVisible()) {
|
||||
base.extender_setup();
|
||||
}
|
||||
// setup extender
|
||||
base.$el
|
||||
.unbind( $keyboard.events.kbBeforeVisible + base.extender_namespace )
|
||||
.bind( $keyboard.events.kbBeforeVisible + base.extender_namespace, function() {
|
||||
base.extender_setup();
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
|
@ -1,188 +0,0 @@
|
|||
/*! jQuery UI Virtual Keyboard for jQuery Mobile Themes v1.4.1 *//*
|
||||
* for Keyboard v1.18+ (updated 7/7/2015)
|
||||
*
|
||||
* By Rob Garrison (aka Mottie & Fudgey)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* Use this extension with the Virtual Keyboard to apply
|
||||
* the necessary themes to make the keyboard compatible with
|
||||
* jQuery Mobile themes
|
||||
*
|
||||
* Requires:
|
||||
* jQuery - http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js
|
||||
* jQuery Mobile - http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js
|
||||
* jQuery Mobile themes - http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css
|
||||
*
|
||||
* Setup:
|
||||
* $('.ui-keyboard-input')
|
||||
* .keyboard(options)
|
||||
* .addMobile(mobile-options);
|
||||
*
|
||||
* // or if targeting a specific keyboard
|
||||
* $('#keyboard1')
|
||||
* .keyboard(options) // keyboard plugin
|
||||
* .addMobile(mobile-options); // this keyboard extension
|
||||
*
|
||||
*/
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global require:false, define:false, module:false */
|
||||
;(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
$.fn.addMobile = function(options){
|
||||
|
||||
var o, defaults = {
|
||||
// keyboard wrapper theme
|
||||
container : { theme:'b', cssClass:'ui-body' },
|
||||
// keyboard duplicate input
|
||||
input : { theme:'b', cssClass:'' },
|
||||
// theme added to all regular buttons
|
||||
buttonMarkup : { theme:'b', cssClass:'ui-btn', shadow:'true', corners:'true' },
|
||||
// theme added to all buttons when they are being hovered
|
||||
buttonHover : { theme:'b', cssClass:'ui-btn-hover' },
|
||||
// theme added to action buttons (e.g. tab, shift, accept, cancel);
|
||||
// parameters here will override the settings in the buttonMarkup
|
||||
buttonAction : { theme:'b', cssClass:'ui-btn-active' },
|
||||
// theme added to button when it is active (e.g. shift is down)
|
||||
// All extra parameters will be ignored
|
||||
buttonActive : { theme:'b', cssClass:'ui-btn-active' },
|
||||
// if more than 3 mobile themes are used, add them here
|
||||
allThemes : 'a b c'
|
||||
};
|
||||
|
||||
return this.each(function(){
|
||||
var base = $(this).data('keyboard');
|
||||
|
||||
// Stop if no keyboard attached or if jQuery Mobile isn't loaded
|
||||
if (!base || typeof($.fn.textinput) === 'undefined') { return; }
|
||||
|
||||
base.mobile_options = o = $.extend(true, {}, defaults, options);
|
||||
// create a list of theme class names to remove
|
||||
base.mobile_themes = $.trim(
|
||||
(' ' + o.allThemes).split(' ').join(' ' + o.buttonMarkup.cssClass + '-') +
|
||||
(' ' + o.allThemes).split(' ').join(' ' + o.buttonAction.cssClass + '-') +
|
||||
(' ' + o.allThemes).split(' ').join(' ' + o.buttonActive.cssClass + '-')
|
||||
);
|
||||
|
||||
// save original action class because it gets removed when this theme switches swatches
|
||||
if (typeof base.options.mobile_savedActiveClass === 'undefined') {
|
||||
base.options.mobile_savedActiveClass = '' + base.options.css.buttonActive;
|
||||
}
|
||||
|
||||
// Setup
|
||||
base.mobile_init = function() {
|
||||
|
||||
var namespace = base.namespace + 'Mobile';
|
||||
|
||||
// Add theme to input - if not already done through the markup
|
||||
$('.' + $.keyboard.css.input).textinput();
|
||||
|
||||
// visible event is fired before this extension is initialized, so check!
|
||||
if (base.options.alwaysOpen && base.isVisible) {
|
||||
base.mobile_setup();
|
||||
}
|
||||
|
||||
base.extensionNamespace.push( namespace );
|
||||
|
||||
// Setup mobile theme on keyboard once it is visible.
|
||||
// Note: There is a 10ms delay after the keyboard is displayed before it actually fires 'visible.keyboard'.
|
||||
// Since we are restyling here, the user will experience FlashOfUnstyledContent (FOUC).
|
||||
// This is avoided by first setting the visibility to hidden, then after the mobile styles are applied we
|
||||
// set it visible.
|
||||
base.$el
|
||||
.unbind(namespace)
|
||||
.bind($.keyboard.events.kbBeforeVisible + namespace, function() {
|
||||
if ( base && base.el.active && base.$keyboard.length ) {
|
||||
base.$keyboard.css('visibility', 'hidden');
|
||||
}
|
||||
})
|
||||
.bind($.keyboard.events.kbVisible + namespace, function() {
|
||||
if ( base && base.el.active && base.$keyboard.length ) {
|
||||
base.mobile_setup();
|
||||
base.$keyboard.css('visibility', 'visible');
|
||||
base.$preview.focus();
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
base.mobile_setup = function(){
|
||||
var p,
|
||||
kbcss = $.keyboard.css,
|
||||
opts = base.options,
|
||||
themes = base.mobile_themes;
|
||||
|
||||
base.mobile_$actionKeys = base.$keyboard.find('.' + base.options.css.buttonAction);
|
||||
|
||||
opts.css.buttonActive = opts.mobile_savedActiveClass + ' ' + base.modOptions(o.buttonActive, o.buttonMarkup);
|
||||
|
||||
base.$keyboard
|
||||
// 'ui-body ui-body-a' classes to apply swatch theme
|
||||
.addClass( base.modOptions(o.container, o.container) )
|
||||
// preview input
|
||||
.find('.' + kbcss.preview)
|
||||
// removing 'ui-widget-content' will prevent jQuery UI theme from applying to the keyboard
|
||||
.removeClass('ui-widget ui-widget-content')
|
||||
.addClass( base.modOptions(o.input, o.input) ).end()
|
||||
// apply jQuery Mobile button markup
|
||||
// removed call to jQuery Mobile buttonMarkup function; replaced with base.modOptions
|
||||
.find('button')
|
||||
.removeClass( $.trim('ui-corner-all ui-state-default ' + themes) )
|
||||
.addClass( base.modOptions(o.buttonMarkup, o.buttonMarkup) )
|
||||
.not( base.mobile_$actionKeys )
|
||||
.hover(function(){
|
||||
$(this)
|
||||
.removeClass( themes )
|
||||
.addClass( base.modOptions(o.buttonHover, o.buttonMarkup) );
|
||||
},function(){
|
||||
$(this)
|
||||
.removeClass( themes + ' ' + o.buttonHover.cssClass )
|
||||
.addClass( base.modOptions(o.buttonMarkup, o.buttonMarkup) );
|
||||
});
|
||||
|
||||
base.mobile_$actionKeys
|
||||
.removeClass( themes )
|
||||
.addClass( base.modOptions(o.buttonAction, o.buttonMarkup) );
|
||||
|
||||
// update keyboard width if preview is showing... after applying mobile theme
|
||||
if (base.msie && base.$preview[0] !== base.el) {
|
||||
base.$preview.hide();
|
||||
base.$keyboard.css('width','');
|
||||
base.width = base.$keyboard.outerWidth();
|
||||
// add about 1em to input width for extra padding
|
||||
base.$keyboard.width(base.width + parseInt(base.$preview.css('fontSize'),10));
|
||||
base.$preview.width(base.width);
|
||||
base.$preview.show();
|
||||
}
|
||||
|
||||
// adjust keyboard position after applying mobile theme
|
||||
if ($.ui && $.ui.position) {
|
||||
p = opts.position;
|
||||
p.of = p.of || base.$el.data('keyboardPosition') || base.$el;
|
||||
p.collision = p.collision || 'flipfit flipfit';
|
||||
base.$keyboard.position(p);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
base.modOptions = function(t, btn){
|
||||
var css = ' ' + ( t.cssClass || '' );
|
||||
// Using this instead of the jQuery Mobile buttonMarkup because it is expecting <a>'s instead of <button>
|
||||
// theme:'a', shadow:'true', inline:'true', corners:'false'
|
||||
return css + ' ' + (btn && btn.cssClass ? btn.cssClass + '-' + (t.theme || '') : '') +
|
||||
(t.shadow == 'true' ? ' ui-shadow' : '') +
|
||||
(t.corners == 'true' ? ' ui-corner-all' : '');
|
||||
};
|
||||
|
||||
base.mobile_init();
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
|
@ -1,218 +0,0 @@
|
|||
/*! jQuery UI Virtual Keyboard Navigation v1.6.1 *//*
|
||||
* for Keyboard v1.18+ only (updated 7/7/2015)
|
||||
*
|
||||
* By Rob Garrison (aka Mottie & Fudgey)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* Use this extension with the Virtual Keyboard to navigate
|
||||
* the virtual keyboard keys using the arrow, page, home and end keys
|
||||
* Using this extension WILL prevent keyboard navigation inside of all
|
||||
* input and textareas
|
||||
*
|
||||
* Requires:
|
||||
* jQuery
|
||||
* Keyboard plugin : https://github.com/Mottie/Keyboard
|
||||
*
|
||||
* Setup:
|
||||
* $('.ui-keyboard-input')
|
||||
* .keyboard(options)
|
||||
* .addNavigation();
|
||||
*
|
||||
* // or if targeting a specific keyboard
|
||||
* $('#keyboard1')
|
||||
* .keyboard(options) // keyboard plugin
|
||||
* .addNavigation(); // this keyboard extension
|
||||
*
|
||||
*/
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global require:false, define:false, module:false */
|
||||
;(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
'use strict';
|
||||
$.keyboard = $.keyboard || {};
|
||||
|
||||
$.keyboard.navigationKeys = {
|
||||
// all keys
|
||||
toggle : 112, // toggle key; F1 = 112 (event.which value for function 1 key)
|
||||
enter : 13,
|
||||
pageup : 33,
|
||||
pagedown : 34,
|
||||
end : 35,
|
||||
home : 36,
|
||||
left : 37,
|
||||
up : 38,
|
||||
right : 39,
|
||||
down : 40,
|
||||
// move caret WITH navigate toggle active
|
||||
caretrt : 45, // Insert key
|
||||
caretlt : 46, // delete key
|
||||
|
||||
// ** custom navigationKeys functions **
|
||||
// move caret without navigate toggle active
|
||||
caretright : function(kb){
|
||||
$.keyboard.keyaction.right(kb);
|
||||
},
|
||||
caretleft : function(kb){
|
||||
$.keyboard.keyaction.left(kb);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$.fn.addNavigation = function(options){
|
||||
return this.each(function(){
|
||||
// make sure a keyboard is attached
|
||||
var o, k,
|
||||
base = $(this).data('keyboard'),
|
||||
opts = base.options,
|
||||
defaults = {
|
||||
position : [0,0], // set start position [row-number, key-index]
|
||||
toggleMode : false, // true = navigate the virtual keyboard, false = navigate in input/textarea
|
||||
focusClass : 'hasFocus',// css class added when toggle mode is on
|
||||
toggleKey : null // defaults to $.keyboard.navigationKeys.toggle value
|
||||
},
|
||||
kbevents = $.keyboard.events;
|
||||
if (!base) { return; }
|
||||
|
||||
base.navigation_options = o = $.extend({}, defaults, options);
|
||||
base.navigation_keys = k = $.extend({}, $.keyboard.navigationKeys);
|
||||
base.navigation_namespace = base.namespace + 'Nav';
|
||||
base.extensionNamespace.push( base.navigation_namespace );
|
||||
|
||||
// save navigation settings - disabled when the toggled
|
||||
base.saveNav = [ base.options.tabNavigation, base.options.enterNavigation ];
|
||||
base.allNavKeys = $.map(k, function(v,i){ return v; });
|
||||
|
||||
// Setup
|
||||
base.navigation_init = function(){
|
||||
var kbcss = $.keyboard.css;
|
||||
base.$keyboard.toggleClass(o.focusClass, o.toggleMode)
|
||||
.find('.' + kbcss.keySet + ':visible')
|
||||
.find('.' + kbcss.keyButton + '[data-pos="' + o.position[0] + ',' + o.position[1] + '"]')
|
||||
.addClass(opts.css.buttonHover);
|
||||
|
||||
base.$preview
|
||||
.unbind(base.navigation_namespace)
|
||||
.bind('keydown' + base.navigation_namespace,function(e){
|
||||
return base.checkKeys(e.which);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
base.checkKeys = function(key, disable){
|
||||
if (typeof(key) === "undefined") {
|
||||
return;
|
||||
}
|
||||
var k = base.navigation_keys,
|
||||
kbcss = $.keyboard.css;
|
||||
if (key === ( o.toggleKey || k.toggle ) || disable) {
|
||||
o.toggleMode = (disable) ? false : !o.toggleMode;
|
||||
base.options.tabNavigation = (o.toggleMode) ? false : base.saveNav[0];
|
||||
base.options.enterNavigation = (o.toggleMode) ? false : base.saveNav[1];
|
||||
}
|
||||
base.$keyboard.toggleClass(o.focusClass, o.toggleMode);
|
||||
if ( o.toggleMode && key === k.enter ) {
|
||||
base.$keyboard
|
||||
.find('.' + kbcss.keySet + ':visible')
|
||||
.find('.' + kbcss.keyButton + '[data-pos="' + o.position[0] + ',' + o.position[1] + '"]')
|
||||
.trigger(kbevents.kbRepeater);
|
||||
return false;
|
||||
}
|
||||
if ( o.toggleMode && $.inArray(key, base.allNavKeys) >= 0 ) {
|
||||
base.navigateKeys(key);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
base.navigateKeys = function(key, row, indx){
|
||||
indx = typeof indx === 'number' ? indx : o.position[1];
|
||||
row = typeof row === 'number' ? row : o.position[0];
|
||||
var kbcss = $.keyboard.css,
|
||||
vis = base.$keyboard.find('.' + kbcss.keySet + ':visible'),
|
||||
maxRow = vis.find('.' + kbcss.endRow).length - 1,
|
||||
maxIndx = vis.find('.' + kbcss.keyButton + '[data-pos^="' + row + ',"]').length - 1,
|
||||
p = base.last,
|
||||
l = base.$preview.val().length,
|
||||
k = base.navigation_keys;
|
||||
|
||||
switch(key){
|
||||
case k.pageup : row = 0; break; // pageUp
|
||||
case k.pagedown : row = maxRow; break; // pageDown
|
||||
case k.end : indx = maxIndx; break; // End
|
||||
case k.home : indx = 0; break; // Home
|
||||
case k.left : indx += (indx > 0) ? -1 : 0; break; // Left
|
||||
case k.up : row += (row > 0) ? -1 : 0; break; // Up
|
||||
case k.right : indx += 1; break; // Right
|
||||
case k.down : row += (row + 1 > maxRow) ? 0 : 1; break; // Down
|
||||
case k.caretrt : p.start++; break; // caret right
|
||||
case k.caretlt : p.start--; break; // caret left
|
||||
}
|
||||
|
||||
// move caret
|
||||
if (key === k.caretrt || key === k.caretlt) {
|
||||
p.start = p.start < 0 ? 0 : p.start > l ? l : p.start;
|
||||
base.last.start = base.last.end = p.end = p.start;
|
||||
$.keyboard.caret( base.$preview, base.last );
|
||||
}
|
||||
|
||||
// get max index of new row
|
||||
maxIndx = vis.find('.' + kbcss.keyButton + '[data-pos^="' + row + ',"]').length - 1;
|
||||
if (indx > maxIndx) { indx = maxIndx; }
|
||||
|
||||
vis.find('.' + opts.css.buttonHover).removeClass(opts.css.buttonHover);
|
||||
vis.find('.' + kbcss.keyButton + '[data-pos="' + row + ',' + indx + '"]').addClass(opts.css.buttonHover);
|
||||
o.position = [ row, indx ];
|
||||
};
|
||||
|
||||
// visible event is fired before this extension is initialized, so check!
|
||||
if (base.options.alwaysOpen && base.isVisible) {
|
||||
base.$keyboard.find('.' + opts.css.buttonHover).removeClass(opts.css.buttonHover);
|
||||
base.navigation_init();
|
||||
}
|
||||
// navigation bindings
|
||||
base.$el
|
||||
.unbind(base.navigation_namespace)
|
||||
.bind(kbevents.kbVisible, function(){
|
||||
base.$keyboard.find('.' + opts.css.buttonHover).removeClass(opts.css.buttonHover);
|
||||
base.navigation_init();
|
||||
})
|
||||
.bind(kbevents.kbInactive + ' ' + kbevents.kbHidden, function(e){
|
||||
base.checkKeys(e.which, true); // disable toggle mode & revert navigation options
|
||||
})
|
||||
.bind(kbevents.kbKeysetChange, function(){
|
||||
base.navigateKeys(null);
|
||||
})
|
||||
.bind('navigate navigateTo', function(e, row, indx){
|
||||
var key;
|
||||
// no row given, check if it's a navigation key or keyaction
|
||||
row = isNaN(row) ? row.toLowerCase() : row;
|
||||
if (row in base.navigation_keys) {
|
||||
key = base.navigation_keys[row];
|
||||
if (isNaN(key) && key in $.keyboard.keyaction) {
|
||||
// defined navigation_keys string name is a defined keyaction
|
||||
$.keyboard.keyaction[key]( base, this, e );
|
||||
} else if ($.isFunction(key)) {
|
||||
// custom function defined in navigation_keys
|
||||
key(base);
|
||||
} else {
|
||||
// key (e.which value) is defined in navigation_keys
|
||||
base.checkKeys(key);
|
||||
}
|
||||
} else if ( typeof row === 'string' && row in $.keyboard.keyaction ) {
|
||||
// navigate called directly with a keyaction name
|
||||
$.keyboard.keyaction[row]( base, this, e );
|
||||
} else {
|
||||
base.navigateKeys(null, row, indx);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
|
@ -1,91 +0,0 @@
|
|||
/*! jQuery UI Virtual Keyboard previewKeyset v1.1.1 *//*
|
||||
* for Keyboard v1.18+ only (updated 7/7/2015)
|
||||
*
|
||||
* By Rob Garrison (aka Mottie & Fudgey)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* Use this extension with the Virtual Keyboard to add a preview
|
||||
* of other keysets to the main keyboard.
|
||||
*
|
||||
* Requires:
|
||||
* jQuery
|
||||
* Keyboard plugin : https://github.com/Mottie/Keyboard
|
||||
*
|
||||
* Setup:
|
||||
* $('.ui-keyboard-input')
|
||||
* .keyboard(options)
|
||||
* .previewKeyset();
|
||||
*
|
||||
* // or if targeting a specific keyboard
|
||||
* $('#keyboard1')
|
||||
* .keyboard(options) // keyboard plugin
|
||||
* .previewKeyset(); // this keyboard extension
|
||||
*
|
||||
*/
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global require:false, define:false, module:false */
|
||||
;(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
'use strict';
|
||||
$.keyboard = $.keyboard || {};
|
||||
|
||||
$.fn.previewKeyset = function( options ) {
|
||||
return this.each( function() {
|
||||
// make sure a keyboard is attached
|
||||
var base = $( this ).data( 'keyboard' ),
|
||||
namespace = base.namespace + 'Preview',
|
||||
defaults = {
|
||||
sets : [ 'normal', 'shift', 'alt', 'alt-shift' ]
|
||||
};
|
||||
|
||||
if ( !base ) { return; }
|
||||
|
||||
base.previewKeyset_options = $.extend( {}, defaults, options );
|
||||
base.extensionNamespace.push( namespace );
|
||||
|
||||
base.previewKeyset = function() {
|
||||
var kbcss = $.keyboard.css,
|
||||
sets = base.previewKeyset_options.sets,
|
||||
// only target option defined sets
|
||||
$sets = base.$keyboard.find( '.' + kbcss.keySet ).filter( '[name="' + sets.join('"],[name="') + '"]' );
|
||||
if ( $sets.length > 1 ) {
|
||||
// start with normal keyset & find all non-action buttons
|
||||
$sets.eq( 0 ).find( '.' + kbcss.keyButton ).not( '.' + kbcss.keyAction ).each(function(){
|
||||
var indx, nam,
|
||||
data = {},
|
||||
len = sets.length,
|
||||
// find all keys with the same position
|
||||
$sibs = $sets.find( 'button[data-pos="' + $(this).attr('data-pos') + '"]' );
|
||||
for ( indx = 0; indx < len; indx++ ) {
|
||||
nam = $sibs.eq( indx ).parent().attr( 'name' );
|
||||
if ( $.inArray( nam, sets ) >= 0 ) {
|
||||
data[ 'data-' + nam ] = $sibs.eq( indx ).find( '.' + kbcss.keyText ).text();
|
||||
}
|
||||
}
|
||||
$sibs.attr( data );
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// visible event is fired before this extension is initialized, so check!
|
||||
if (base.options.alwaysOpen && base.isVisible()) {
|
||||
base.previewKeyset();
|
||||
} else {
|
||||
base.$el
|
||||
.unbind($.keyboard.events.kbBeforeVisible + namespace)
|
||||
.bind($.keyboard.events.kbBeforeVisible + namespace, function() {
|
||||
base.previewKeyset();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* jQuery UI Virtual Keyboard Scramble Extension v1.6.1 for Keyboard v1.18+ (updated 7/7/2015)
|
||||
*
|
||||
* By Rob Garrison (aka Mottie & Fudgey)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* Use this extension with the Virtual Keyboard to scramble the
|
||||
* specified keyboard keys
|
||||
*
|
||||
* Requires:
|
||||
* jQuery v1.4.4+
|
||||
* Keyboard v1.17.14+ - https://github.com/Mottie/Keyboard
|
||||
*
|
||||
* Setup:
|
||||
* $('.ui-keyboard-input')
|
||||
* .keyboard(options)
|
||||
* .addScramble();
|
||||
*
|
||||
* // or if targeting a specific keyboard
|
||||
* $('#keyboard1')
|
||||
* .keyboard(options) // keyboard plugin
|
||||
* .addScramble(); // this keyboard extension
|
||||
*
|
||||
*/
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global require:false, define:false, module:false */
|
||||
;(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
'use strict';
|
||||
$.keyboard = $.keyboard || {};
|
||||
|
||||
$.fn.addScramble = function(options) {
|
||||
//Set the default values, use comma to separate the settings, example:
|
||||
var savedLayout,
|
||||
defaults = {
|
||||
targetKeys : /[a-z\d]/i, // keys to randomize
|
||||
byRow : true, // randomize by row, otherwise randomize all keys
|
||||
byKeySet : false, // if true, randomize one keyset & duplicate
|
||||
randomizeOnce : true, // if true, randomize only once on keyboard visible
|
||||
sameForAll : false, // use the same scrambled keyboard for all targetted keyboards - not fully implemented!
|
||||
init : null // function(keyboard){}
|
||||
};
|
||||
return this.each(function() {
|
||||
// make sure a keyboard is attached
|
||||
var o,
|
||||
base = $(this).data('keyboard'),
|
||||
namespace = base.namespace + 'Scramble',
|
||||
opts = base.options;
|
||||
|
||||
if (!base || base.scramble_options) { return; }
|
||||
o = base.scramble_options = $.extend({}, defaults, options);
|
||||
base.extensionNamespace.push( namespace );
|
||||
|
||||
// save create callback
|
||||
o.orig_create = opts.create;
|
||||
|
||||
base.scramble_setup = function($keyboard) {
|
||||
var $sets, set, $keys, key, index, tmp,
|
||||
rowIndex, keyboardmap, map, keyboard, row;
|
||||
$sets = $keyboard.find('.' + $.keyboard.css.keySet);
|
||||
if ($keyboard.length) {
|
||||
if (o.byKeySet) {
|
||||
$sets = $sets.eq(0);
|
||||
}
|
||||
for (set = 0; set < $sets.length; set++) {
|
||||
/*jshint loopfunc:true */
|
||||
$keys = $sets.eq(set);
|
||||
rowIndex = 0;
|
||||
row = [];
|
||||
map = [];
|
||||
keyboardmap = [];
|
||||
keyboard = [];
|
||||
$keys.children('button, span, br').each(function() {
|
||||
if (this.tagName === 'BR') {
|
||||
if (o.byRow) {
|
||||
row.push(this);
|
||||
map.push(false);
|
||||
keyboard[rowIndex] = row;
|
||||
keyboardmap[rowIndex] = map;
|
||||
row = [];
|
||||
map = [];
|
||||
rowIndex++;
|
||||
} else {
|
||||
keyboard[rowIndex] = this;
|
||||
keyboardmap[rowIndex] = false;
|
||||
rowIndex++;
|
||||
}
|
||||
} else {
|
||||
tmp = $(this).attr('data-value') || '';
|
||||
tmp = tmp.length === 1 && o.targetKeys.test(tmp) ? tmp : false;
|
||||
if (o.byRow) {
|
||||
row.push( this );
|
||||
map.push ( tmp );
|
||||
} else {
|
||||
keyboard[rowIndex] = this;
|
||||
keyboardmap[rowIndex] = tmp;
|
||||
rowIndex++;
|
||||
}
|
||||
}
|
||||
});
|
||||
// remove original <br> elements
|
||||
$keys.find('.' + $.keyboard.css.endRow).remove();
|
||||
// re-map keys
|
||||
if (!o.byRow) {
|
||||
row = base.shuffle( keyboard, keyboardmap );
|
||||
for (key = 0; key < row.length; key++) {
|
||||
$keys.append(row[key]);
|
||||
}
|
||||
} else {
|
||||
for (index = 0; index < keyboard.length; index++) {
|
||||
row = base.shuffle( keyboard[index], keyboardmap[index] );
|
||||
for (key = 0; key < row.length; key++) {
|
||||
$keys.append(row[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (o.byKeySet) {
|
||||
$keyboard = base.realign($keyboard);
|
||||
}
|
||||
return $keyboard;
|
||||
}
|
||||
};
|
||||
|
||||
// modified from Fisher-Yates shuffle ( http://bost.ocks.org/mike/shuffle/ )
|
||||
// to allow not shuffling specifically mapped array elements
|
||||
base.shuffle = function(array, map) {
|
||||
var swap, random,
|
||||
index = array.length;
|
||||
// While there remain elements to shuffle...
|
||||
while (index > 0) {
|
||||
// Pick a remaining element...
|
||||
random = Math.floor(Math.random() * index);
|
||||
if (map[index - 1] === false) {
|
||||
index--;
|
||||
}
|
||||
// skip elements that are mapped to false
|
||||
if (map[index - 1] !== false && map[random] !== false) {
|
||||
// And swap it with the current element
|
||||
index--;
|
||||
swap = array[index];
|
||||
array[index] = array[random];
|
||||
array[random] = swap;
|
||||
}
|
||||
}
|
||||
return array;
|
||||
};
|
||||
|
||||
// make other keysets "line-up" with scrambled keyset
|
||||
base.realign = function($keyboard) {
|
||||
var selector, typ, pos,
|
||||
$sets = $keyboard.find('.' + $.keyboard.css.keySet),
|
||||
$orig = $sets.eq(0);
|
||||
$sets = $sets.filter(':gt(0)');
|
||||
$orig.children().each(function(i, cell){
|
||||
typ = cell.tagName === 'BR';
|
||||
pos = $(cell).attr('data-pos');
|
||||
/*jshint loopfunc:true */
|
||||
$sets.each(function(j, k){
|
||||
selector = typ ? 'br:first' : 'button[data-pos="' + pos + '"]';
|
||||
$(k).find(selector).appendTo( k );
|
||||
});
|
||||
});
|
||||
return $keyboard;
|
||||
};
|
||||
|
||||
// create scrambled keyboard layout
|
||||
opts.create = function() {
|
||||
var layout = opts.layout;
|
||||
$.keyboard.builtLayouts[layout] = {
|
||||
mappedKeys : {},
|
||||
acceptedKeys : [],
|
||||
$keyboard: null
|
||||
};
|
||||
if ( typeof $.keyboard.builtLayouts[base.orig_layout] === 'undefined' ) {
|
||||
base.layout = opts.layout = base.orig_layout;
|
||||
// build original layout, if not already built, e.g. "qwerty"
|
||||
base.buildKeyboard( base.layout, true );
|
||||
base.layout = opts.layout = layout;
|
||||
}
|
||||
// clone, scramble then save layout
|
||||
$.keyboard.builtLayouts[layout] = $.extend(true, {}, $.keyboard.builtLayouts[base.orig_layout]);
|
||||
if (o.randomizeOnce) {
|
||||
$.keyboard.builtLayouts[layout].$keyboard = base.scramble_setup( $.keyboard.builtLayouts[base.orig_layout].$keyboard.clone() );
|
||||
}
|
||||
base.$keyboard = $.keyboard.builtLayouts[layout].$keyboard;
|
||||
if ( !o.randomizeOnce ) {
|
||||
base.$el
|
||||
.unbind($.keyboard.events.kbBeforeVisible + namespace)
|
||||
.bind($.keyboard.events.kbBeforeVisible + namespace, function(e, kb) {
|
||||
kb.$keyboard = kb.scramble_setup(kb.$keyboard);
|
||||
});
|
||||
}
|
||||
if ( $.isFunction( o.orig_create ) ) {
|
||||
o.orig_create( base );
|
||||
}
|
||||
};
|
||||
|
||||
// scrambled layout already initialized
|
||||
if (!/^scrambled/.test(opts.layout)) {
|
||||
base.orig_layout = opts.layout;
|
||||
savedLayout = savedLayout || 'scrambled' + Math.round(Math.random() * 10000);
|
||||
opts.layout = o.sameForAll ? savedLayout : 'scrambled' + Math.round(Math.random() * 10000);
|
||||
}
|
||||
|
||||
// special case when keyboard is set to always be open
|
||||
if (opts.alwaysOpen && base.$keyboard.length) {
|
||||
setTimeout(function(){
|
||||
base.$keyboard = base.scramble_setup(base.$keyboard);
|
||||
if ($.isFunction(o.init)) {
|
||||
o.init(base);
|
||||
}
|
||||
}, 0);
|
||||
} else {
|
||||
if ($.isFunction(o.init)) {
|
||||
o.init(base);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
|
@ -1,323 +0,0 @@
|
|||
/*! jQuery UI Virtual Keyboard Typing Simulator v1.10.0 *//*
|
||||
* for Keyboard v1.18+ only (9/14/2015)
|
||||
*
|
||||
* By Rob Garrison (aka Mottie & Fudgey)
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* Use this extension with the Virtual Keyboard to simulate
|
||||
* typing for tutorials or whatever else use you can find
|
||||
*
|
||||
* Requires:
|
||||
* jQuery
|
||||
* Keyboard plugin : https://github.com/Mottie/Keyboard
|
||||
*
|
||||
* Setup:
|
||||
* $('.ui-keyboard-input')
|
||||
* .keyboard(options)
|
||||
* .addTyping(typing-options);
|
||||
*
|
||||
* // or if targeting a specific keyboard
|
||||
* $('#keyboard1')
|
||||
* .keyboard(options)
|
||||
* .addTyping(typing-options);
|
||||
*
|
||||
* Basic Usage:
|
||||
* // To disable manual typing on the virtual keyboard, just set "showTyping" option to false
|
||||
* $('#keyboard-input').keyboard(options).addTyping({ showTyping: false });
|
||||
*
|
||||
* // Change the default typing delay (time the virtual keyboard highlights the manually typed key) - default = 250 milliseconds
|
||||
* $('#keyboard-input').keyboard(options).addTyping({ delay: 500 });
|
||||
*
|
||||
* // get keyboard object, open it, then start typing simulation
|
||||
* $('#keyboard-input').getkeyboard().reveal().typeIn('Hello World', 700);
|
||||
*
|
||||
* // get keyboard object, open it, type in "This is a test" with 700ms delay between types, then accept & close the keyboard
|
||||
* $('#keyboard-input').getkeyboard().reveal().typeIn('This is a test', 700, function(){ $('#keyboard-input').getkeyboard().close(true); });
|
||||
*/
|
||||
|
||||
// EXAMPLES:
|
||||
// $('#inter').getkeyboard().reveal().typeIn('\tHello \b\n\tWorld', 500);
|
||||
// $('#meta').getkeyboard().reveal().typeIn('abCDd11123\u2648\u2649\u264A\u264B', 700, function(){ alert('all done!'); });
|
||||
/*jshint browser:true, jquery:true, unused:false */
|
||||
/*global require:false, define:false, module:false */
|
||||
;(function(factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = factory(require('jquery'));
|
||||
} else {
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function($) {
|
||||
$.fn.addTyping = function(options){
|
||||
//Set the default values, use comma to separate the settings, example:
|
||||
var defaults = {
|
||||
showTyping : true,
|
||||
lockTypeIn : false,
|
||||
delay : 250
|
||||
},
|
||||
$keyboard = $.keyboard;
|
||||
return this.each(function(){
|
||||
// make sure a keyboard is attached
|
||||
var o, base = $(this).data('keyboard');
|
||||
if (!base) { return; }
|
||||
|
||||
// variables
|
||||
o = base.typing_options = $.extend({}, defaults, options);
|
||||
base.typing_keymap = {
|
||||
' ' : 'space',
|
||||
'"' : '34',
|
||||
"'" : '39',
|
||||
' ' : 'space',
|
||||
'\b' : 'bksp', // delete character to the left
|
||||
'{b}' : 'bksp',
|
||||
'{d}' : 'del', // delete character to the right
|
||||
'{l}' : 'left', // move caret left
|
||||
'{r}' : 'right', // move caret right
|
||||
'\n' : 'enter',
|
||||
'\r' : 'enter',
|
||||
'{e}' : 'enter',
|
||||
'\t' : 'tab',
|
||||
'{t}' : 'tab'
|
||||
};
|
||||
base.typing_xref = {
|
||||
8 : 'bksp',
|
||||
9 : 'tab',
|
||||
13 : 'enter',
|
||||
32 : 'space',
|
||||
46 : 'del'
|
||||
};
|
||||
base.typing_event = false;
|
||||
base.typing_namespace = base.namespace + 'typing';
|
||||
base.extensionNamespace.push( base.typing_namespace );
|
||||
// save lockInput setting
|
||||
o.savedLockInput = base.options.lockInput;
|
||||
|
||||
base.typing_setup = function(){
|
||||
var kbevents = $keyboard.events,
|
||||
namespace = base.typing_namespace;
|
||||
base.$el.add( base.$preview ).unbind(namespace);
|
||||
base.$el
|
||||
.bind([ kbevents.kbHidden, kbevents.kbInactive, '' ].join( namespace + ' ' ), function(e){
|
||||
base.typing_reset();
|
||||
})
|
||||
.bind( $keyboard.events.kbBeforeVisible + namespace, function(){
|
||||
base.typing_setup();
|
||||
});
|
||||
base.$allKeys
|
||||
.bind('mousedown' + namespace, function(){
|
||||
base.typing_reset();
|
||||
});
|
||||
base.$preview
|
||||
.bind('keyup' + namespace, function(e){
|
||||
if (o.init && o.lockTypeIn) { return false; }
|
||||
if (e.which >= 37 && e.which <=40) { return; } // ignore arrow keys
|
||||
if (e.which === 16) { base.shiftActive = false; }
|
||||
if (e.which === 18) { base.altActive = false; }
|
||||
if (e.which === 16 || e.which === 18) {
|
||||
base.showSet();
|
||||
// Alt key will shift focus to the menu - doesn't work in Windows
|
||||
setTimeout(function(){ base.$preview.focus(); }, 200);
|
||||
return;
|
||||
}
|
||||
})
|
||||
// change keyset when either shift or alt is held down
|
||||
.bind('keydown' + namespace, function(e){
|
||||
if (o.init && o.lockTypeIn) { return false; }
|
||||
e.temp = false; // prevent repetitive calls while keydown repeats.
|
||||
if (e.which === 16) { e.temp = !base.shiftActive; base.shiftActive = true; }
|
||||
// it should be ok to reset e.temp, since both alt and shift will call this function separately
|
||||
if (e.which === 18) { e.temp = !base.altActive; base.altActive = true; }
|
||||
if (e.temp) {
|
||||
base.showSet();
|
||||
base.$preview.focus(); // Alt shift focus to the menu
|
||||
}
|
||||
base.typing_event = true;
|
||||
// Simulate key press for tab and backspace since they don't fire the keypress event
|
||||
if (e.which === 8 || e.which === 9) {
|
||||
base.typing_findKey( '', e ); // pass event object
|
||||
}
|
||||
|
||||
})
|
||||
.bind('keypress' + namespace, function(e){
|
||||
if (o.init && o.lockTypeIn) { return false; }
|
||||
// Simulate key press on virtual keyboard
|
||||
if (base.typing_event && !base.options.lockInput) {
|
||||
base.typing_reset();
|
||||
base.typing_event = true;
|
||||
base.typing_findKey( '', e ); // pass event object
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
base.typing_reset = function(){
|
||||
base.typing_event = o.init = false;
|
||||
o.text = '';
|
||||
o.len = o.current = 0;
|
||||
base.options.lockInput = o.savedLockInput;
|
||||
// clearTimeout(base.typing_timer);
|
||||
};
|
||||
|
||||
// Store typing text
|
||||
base.typeIn = function(txt, delay, callback, e){
|
||||
if (!base.isVisible()) {
|
||||
// keyboard was closed
|
||||
clearTimeout(base.typing_timer);
|
||||
base.typing_reset();
|
||||
return;
|
||||
}
|
||||
if (!base.typing_event){
|
||||
|
||||
if (o.init !== true) {
|
||||
o.init = true;
|
||||
base.options.lockInput = o.lockTypeIn;
|
||||
o.text = txt || o.text || '';
|
||||
o.len = o.text.length;
|
||||
o.delay = delay || 300;
|
||||
o.current = 0; // position in text string
|
||||
if (callback) {
|
||||
o.callback = callback;
|
||||
}
|
||||
}
|
||||
// function that loops through and types each character
|
||||
txt = o.text.substring( o.current, ++o.current );
|
||||
// add support for curly-wrapped single character: {l}, {r}, {d}, etc.
|
||||
if ( txt === '{' && o.text.substring( o.current + 1, o.current + 2 ) === '}' ) {
|
||||
txt += o.text.substring( o.current, o.current += 2 );
|
||||
}
|
||||
base.typing_findKey( txt, e );
|
||||
} else if (typeof txt === 'undefined') {
|
||||
// typeIn called by user input
|
||||
base.typing_event = false;
|
||||
base.options.lockInput = o.savedLockInput;
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
base.typing_findKey = function(txt, e){
|
||||
var tar, m, n, k, key, ks, meta, set,
|
||||
kbcss = $keyboard.css,
|
||||
mappedKeys = $keyboard.builtLayouts[base.layout].mappedKeys;
|
||||
// stop if keyboard is closed
|
||||
if ( !base.isOpen || !base.$keyboard.length ) { return; }
|
||||
ks = base.$keyboard.find('.' + kbcss.keySet);
|
||||
k = txt in base.typing_keymap ? base.typing_keymap[txt] : txt;
|
||||
// typing_event is true when typing on the actual keyboard - look for actual key
|
||||
// All of this breaks when the CapLock is on... unable to find a cross-browser method that works.
|
||||
tar = '.' + kbcss.keyButton + '[data-action="' + k + '"]';
|
||||
if (base.typing_event && e) {
|
||||
if (base.typing_xref.hasOwnProperty(e.keyCode || e.which)) {
|
||||
// special named keys: bksp, tab and enter
|
||||
tar = '.' + kbcss.keyPrefix + base.typing_xref[e.keyCode || e.which];
|
||||
} else {
|
||||
m = String.fromCharCode(e.charCode || e.which);
|
||||
tar = (mappedKeys.hasOwnProperty(m)) ?
|
||||
'.' + kbcss.keyButton + '[data-action="' + mappedKeys[m] + '"]' :
|
||||
'.' + kbcss.keyPrefix + m;
|
||||
}
|
||||
}
|
||||
// find key
|
||||
key = ks.filter(':visible').find(tar);
|
||||
if (key.length) {
|
||||
// key is visible, simulate typing
|
||||
base.typing_simulateKey(key, txt, e);
|
||||
} else {
|
||||
// key not found, check if it is in the keymap (tab, space, enter, etc)
|
||||
if (base.typing_event) {
|
||||
key = ks.find(tar);
|
||||
} else {
|
||||
// key not found, check if it is in the keymap (tab, space, enter, etc)
|
||||
n = txt in base.typing_keymap ? base.typing_keymap[txt] : base.processName( txt );
|
||||
// find actual key on keyboard
|
||||
key = ks.find('.' + kbcss.keyPrefix + n);
|
||||
}
|
||||
// find the keyset
|
||||
set = key.closest('.' + kbcss.keySet);
|
||||
// figure out which keyset the key is in then simulate clicking on that meta key, then on the key
|
||||
if (set.attr('name')) {
|
||||
// get meta key name
|
||||
meta = set.attr('name');
|
||||
// show correct key set
|
||||
base.shiftActive = /shift/.test(meta);
|
||||
base.altActive = /alt/.test(meta);
|
||||
base.metaActive = base.last.keyset[2] = (meta).match(/meta\d+/) || false;
|
||||
// make the plugin think we're passing it a jQuery object with a name
|
||||
base.showSet( base.metaActive );
|
||||
// Add the key
|
||||
base.typing_simulateKey(key, txt, e);
|
||||
} else {
|
||||
if (!base.typing_event) {
|
||||
// Key doesn't exist on the keyboard, so just enter it
|
||||
if (txt in base.typing_keymap && base.typing_keymap[txt] in $keyboard.keyaction) {
|
||||
$keyboard.keyaction[base.typing_keymap[txt]](base, key, e);
|
||||
} else {
|
||||
base.insertText(txt);
|
||||
}
|
||||
base.checkCombos();
|
||||
base.$el.trigger( $keyboard.events.kbChange, [ base, base.el ] );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (o.current <= o.len && o.len !== 0){
|
||||
if (!base.isVisible()) { return; } // keyboard was closed, abort!!
|
||||
setTimeout(function(){ base.typeIn(); }, o.delay);
|
||||
} else if (o.len !== 0){
|
||||
// o.len is zero when the user typed on the actual keyboard during simulation
|
||||
base.typing_reset();
|
||||
if ($.isFunction(o.callback)) {
|
||||
// ensure all typing animation is done before the callback
|
||||
setTimeout(function(){
|
||||
// if the user typed during the key simulation, the "o" variable may sometimes be undefined
|
||||
if ($.isFunction(o.callback)) {
|
||||
o.callback(base);
|
||||
}
|
||||
}, o.delay);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
base.typing_reset();
|
||||
}
|
||||
};
|
||||
|
||||
// mouseover the key, add the text directly, then mouseout on the key
|
||||
base.typing_simulateKey = function(el, txt, e){
|
||||
var len = el.length;
|
||||
if (len) { el.filter(':visible').trigger('mouseenter' + base.namespace); }
|
||||
base.typing_timer = setTimeout(function(){
|
||||
var len = el.length;
|
||||
if (len) { setTimeout(function(){ el.trigger('mouseleave' + base.namespace); }, o.delay/3); }
|
||||
if (!base.isVisible()) { return; }
|
||||
if (!base.typing_event) {
|
||||
if (txt in base.typing_keymap && base.typing_keymap[txt] in $keyboard.keyaction) {
|
||||
e = e || $.Event('keypress');
|
||||
e.target = el; // "Enter" checks for the e.target
|
||||
$keyboard.keyaction[base.typing_keymap[txt]](base, el, e );
|
||||
} else {
|
||||
base.insertText(txt);
|
||||
}
|
||||
base.checkCombos();
|
||||
base.$el.trigger( $keyboard.events.kbChange, [ base, base.el ] );
|
||||
}
|
||||
}, o.delay/3);
|
||||
};
|
||||
|
||||
if (o.showTyping) {
|
||||
// visible event is fired before this extension is initialized, so check!
|
||||
if (base.options.alwaysOpen && base.isVisible()) {
|
||||
base.typing_setup();
|
||||
}
|
||||
// capture and simulate typing
|
||||
base.$el
|
||||
.unbind( $keyboard.events.kbBeforeVisible + base.typing_namespace )
|
||||
.bind( $keyboard.events.kbBeforeVisible + base.typing_namespace, function(){
|
||||
base.typing_setup();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
}));
|
2460
web_app/js/external/jquery.keyboard.js
vendored
2460
web_app/js/external/jquery.keyboard.js
vendored
File diff suppressed because it is too large
Load diff
920
web_app/js/external/jquery.keypad.js
vendored
Normal file
920
web_app/js/external/jquery.keypad.js
vendored
Normal file
|
@ -0,0 +1,920 @@
|
|||
/* http://keith-wood.name/keypad.html
|
||||
Keypad field entry extension for jQuery v2.0.1.
|
||||
Written by Keith Wood (kbwood{at}iinet.com.au) August 2008.
|
||||
Available under the MIT (https://github.com/jquery/jquery/blob/master/LICENSE.txt) license.
|
||||
Please attribute the author if you use it. */
|
||||
|
||||
(function($) { // hide the namespace
|
||||
|
||||
var pluginName = 'keypad';
|
||||
|
||||
var layoutStandard = [' BSCECA', '_1_2_3_+@X', '_4_5_6_-@U', '_7_8_9_*@E', '_0_._=_/'];
|
||||
|
||||
/** Create the keypad plugin.
|
||||
<p>Sets an input field to popup a keypad for keystroke entry,
|
||||
or creates an inline keypad in a <code>div</code> or <code>span</code>.</p>
|
||||
<p>Expects HTML like:</p>
|
||||
<pre><input type="text"> or
|
||||
<div></div></pre>
|
||||
<p>Provide inline configuration like:</p>
|
||||
<pre><input type="text" data-keypad="name: 'value'"/></pre>
|
||||
@module Keypad
|
||||
@augments JQPlugin
|
||||
@example $(selector).keypad() */
|
||||
$.JQPlugin.createPlugin({
|
||||
|
||||
/** The name of the plugin. */
|
||||
name: pluginName,
|
||||
|
||||
/** Keypad before show callback.
|
||||
Triggered before the keypad is shown.
|
||||
@callback beforeShowCallback
|
||||
@param div {jQuery} The div to be shown.
|
||||
@param inst {object} The current instance settings. */
|
||||
|
||||
/** Keypad on keypress callback.
|
||||
Triggered when a key on the keypad is pressed.
|
||||
@callback keypressCallback
|
||||
@param key {string} The key just pressed.
|
||||
@param value {string} The full value entered so far.
|
||||
@param inst {object} The current instance settings. */
|
||||
|
||||
/** Keypad on close callback.
|
||||
Triggered when the keypad is closed.
|
||||
@callback closeCallback
|
||||
@param value {string} The full value entered so far.
|
||||
@param inst {object} The current instance settings. */
|
||||
|
||||
/** Keypad is alphabetic callback.
|
||||
Triggered when an alphabetic key needs to be identified.
|
||||
@callback isAlphabeticCallback
|
||||
@param ch {string} The key to check.
|
||||
@return {boolean} True if this key is alphabetic, false if not.
|
||||
@example isAlphabetic: function(ch) {
|
||||
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||
} */
|
||||
|
||||
/** Keypad is numeric callback.
|
||||
Triggered when an numeric key needs to be identified.
|
||||
@callback isNumericCallback
|
||||
@param ch {string} The key to check.
|
||||
@return {boolean} True if this key is numeric, false if not.
|
||||
@example isNumeric: function(ch) {
|
||||
return (ch >= '0' && ch <= '9');
|
||||
} */
|
||||
|
||||
/** Keypad to upper callback.
|
||||
Triggered to convert keys to upper case.
|
||||
@callback toUpperCallback
|
||||
@param ch {string} The key to convert.
|
||||
@return {string} The upper case version of this key.
|
||||
@example toUpper: function(ch) {
|
||||
return ch.toUpperCase();
|
||||
} */
|
||||
|
||||
/** Default settings for the plugin.
|
||||
@property [showOn='focus'] {string} 'focus' for popup on focus, 'button' for trigger button, or 'both' for either.
|
||||
@property [buttonImage=''] {string} URL for trigger button image.
|
||||
@property [buttonImageOnly=false] {boolean} True if the image appears alone, false if it appears on a button.
|
||||
@property [showAnim='show'] {string} Name of jQuery animation for popup.
|
||||
@property [showOptions=null] {object} Options for enhanced animations.
|
||||
@property [duration='normal'] {string|number} Duration of display/closure.
|
||||
@property [appendText=''] {string} Display text following the text field, e.g. showing the format.
|
||||
@property [useThemeRoller=false] {boolean} True to add ThemeRoller classes.
|
||||
@property [keypadClass=''] {string} Additional CSS class for the keypad for an instance.
|
||||
@property [prompt=''] {string} Display text at the top of the keypad.
|
||||
@property [layout=this.numericLayout] {string} Layout of keys.
|
||||
@property [separator=''] {string} Separator character between keys.
|
||||
@property [target=null] {string|jQuery|Element} Input target for an inline keypad.
|
||||
@property [keypadOnly=true] {boolean} True for entry only via the keypad, false for real keyboard too.
|
||||
@property [randomiseAlphabetic=false] {boolean} True to randomise the alphabetic key positions, false to keep in order.
|
||||
@property [randomiseNumeric=false] {boolean} True to randomise the numeric key positions, false to keep in order.
|
||||
@property [randomiseOther=false] {boolean} True to randomise the other key positions, false to keep in order.
|
||||
@property [randomiseAll=false] {boolean} True to randomise all key positions, false to keep in order.
|
||||
@property [beforeShow=null] {beforeShowCallback} Callback before showing the keypad.
|
||||
@property [onKeypress=null] {keypressCallback} Callback when a key is selected.
|
||||
@property [onClose=null] {closeCallback} Callback when the panel is closed. */
|
||||
defaultOptions: {
|
||||
showOn: 'focus',
|
||||
buttonImage: '',
|
||||
buttonImageOnly: false,
|
||||
showAnim: 'show',
|
||||
showOptions: null,
|
||||
duration: 'normal',
|
||||
appendText: '',
|
||||
useThemeRoller: false,
|
||||
keypadClass: '',
|
||||
prompt: '',
|
||||
layout: [], // Set at the end
|
||||
separator: '',
|
||||
target: null,
|
||||
keypadOnly: true,
|
||||
randomiseAlphabetic: false,
|
||||
randomiseNumeric: false,
|
||||
randomiseOther: false,
|
||||
randomiseAll: false,
|
||||
beforeShow: null,
|
||||
onKeypress: null,
|
||||
onClose: null
|
||||
},
|
||||
|
||||
/** Localisations for the plugin.
|
||||
Entries are objects indexed by the language code ('' being the default US/English).
|
||||
Each object has the following attributes.
|
||||
@property [buttonText='...'] {string} Display text for trigger button.
|
||||
@property [buttonStatus='Open the keypad'] {string} Status text for trigger button.
|
||||
@property [closeText='Close'] {string} Display text for close link.
|
||||
@property [closeStatus='Close the keypad'] {string} Status text for close link.
|
||||
@property [clearText='Clear'] {string} Display text for clear link.
|
||||
@property [clearStatus='Erase all the text'] {string} Status text for clear link.
|
||||
@property [backText='Back'] {string} Display text for back link.
|
||||
@property [backStatus='Erase the previous character'] {string} Status text for back link.
|
||||
@property [spacebarText=' '] {string} Display text for space bar.
|
||||
@property [spacebarStatus='Space'] {string} Status text for space bar.
|
||||
@property [enterText='Enter'] {string} Display text for carriage return.
|
||||
@property [enterStatus='Carriage return'] {string} Status text for carriage return.
|
||||
@property [tabText='→'] {string} Display text for tab.
|
||||
@property [tabStatus='Horizontal tab'] {string} Status text for tab.
|
||||
@property [shiftText='Shift'] {string} Display text for shift link.
|
||||
@property [shiftStatus='Toggle upper/lower case characters'] {string} Status text for shift link.
|
||||
@property [alphabeticLayout=this.qwertyAlphabetic] {string} Default layout for alphabetic characters.
|
||||
@property [fullLayout=this.qwertyLayout] {string} Default layout for full keyboard.
|
||||
@property [isAlphabetic=this.isAlphabetic] {isAlphabeticCallback} Function to determine if character is alphabetic.
|
||||
@property [isNumeric=this.isNumeric] {isNumericCallback} Function to determine if character is numeric.
|
||||
@property [toUpper=this.toUpper] {toUpperCallback} Function to convert characters to upper case.
|
||||
@property [isRTL=false] {boolean} True if right-to-left language, false if left-to-right. */
|
||||
regionalOptions: { // Available regional settings, indexed by language/country code
|
||||
'': { // Default regional settings - English/US
|
||||
buttonText: '...',
|
||||
buttonStatus: 'Open the keypad',
|
||||
closeText: 'Close',
|
||||
closeStatus: 'Close the keypad',
|
||||
clearText: 'Clear',
|
||||
clearStatus: 'Erase all the text',
|
||||
backText: 'Back',
|
||||
backStatus: 'Erase the previous character',
|
||||
spacebarText: ' ',
|
||||
spacebarStatus: 'Space',
|
||||
enterText: 'Enter',
|
||||
enterStatus: 'Carriage return',
|
||||
tabText: '→',
|
||||
tabStatus: 'Horizontal tab',
|
||||
shiftText: 'Shift',
|
||||
shiftStatus: 'Toggle upper/lower case characters',
|
||||
alphabeticLayout: [], // Set at the end
|
||||
fullLayout: [],
|
||||
isAlphabetic: null,
|
||||
isNumeric: null,
|
||||
toUpper: null,
|
||||
isRTL: false
|
||||
}
|
||||
},
|
||||
|
||||
/** Names of getter methods - those that can't be chained. */
|
||||
_getters: ['isDisabled'],
|
||||
|
||||
_curInst: null, // The current instance in use
|
||||
_disabledFields: [], // List of keypad fields that have been disabled
|
||||
_keypadShowing: false, // True if the popup panel is showing , false if not
|
||||
_keyCode: 0,
|
||||
_specialKeys: [],
|
||||
|
||||
_mainDivClass: pluginName + '-popup', // The main keypad division class
|
||||
_inlineClass: pluginName + '-inline', // The inline marker class
|
||||
_appendClass: pluginName + '-append', // The append marker class
|
||||
_triggerClass: pluginName + '-trigger', // The trigger marker class
|
||||
_disableClass: pluginName + '-disabled', // The disabled covering marker class
|
||||
_inlineEntryClass: pluginName + '-keyentry', // The inline entry marker class
|
||||
_rtlClass: pluginName + '-rtl', // The right-to-left marker class
|
||||
_rowClass: pluginName + '-row', // The keypad row marker class
|
||||
_promptClass: pluginName + '-prompt', // The prompt marker class
|
||||
_specialClass: pluginName + '-special', // The special key marker class
|
||||
_namePrefixClass: pluginName + '-', // The key name marker class prefix
|
||||
_keyClass: pluginName + '-key', // The key marker class
|
||||
_keyDownClass: pluginName + '-key-down', // The key down marker class
|
||||
|
||||
// Standard US keyboard alphabetic layout
|
||||
qwertyAlphabetic: ['qwertyuiop', 'asdfghjkl', 'zxcvbnm'],
|
||||
// Standard US keyboard layout
|
||||
qwertyLayout: ['!@#$%^&*()_=' + this.HALF_SPACE + this.SPACE + this.CLOSE,
|
||||
this.HALF_SPACE + '`~[]{}<>\\|/' + this.SPACE + '789',
|
||||
'qwertyuiop\'"' + this.HALF_SPACE + '456',
|
||||
this.HALF_SPACE + 'asdfghjkl;:' + this.SPACE + '123',
|
||||
this.SPACE + 'zxcvbnm,.?' + this.SPACE + this.HALF_SPACE + '-0+',
|
||||
'' + this.TAB + this.ENTER + this.SPACE_BAR + this.SHIFT +
|
||||
this.HALF_SPACE + this.BACK + this.CLEAR],
|
||||
|
||||
/** Add the definition of a special key.
|
||||
@param id {string} The identifier for this key - access via <code>$.keypad.xxx</code>.<id>.
|
||||
@param name {string} The prefix for localisation strings and the suffix for a class name.
|
||||
@param action {function} The action performed for this key - receives <code>inst</code> as a parameter.
|
||||
@param noHighlight {boolean} True to suppress highlight when using ThemeRoller.
|
||||
@return {Keypad} The keypad object for chaining further calls.
|
||||
@example $.keypad.addKeyDef('CLEAR', 'clear', function(inst) { plugin._clearValue(inst); }); */
|
||||
addKeyDef: function(id, name, action, noHighlight) {
|
||||
if (this._keyCode == 32) {
|
||||
throw 'Only 32 special keys allowed';
|
||||
}
|
||||
this[id] = String.fromCharCode(this._keyCode++);
|
||||
this._specialKeys.push({code: this[id], id: id, name: name,
|
||||
action: action, noHighlight: noHighlight});
|
||||
return this;
|
||||
},
|
||||
|
||||
/** Additional setup for the keypad.
|
||||
Create popup div. */
|
||||
_init: function() {
|
||||
this.mainDiv = $('<div class="' + this._mainDivClass + '" style="display: none;"></div>');
|
||||
this._super();
|
||||
},
|
||||
|
||||
_instSettings: function(elem, options) {
|
||||
var inline = !elem[0].nodeName.toLowerCase().match(/input|textarea/);
|
||||
return {_inline: inline, ucase: false,
|
||||
_mainDiv: (inline ? $('<div class="' + this._inlineClass + '"></div>') : plugin.mainDiv)};
|
||||
},
|
||||
|
||||
_postAttach: function(elem, inst) {
|
||||
if (inst._inline) {
|
||||
elem.append(inst._mainDiv).
|
||||
on('click.' + inst.name, function() { inst._input.focus(); });
|
||||
this._updateKeypad(inst);
|
||||
}
|
||||
else if (elem.is(':disabled')) {
|
||||
this.disable(elem);
|
||||
}
|
||||
},
|
||||
|
||||
/** Determine the input field for the keypad.
|
||||
@private
|
||||
@param elem {jQuery} The target control.
|
||||
@param inst {object} The instance settings. */
|
||||
_setInput: function(elem, inst) {
|
||||
inst._input = $(!inst._inline ? elem : inst.options.target ||
|
||||
'<input type="text" class="' + this._inlineEntryClass + '" disabled/>');
|
||||
if (inst._inline) {
|
||||
elem.find('input').remove();
|
||||
if (!inst.options.target) {
|
||||
elem.append(inst._input);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_optionsChanged: function(elem, inst, options) {
|
||||
$.extend(inst.options, options);
|
||||
elem.off('.' + inst.name).
|
||||
siblings('.' + this._appendClass).remove().end().
|
||||
siblings('.' + this._triggerClass).remove();
|
||||
var appendText = inst.options.appendText;
|
||||
if (appendText) {
|
||||
elem[inst.options.isRTL ? 'before' : 'after'](
|
||||
'<span class="' + this._appendClass + '">' + appendText + '</span>');
|
||||
}
|
||||
if (!inst._inline) {
|
||||
if (inst.options.showOn == 'focus' || inst.options.showOn == 'both') {
|
||||
// pop-up keypad when in the marked field
|
||||
elem.on('focus.' + inst.name, this.show).
|
||||
on('keydown.' + inst.name, this._doKeyDown);
|
||||
}
|
||||
if (inst.options.showOn == 'button' || inst.options.showOn == 'both') {
|
||||
// pop-up keypad when button clicked
|
||||
var buttonStatus = inst.options.buttonStatus;
|
||||
var buttonImage = inst.options.buttonImage;
|
||||
var trigger = $(inst.options.buttonImageOnly ?
|
||||
$('<img src="' + buttonImage + '" alt="' +
|
||||
buttonStatus + '" title="' + buttonStatus + '"/>') :
|
||||
$('<button type="button" title="' + buttonStatus + '"></button>').
|
||||
html(buttonImage == '' ? inst.options.buttonText :
|
||||
$('<img src="' + buttonImage + '" alt="' +
|
||||
buttonStatus + '" title="' + buttonStatus + '"/>')));
|
||||
elem[inst.options.isRTL ? 'before' : 'after'](trigger);
|
||||
trigger.addClass(this._triggerClass).click(function() {
|
||||
if (plugin._keypadShowing && plugin._lastField == elem[0]) {
|
||||
plugin.hide();
|
||||
}
|
||||
else {
|
||||
plugin.show(elem[0]);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
inst.saveReadonly = elem.attr('readonly');
|
||||
elem[inst.options.keypadOnly ? 'attr' : 'removeAttr']('readonly', true).
|
||||
on('setData.' + inst.name, function(event, key, value) {
|
||||
inst.options[key] = value;
|
||||
}).
|
||||
on('getData.' + inst.name, function(event, key) {
|
||||
return inst.options[key];
|
||||
});
|
||||
this._setInput(elem, inst);
|
||||
this._updateKeypad(inst);
|
||||
},
|
||||
|
||||
_preDestroy: function(elem, inst) {
|
||||
if (this._curInst == inst) {
|
||||
this.hide();
|
||||
}
|
||||
elem.siblings('.' + this._appendClass).remove().end().
|
||||
siblings('.' + this._triggerClass).remove().end().
|
||||
prev('.' + this._inlineEntryClass).remove();
|
||||
elem.empty().off('.' + inst.name)
|
||||
[inst.saveReadonly ? 'attr' : 'removeAttr']('readonly', true);
|
||||
inst._input.removeData(inst.name);
|
||||
},
|
||||
|
||||
/** Enable the keypad for a jQuery selection.
|
||||
@param elem {Element} The target text field.
|
||||
@example $(selector).keypad('enable'); */
|
||||
enable: function(elem) {
|
||||
elem = $(elem);
|
||||
if (!elem.hasClass(this._getMarker())) {
|
||||
return;
|
||||
}
|
||||
var nodeName = elem[0].nodeName.toLowerCase();
|
||||
if (nodeName.match(/input|textarea/)) {
|
||||
elem.prop('disabled', false).
|
||||
siblings('button.' + this._triggerClass).prop('disabled', false).end().
|
||||
siblings('img.' + this._triggerClass).css({opacity: '1.0', cursor: ''});
|
||||
}
|
||||
else if (nodeName.match(/div|span/)) {
|
||||
elem.children('.' + this._disableClass).remove();
|
||||
this._getInst(elem)._mainDiv.find('button').prop('disabled', false);
|
||||
}
|
||||
this._disabledFields = $.map(this._disabledFields,
|
||||
function(value) { return (value == elem[0] ? null : value); }); // delete entry
|
||||
},
|
||||
|
||||
/** Disable the keypad for a jQuery selection.
|
||||
@param elem {Element} The target text field.
|
||||
@example $(selector).keypad('disable'); */
|
||||
disable: function(elem) {
|
||||
elem = $(elem);
|
||||
if (!elem.hasClass(this._getMarker())) {
|
||||
return;
|
||||
}
|
||||
var nodeName = elem[0].nodeName.toLowerCase();
|
||||
if (nodeName.match(/input|textarea/)) {
|
||||
elem.prop('disabled', true).
|
||||
siblings('button.' + this._triggerClass).prop('disabled', true).end().
|
||||
siblings('img.' + this._triggerClass).css({opacity: '0.5', cursor: 'default'});
|
||||
}
|
||||
else if (nodeName.match(/div|span/)) {
|
||||
var inline = elem.children('.' + this._inlineClass);
|
||||
var offset = inline.offset();
|
||||
var relOffset = {left: 0, top: 0};
|
||||
inline.parents().each(function() {
|
||||
if ($(this).css('position') == 'relative') {
|
||||
relOffset = $(this).offset();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
elem.prepend('<div class="' + this._disableClass + '" style="width: ' +
|
||||
inline.outerWidth() + 'px; height: ' + inline.outerHeight() +
|
||||
'px; left: ' + (offset.left - relOffset.left) +
|
||||
'px; top: ' + (offset.top - relOffset.top) + 'px;"></div>');
|
||||
this._getInst(elem)._mainDiv.find('button').prop('disabled', true);
|
||||
}
|
||||
this._disabledFields = $.map(this._disabledFields,
|
||||
function(value) { return (value == elem[0] ? null : value); }); // delete entry
|
||||
this._disabledFields[this._disabledFields.length] = elem[0];
|
||||
},
|
||||
|
||||
/** Is the text field disabled as a keypad?
|
||||
@param elem {Element} The target text field.
|
||||
@return {boolean} True if disabled, false if enabled.
|
||||
@example var disabled = $(selector).keypad('isDisabled'); */
|
||||
isDisabled: function(elem) {
|
||||
return (elem && $.inArray(elem, this._disabledFields) > -1);
|
||||
},
|
||||
|
||||
/** Pop-up the keypad for a given text field.
|
||||
@param elem {Element|Event} The text field attached to the keypad or event if triggered by focus.
|
||||
@example $(selector).keypad('show'); */
|
||||
show: function(elem) {
|
||||
elem = elem.target || elem;
|
||||
if (plugin.isDisabled(elem) || plugin._lastField == elem) { // already here
|
||||
return;
|
||||
}
|
||||
var inst = plugin._getInst(elem);
|
||||
plugin.hide(null, '');
|
||||
plugin._lastField = elem;
|
||||
plugin._pos = plugin._findPos(elem);
|
||||
plugin._pos[1] += elem.offsetHeight; // add the height
|
||||
var isFixed = false;
|
||||
$(elem).parents().each(function() {
|
||||
isFixed |= $(this).css('position') == 'fixed';
|
||||
return !isFixed;
|
||||
});
|
||||
var offset = {left: plugin._pos[0], top: plugin._pos[1]};
|
||||
plugin._pos = null;
|
||||
// determine sizing offscreen
|
||||
inst._mainDiv.css({position: 'absolute', display: 'block', top: '-1000px', width: 'auto'});
|
||||
plugin._updateKeypad(inst);
|
||||
// and adjust position before showing
|
||||
offset = plugin._checkOffset(inst, offset, isFixed);
|
||||
inst._mainDiv.css({position: (isFixed ? 'fixed' : 'absolute'), display: 'none',
|
||||
left: offset.left + 'px', top: offset.top + 'px'});
|
||||
var duration = inst.options.duration;
|
||||
var showAnim = inst.options.showAnim;
|
||||
var postProcess = function() {
|
||||
plugin._keypadShowing = true;
|
||||
};
|
||||
if ($.effects && ($.effects[showAnim] || ($.effects.effect && $.effects.effect[showAnim]))) {
|
||||
var data = inst._mainDiv.data(); // Update old effects data
|
||||
for (var key in data) {
|
||||
if (key.match(/^ec\.storage\./)) {
|
||||
data[key] = inst._mainDiv.css(key.replace(/ec\.storage\./, ''));
|
||||
}
|
||||
}
|
||||
inst._mainDiv.data(data).show(showAnim,
|
||||
inst.options.showOptions || {}, duration, postProcess);
|
||||
}
|
||||
else {
|
||||
inst._mainDiv[showAnim || 'show']((showAnim ? duration : 0), postProcess);
|
||||
}
|
||||
if (inst._input[0].type != 'hidden') {
|
||||
inst._input[0].focus();
|
||||
}
|
||||
plugin._curInst = inst;
|
||||
},
|
||||
|
||||
/** Generate the keypad content.
|
||||
@private
|
||||
@param inst {object} The instance settings. */
|
||||
_updateKeypad: function(inst) {
|
||||
var borders = this._getBorders(inst._mainDiv);
|
||||
inst._mainDiv.empty().append(this._generateHTML(inst)).
|
||||
removeClass().addClass(inst.options.keypadClass +
|
||||
(inst.options.useThemeRoller ? ' ui-widget ui-widget-content' : '') +
|
||||
(inst.options.isRTL ? ' ' + this._rtlClass : '') + ' ' +
|
||||
(inst._inline ? this._inlineClass : this._mainDivClass));
|
||||
if ($.isFunction(inst.options.beforeShow)) {
|
||||
inst.options.beforeShow.apply((inst._input ? inst._input[0] : null),
|
||||
[inst._mainDiv, inst]);
|
||||
}
|
||||
},
|
||||
|
||||
/** Retrieve the size of left and top borders for an element.
|
||||
@private
|
||||
@param elem {jQuery} The element of interest.
|
||||
@return {number[]} The left and top borders. */
|
||||
_getBorders: function(elem) {
|
||||
var convert = function(value) {
|
||||
return {thin: 1, medium: 3, thick: 5}[value] || value;
|
||||
};
|
||||
return [parseFloat(convert(elem.css('border-left-width'))),
|
||||
parseFloat(convert(elem.css('border-top-width')))];
|
||||
},
|
||||
|
||||
/** Check positioning to remain on screen.
|
||||
@private
|
||||
@param inst {object} The instance settings.
|
||||
@param offset {object} The current offset.
|
||||
@param isFixed {boolean} True if the text field is fixed in position.
|
||||
@return {object} The updated offset. */
|
||||
_checkOffset: function(inst, offset, isFixed) {
|
||||
var pos = inst._input ? this._findPos(inst._input[0]) : null;
|
||||
var browserWidth = window.innerWidth || document.documentElement.clientWidth;
|
||||
var browserHeight = window.innerHeight || document.documentElement.clientHeight;
|
||||
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
// recalculate width as otherwise set to 100%
|
||||
var width = 0;
|
||||
inst._mainDiv.find(':not(div)').each(function() {
|
||||
width = Math.max(width, this.offsetLeft + $(this).outerWidth(true));
|
||||
});
|
||||
inst._mainDiv.css('width', width + 1);
|
||||
// reposition keypad panel horizontally if outside the browser window
|
||||
if (inst.options.isRTL ||
|
||||
(offset.left + inst._mainDiv.outerWidth() - scrollX) > browserWidth) {
|
||||
offset.left = Math.max((isFixed ? 0 : scrollX),
|
||||
pos[0] + (inst._input ? inst._input.outerWidth() : 0) -
|
||||
(isFixed ? scrollX : 0) - inst._mainDiv.outerWidth());
|
||||
}
|
||||
else {
|
||||
offset.left = Math.max((isFixed ? 0 : scrollX), offset.left - (isFixed ? scrollX : 0));
|
||||
}
|
||||
// reposition keypad panel vertically if outside the browser window
|
||||
if ((offset.top + inst._mainDiv.outerHeight() - scrollY) > browserHeight) {
|
||||
offset.top = Math.max((isFixed ? 0 : scrollY),
|
||||
pos[1] - (isFixed ? scrollY : 0) - inst._mainDiv.outerHeight());
|
||||
}
|
||||
else {
|
||||
offset.top = Math.max((isFixed ? 0 : scrollY), offset.top - (isFixed ? scrollY : 0));
|
||||
}
|
||||
return offset;
|
||||
},
|
||||
|
||||
/** Find an object's position on the screen.
|
||||
@private
|
||||
@param obj {Element} The element to find the position for.
|
||||
@return {number[]} The element's position. */
|
||||
_findPos: function(obj) {
|
||||
while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
|
||||
obj = obj.nextSibling;
|
||||
}
|
||||
var position = $(obj).offset();
|
||||
return [position.left, position.top];
|
||||
},
|
||||
|
||||
/** Hide the keypad from view.
|
||||
@param elem {Element} The text field attached to the keypad.
|
||||
@param duration {string} The duration over which to close the keypad.
|
||||
@example $(selector).keypad('hide') */
|
||||
hide: function(elem, duration) {
|
||||
var inst = this._curInst;
|
||||
if (!inst || (elem && inst != $.data(elem, this.name))) {
|
||||
return;
|
||||
}
|
||||
if (this._keypadShowing) {
|
||||
duration = (duration != null ? duration : inst.options.duration);
|
||||
var showAnim = inst.options.showAnim;
|
||||
if ($.effects && ($.effects[showAnim] || ($.effects.effect && $.effects.effect[showAnim]))) {
|
||||
inst._mainDiv.hide(showAnim, inst.options.showOptions || {}, duration);
|
||||
}
|
||||
else {
|
||||
inst._mainDiv[(showAnim == 'slideDown' ? 'slideUp' :
|
||||
(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))](showAnim ? duration : 0);
|
||||
}
|
||||
}
|
||||
if ($.isFunction(inst.options.onClose)) {
|
||||
inst.options.onClose.apply((inst._input ? inst._input[0] : null), // trigger custom callback
|
||||
[inst._input.val(), inst]);
|
||||
}
|
||||
if (this._keypadShowing) {
|
||||
this._keypadShowing = false;
|
||||
this._lastField = null;
|
||||
}
|
||||
if (inst._inline) {
|
||||
inst._input.val('');
|
||||
}
|
||||
this._curInst = null;
|
||||
},
|
||||
|
||||
/** Handle keystrokes.
|
||||
@private
|
||||
@param event {Event} The key event. */
|
||||
_doKeyDown: function(event) {
|
||||
if (event.keyCode == 9) { // Tab out
|
||||
plugin.mainDiv.stop(true, true);
|
||||
plugin.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/** Close keypad if clicked elsewhere.
|
||||
@private
|
||||
@param event {Event} The mouseclick details. */
|
||||
_checkExternalClick: function(event) {
|
||||
if (!plugin._curInst) {
|
||||
return;
|
||||
}
|
||||
var target = $(event.target);
|
||||
if (target.closest('.' + plugin._mainDivClass).length === 0 &&
|
||||
!target.hasClass(plugin._getMarker()) &&
|
||||
target.closest('.' + plugin._triggerClass).length === 0 &&
|
||||
plugin._keypadShowing) {
|
||||
plugin.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/** Toggle between upper and lower case.
|
||||
@private
|
||||
@param inst {object} The instance settings. */
|
||||
_shiftKeypad: function(inst) {
|
||||
inst.ucase = !inst.ucase;
|
||||
this._updateKeypad(inst);
|
||||
inst._input.focus(); // for further typing
|
||||
},
|
||||
|
||||
/** Erase the text field.
|
||||
@private
|
||||
@param inst {object} The instance settings. */
|
||||
_clearValue: function(inst) {
|
||||
this._setValue(inst, '', 0);
|
||||
this._notifyKeypress(inst, plugin.DEL);
|
||||
},
|
||||
|
||||
/** Erase the last character.
|
||||
@private
|
||||
@param inst {object} The instance settings. */
|
||||
_backValue: function(inst) {
|
||||
var elem = inst._input[0];
|
||||
var value = inst._input.val();
|
||||
var range = [value.length, value.length];
|
||||
range = (inst._input.prop('readonly') || inst._input.prop('disabled') ? range :
|
||||
(elem.setSelectionRange /* Mozilla */ ? [elem.selectionStart, elem.selectionEnd] :
|
||||
(elem.createTextRange /* IE */ ? this._getIERange(elem) : range)));
|
||||
this._setValue(inst, (value.length == 0 ? '' :
|
||||
value.substr(0, range[0] - 1) + value.substr(range[1])), range[0] - 1);
|
||||
this._notifyKeypress(inst, plugin.BS);
|
||||
},
|
||||
|
||||
/** Update the text field with the selected value.
|
||||
@private
|
||||
@param inst {object} The instance settings.
|
||||
@param value {string} The new character to add. */
|
||||
_selectValue: function(inst, value) {
|
||||
this.insertValue(inst._input[0], value);
|
||||
this._setValue(inst, inst._input.val());
|
||||
this._notifyKeypress(inst, value);
|
||||
},
|
||||
|
||||
/** Update the text field with the selected value.
|
||||
@param input {string|Element|jQuery} The jQuery selector, input field, or jQuery collection.
|
||||
@param value {string} The new character to add.
|
||||
@example $.keypad.insertValue(field, 'abc'); */
|
||||
insertValue: function(input, value) {
|
||||
input = (input.jquery ? input : $(input));
|
||||
var elem = input[0];
|
||||
var newValue = input.val();
|
||||
var range = [newValue.length, newValue.length];
|
||||
range = (input.attr('readonly') || input.attr('disabled') ? range :
|
||||
(elem.setSelectionRange /* Mozilla */ ? [elem.selectionStart, elem.selectionEnd] :
|
||||
(elem.createTextRange /* IE */ ? this._getIERange(elem) : range)));
|
||||
input.val(newValue.substr(0, range[0]) + value + newValue.substr(range[1]));
|
||||
pos = range[0] + value.length;
|
||||
if (input.is(':visible')) {
|
||||
input.focus(); // for further typing
|
||||
}
|
||||
if (elem.setSelectionRange) { // Mozilla
|
||||
if (input.is(':visible')) {
|
||||
elem.setSelectionRange(pos, pos);
|
||||
}
|
||||
}
|
||||
else if (elem.createTextRange) { // IE
|
||||
range = elem.createTextRange();
|
||||
range.move('character', pos);
|
||||
range.select();
|
||||
}
|
||||
},
|
||||
|
||||
/** Get the coordinates for the selected area in the text field in IE.
|
||||
@private
|
||||
@param elem {Element} The target text field.
|
||||
@return {number[]} The start and end positions of the selection. */
|
||||
_getIERange: function(elem) {
|
||||
elem.focus();
|
||||
var selectionRange = document.selection.createRange().duplicate();
|
||||
// Use two ranges: before and selection
|
||||
var beforeRange = this._getIETextRange(elem);
|
||||
beforeRange.setEndPoint('EndToStart', selectionRange);
|
||||
// Check each range for trimmed newlines by shrinking the range by one
|
||||
// character and seeing if the text property has changed. If it has not
|
||||
// changed then we know that IE has trimmed a \r\n from the end.
|
||||
var checkCRLF = function(range) {
|
||||
var origText = range.text;
|
||||
var text = origText;
|
||||
var finished = false;
|
||||
while (true) {
|
||||
if (range.compareEndPoints('StartToEnd', range) == 0) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
range.moveEnd('character', -1);
|
||||
if (range.text == origText) {
|
||||
text += '\r\n';
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return text;
|
||||
};
|
||||
var beforeText = checkCRLF(beforeRange);
|
||||
var selectionText = checkCRLF(selectionRange);
|
||||
return [beforeText.length, beforeText.length + selectionText.length];
|
||||
},
|
||||
|
||||
/** Create an IE text range for the text field.
|
||||
@private
|
||||
@param elem {Element} The target text field.
|
||||
@return {object} The corresponding text range. */
|
||||
_getIETextRange: function(elem) {
|
||||
var isInput = (elem.nodeName.toLowerCase() == 'input');
|
||||
var range = (isInput ? elem.createTextRange() : document.body.createTextRange());
|
||||
if (!isInput) {
|
||||
range.moveToElementText(elem); // Selects all the text for a textarea
|
||||
}
|
||||
return range;
|
||||
},
|
||||
|
||||
/** Set the text field to the selected value, and trigger any on change event.
|
||||
@private
|
||||
@param inst {object} The instance settings.
|
||||
@param value {string} The new value for the text field. */
|
||||
_setValue: function(inst, value) {
|
||||
var maxlen = inst._input.attr('maxlength');
|
||||
if (maxlen > -1) {
|
||||
value = value.substr(0, maxlen);
|
||||
}
|
||||
inst._input.val(value);
|
||||
if (!$.isFunction(inst.options.onKeypress)) {
|
||||
inst._input.trigger('change'); // fire the change event
|
||||
}
|
||||
},
|
||||
|
||||
/** Notify clients of a keypress.
|
||||
@private
|
||||
@param inst {object} The instance settings.
|
||||
@param key {string} The character pressed. */
|
||||
_notifyKeypress: function(inst, key) {
|
||||
if ($.isFunction(inst.options.onKeypress)) { // trigger custom callback
|
||||
inst.options.onKeypress.apply((inst._input ? inst._input[0] : null),
|
||||
[key, inst._input.val(), inst]);
|
||||
}
|
||||
},
|
||||
|
||||
/** Generate the HTML for the current state of the keypad.
|
||||
@private
|
||||
@param inst {object} The instance settings.
|
||||
@return {jQuery} The HTML for this keypad. */
|
||||
_generateHTML: function(inst) {
|
||||
var html = (!inst.options.prompt ? '' : '<div class="' + this._promptClass +
|
||||
(inst.options.useThemeRoller ? ' ui-widget-header ui-corner-all' : '') + '">' +
|
||||
inst.options.prompt + '</div>');
|
||||
var layout = this._randomiseLayout(inst);
|
||||
for (var i = 0; i < layout.length; i++) {
|
||||
html += '<div class="' + this._rowClass + '">';
|
||||
var keys = layout[i].split(inst.options.separator);
|
||||
for (var j = 0; j < keys.length; j++) {
|
||||
if (inst.ucase) {
|
||||
keys[j] = inst.options.toUpper(keys[j]);
|
||||
}
|
||||
var keyDef = this._specialKeys[keys[j].charCodeAt(0)];
|
||||
if (keyDef) {
|
||||
html += (keyDef.action ? '<button type="button" class="' +
|
||||
this._specialClass + ' ' + this._namePrefixClass + keyDef.name +
|
||||
(inst.options.useThemeRoller ? ' ui-corner-all ui-state-default' +
|
||||
(keyDef.noHighlight ? '' : ' ui-state-highlight') : '') +
|
||||
'" title="' + inst.options[keyDef.name + 'Status'] + '">' +
|
||||
(inst.options[keyDef.name + 'Text'] || ' ') + '</button>' :
|
||||
'<div class="' + this._namePrefixClass + keyDef.name + '"></div>');
|
||||
}
|
||||
else {
|
||||
html += '<button type="button" class="' + this._keyClass +
|
||||
(inst.options.useThemeRoller ? ' ui-corner-all ui-state-default' : '') +
|
||||
'">' + (keys[j] == ' ' ? ' ' : keys[j]) + '</button>';
|
||||
}
|
||||
}
|
||||
html += '</div>';
|
||||
}
|
||||
html = $(html);
|
||||
var thisInst = inst;
|
||||
var activeClasses = this._keyDownClass +
|
||||
(inst.options.useThemeRoller ? ' ui-state-active' : '');
|
||||
html.find('button').mousedown(function() { $(this).addClass(activeClasses); }).
|
||||
mouseup(function() { $(this).removeClass(activeClasses); }).
|
||||
mouseout(function() { $(this).removeClass(activeClasses); }).
|
||||
filter('.' + this._keyClass).
|
||||
click(function() { plugin._selectValue(thisInst, $(this).text()); });
|
||||
$.each(this._specialKeys, function(i, keyDef) {
|
||||
html.find('.' + plugin._namePrefixClass + keyDef.name).click(function() {
|
||||
keyDef.action.apply(thisInst._input, [thisInst]);
|
||||
});
|
||||
});
|
||||
return html;
|
||||
},
|
||||
|
||||
/** Check whether characters should be randomised, and, if so, produce the randomised layout.
|
||||
@private
|
||||
@param inst {object} The instance settings.
|
||||
@return {string[]} The layout with any requested randomisations applied. */
|
||||
_randomiseLayout: function(inst) {
|
||||
if (!inst.options.randomiseNumeric && !inst.options.randomiseAlphabetic &&
|
||||
!inst.options.randomiseOther && !inst.options.randomiseAll) {
|
||||
return inst.options.layout;
|
||||
}
|
||||
var numerics = [];
|
||||
var alphas = [];
|
||||
var others = [];
|
||||
var newLayout = [];
|
||||
// Find characters of different types
|
||||
for (var i = 0; i < inst.options.layout.length; i++) {
|
||||
newLayout[i] = '';
|
||||
var keys = inst.options.layout[i].split(inst.options.separator);
|
||||
for (var j = 0; j < keys.length; j++) {
|
||||
if (this._isControl(keys[j])) {
|
||||
continue;
|
||||
}
|
||||
if (inst.options.randomiseAll) {
|
||||
others.push(keys[j]);
|
||||
}
|
||||
else if (inst.options.isNumeric(keys[j])) {
|
||||
numerics.push(keys[j]);
|
||||
}
|
||||
else if (inst.options.isAlphabetic(keys[j])) {
|
||||
alphas.push(keys[j]);
|
||||
}
|
||||
else {
|
||||
others.push(keys[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Shuffle them
|
||||
if (inst.options.randomiseNumeric) {
|
||||
this._shuffle(numerics);
|
||||
}
|
||||
if (inst.options.randomiseAlphabetic) {
|
||||
this._shuffle(alphas);
|
||||
}
|
||||
if (inst.options.randomiseOther || inst.options.randomiseAll) {
|
||||
this._shuffle(others);
|
||||
}
|
||||
var n = 0;
|
||||
var a = 0;
|
||||
var o = 0;
|
||||
// And replace them in the layout
|
||||
for (var i = 0; i < inst.options.layout.length; i++) {
|
||||
var keys = inst.options.layout[i].split(inst.options.separator);
|
||||
for (var j = 0; j < keys.length; j++) {
|
||||
newLayout[i] += (this._isControl(keys[j]) ? keys[j] :
|
||||
(inst.options.randomiseAll ? others[o++] :
|
||||
(inst.options.isNumeric(keys[j]) ? numerics[n++] :
|
||||
(inst.options.isAlphabetic(keys[j]) ? alphas[a++] :
|
||||
others[o++])))) + inst.options.separator;
|
||||
}
|
||||
}
|
||||
return newLayout;
|
||||
},
|
||||
|
||||
/** Is a given character a control character?
|
||||
@private
|
||||
@param ch {string} The character to test.
|
||||
@return {boolean} True if a control character, false if not. */
|
||||
_isControl: function(ch) {
|
||||
return ch < ' ';
|
||||
},
|
||||
|
||||
/** Is a given character alphabetic?
|
||||
@param ch {string} The character to test.
|
||||
@return {boolean} True if alphabetic, false if not. */
|
||||
isAlphabetic: function(ch) {
|
||||
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||
},
|
||||
|
||||
/** Is a given character numeric?
|
||||
@param ch {string} The character to test.
|
||||
@return {boolean} True if numeric, false if not. */
|
||||
isNumeric: function(ch) {
|
||||
return (ch >= '0' && ch <= '9');
|
||||
},
|
||||
|
||||
/** Convert a character to upper case.
|
||||
@param ch {string} The character to convert.
|
||||
@return {string} Its uppercase version. */
|
||||
toUpper: function(ch) {
|
||||
return ch.toUpperCase();
|
||||
},
|
||||
|
||||
/** Randomise the contents of an array.
|
||||
@private
|
||||
@param values {string[]} The array to rearrange. */
|
||||
_shuffle: function(values) {
|
||||
for (var i = values.length - 1; i > 0; i--) {
|
||||
var j = Math.floor(Math.random() * values.length);
|
||||
var ch = values[i];
|
||||
values[i] = values[j];
|
||||
values[j] = ch;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var plugin = $.keypad;
|
||||
|
||||
// Initialise the key definitions
|
||||
plugin.addKeyDef('CLOSE', 'close', function(inst) {
|
||||
plugin._curInst = (inst._inline ? inst : plugin._curInst);
|
||||
plugin.hide();
|
||||
});
|
||||
plugin.addKeyDef('CLEAR', 'clear', function(inst) { plugin._clearValue(inst); });
|
||||
plugin.addKeyDef('BACK', 'back', function(inst) { plugin._backValue(inst); });
|
||||
plugin.addKeyDef('SHIFT', 'shift', function(inst) { plugin._shiftKeypad(inst); });
|
||||
plugin.addKeyDef('SPACE_BAR', 'spacebar', function(inst) { plugin._selectValue(inst, ' '); }, true);
|
||||
plugin.addKeyDef('SPACE', 'space');
|
||||
plugin.addKeyDef('HALF_SPACE', 'half-space');
|
||||
plugin.addKeyDef('ENTER', 'enter', function(inst) { plugin._selectValue(inst, '\x0D'); }, true);
|
||||
plugin.addKeyDef('TAB', 'tab', function(inst) { plugin._selectValue(inst, '\x09'); }, true);
|
||||
|
||||
// Initialise the layouts and settings
|
||||
plugin.numericLayout = ['123' + plugin.CLOSE, '456' + plugin.CLEAR, '789' + plugin.BACK, plugin.SPACE + '0'];
|
||||
plugin.qwertyLayout = ['!@#$%^&*()_=' + plugin.HALF_SPACE + plugin.SPACE + plugin.CLOSE,
|
||||
plugin.HALF_SPACE + '`~[]{}<>\\|/' + plugin.SPACE + '789',
|
||||
'qwertyuiop\'"' + plugin.HALF_SPACE + '456',
|
||||
plugin.HALF_SPACE + 'asdfghjkl;:' + plugin.SPACE + '123',
|
||||
plugin.SPACE + 'zxcvbnm,.?' + plugin.SPACE + plugin.HALF_SPACE + '-0+',
|
||||
'' + plugin.TAB + plugin.ENTER + plugin.SPACE_BAR + plugin.SHIFT +
|
||||
plugin.HALF_SPACE + plugin.BACK + plugin.CLEAR],
|
||||
$.extend(plugin.regionalOptions[''],
|
||||
{alphabeticLayout: plugin.qwertyAlphabetic, fullLayout: plugin.qwertyLayout,
|
||||
isAlphabetic: plugin.isAlphabetic, isNumeric: plugin.isNumeric, toUpper: plugin.toUpper});
|
||||
plugin.setDefaults($.extend({layout: plugin.numericLayout}, plugin.regionalOptions['']));
|
||||
|
||||
// Add the keypad division and external click check
|
||||
$(function() {
|
||||
$(document.body).append(plugin.mainDiv).
|
||||
on('mousedown.' + pluginName, plugin._checkExternalClick);
|
||||
});
|
||||
|
||||
})(jQuery);
|
BIN
web_app/js/external/jquery.keypad.package-2.0.1.zip
vendored
BIN
web_app/js/external/jquery.keypad.package-2.0.1.zip
vendored
Binary file not shown.
221
web_app/js/external/jquery.mousewheel.js
vendored
221
web_app/js/external/jquery.mousewheel.js
vendored
|
@ -1,221 +0,0 @@
|
|||
/* Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
|
||||
* Licensed under the MIT License (LICENSE.txt).
|
||||
*
|
||||
* Version: 3.1.12
|
||||
*
|
||||
* Requires: jQuery 1.2.2+
|
||||
*/
|
||||
/*! Mousewheel version: 3.1.12 * (c) 2014 Brandon Aaron * MIT License */
|
||||
(function (factory) {
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS style for Browserify
|
||||
module.exports = factory;
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
|
||||
var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
|
||||
toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
|
||||
['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
|
||||
slice = Array.prototype.slice,
|
||||
nullLowestDeltaTimeout, lowestDelta;
|
||||
|
||||
if ( $.event.fixHooks ) {
|
||||
for ( var i = toFix.length; i; ) {
|
||||
$.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
|
||||
}
|
||||
}
|
||||
|
||||
var special = $.event.special.mousewheel = {
|
||||
version: '3.1.12',
|
||||
|
||||
setup: function() {
|
||||
if ( this.addEventListener ) {
|
||||
for ( var i = toBind.length; i; ) {
|
||||
this.addEventListener( toBind[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = handler;
|
||||
}
|
||||
// Store the line height and page height for this particular element
|
||||
$.data(this, 'mousewheel-line-height', special.getLineHeight(this));
|
||||
$.data(this, 'mousewheel-page-height', special.getPageHeight(this));
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
if ( this.removeEventListener ) {
|
||||
for ( var i = toBind.length; i; ) {
|
||||
this.removeEventListener( toBind[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = null;
|
||||
}
|
||||
// Clean up the data we added to the element
|
||||
$.removeData(this, 'mousewheel-line-height');
|
||||
$.removeData(this, 'mousewheel-page-height');
|
||||
},
|
||||
|
||||
getLineHeight: function(elem) {
|
||||
var $elem = $(elem),
|
||||
$parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
|
||||
if (!$parent.length) {
|
||||
$parent = $('body');
|
||||
}
|
||||
return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
|
||||
},
|
||||
|
||||
getPageHeight: function(elem) {
|
||||
return $(elem).height();
|
||||
},
|
||||
|
||||
settings: {
|
||||
adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
|
||||
normalizeOffset: true // calls getBoundingClientRect for each event
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
mousewheel: function(fn) {
|
||||
return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
|
||||
},
|
||||
|
||||
unmousewheel: function(fn) {
|
||||
return this.unbind('mousewheel', fn);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function handler(event) {
|
||||
var orgEvent = event || window.event,
|
||||
args = slice.call(arguments, 1),
|
||||
delta = 0,
|
||||
deltaX = 0,
|
||||
deltaY = 0,
|
||||
absDelta = 0,
|
||||
offsetX = 0,
|
||||
offsetY = 0;
|
||||
event = $.event.fix(orgEvent);
|
||||
event.type = 'mousewheel';
|
||||
|
||||
// Old school scrollwheel delta
|
||||
if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
|
||||
if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
|
||||
if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
|
||||
if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
|
||||
|
||||
// Firefox < 17 horizontal scrolling related to DOMMouseScroll event
|
||||
if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
|
||||
deltaX = deltaY * -1;
|
||||
deltaY = 0;
|
||||
}
|
||||
|
||||
// Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
|
||||
delta = deltaY === 0 ? deltaX : deltaY;
|
||||
|
||||
// New school wheel delta (wheel event)
|
||||
if ( 'deltaY' in orgEvent ) {
|
||||
deltaY = orgEvent.deltaY * -1;
|
||||
delta = deltaY;
|
||||
}
|
||||
if ( 'deltaX' in orgEvent ) {
|
||||
deltaX = orgEvent.deltaX;
|
||||
if ( deltaY === 0 ) { delta = deltaX * -1; }
|
||||
}
|
||||
|
||||
// No change actually happened, no reason to go any further
|
||||
if ( deltaY === 0 && deltaX === 0 ) { return; }
|
||||
|
||||
// Need to convert lines and pages to pixels if we aren't already in pixels
|
||||
// There are three delta modes:
|
||||
// * deltaMode 0 is by pixels, nothing to do
|
||||
// * deltaMode 1 is by lines
|
||||
// * deltaMode 2 is by pages
|
||||
if ( orgEvent.deltaMode === 1 ) {
|
||||
var lineHeight = $.data(this, 'mousewheel-line-height');
|
||||
delta *= lineHeight;
|
||||
deltaY *= lineHeight;
|
||||
deltaX *= lineHeight;
|
||||
} else if ( orgEvent.deltaMode === 2 ) {
|
||||
var pageHeight = $.data(this, 'mousewheel-page-height');
|
||||
delta *= pageHeight;
|
||||
deltaY *= pageHeight;
|
||||
deltaX *= pageHeight;
|
||||
}
|
||||
|
||||
// Store lowest absolute delta to normalize the delta values
|
||||
absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
|
||||
|
||||
if ( !lowestDelta || absDelta < lowestDelta ) {
|
||||
lowestDelta = absDelta;
|
||||
|
||||
// Adjust older deltas if necessary
|
||||
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
|
||||
lowestDelta /= 40;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust older deltas if necessary
|
||||
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
|
||||
// Divide all the things by 40!
|
||||
delta /= 40;
|
||||
deltaX /= 40;
|
||||
deltaY /= 40;
|
||||
}
|
||||
|
||||
// Get a whole, normalized value for the deltas
|
||||
delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
|
||||
deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
|
||||
deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
|
||||
|
||||
// Normalise offsetX and offsetY properties
|
||||
if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
|
||||
var boundingRect = this.getBoundingClientRect();
|
||||
offsetX = event.clientX - boundingRect.left;
|
||||
offsetY = event.clientY - boundingRect.top;
|
||||
}
|
||||
|
||||
// Add information to the event object
|
||||
event.deltaX = deltaX;
|
||||
event.deltaY = deltaY;
|
||||
event.deltaFactor = lowestDelta;
|
||||
event.offsetX = offsetX;
|
||||
event.offsetY = offsetY;
|
||||
// Go ahead and set deltaMode to 0 since we converted to pixels
|
||||
// Although this is a little odd since we overwrite the deltaX/Y
|
||||
// properties with normalized deltas.
|
||||
event.deltaMode = 0;
|
||||
|
||||
// Add event and delta to the front of the arguments
|
||||
args.unshift(event, delta, deltaX, deltaY);
|
||||
|
||||
// Clearout lowestDelta after sometime to better
|
||||
// handle multiple device types that give different
|
||||
// a different lowestDelta
|
||||
// Ex: trackpad = 3 and mouse wheel = 120
|
||||
if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
|
||||
nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
|
||||
|
||||
return ($.event.dispatch || $.event.handle).apply(this, args);
|
||||
}
|
||||
|
||||
function nullLowestDelta() {
|
||||
lowestDelta = null;
|
||||
}
|
||||
|
||||
function shouldAdjustOldDeltas(orgEvent, absDelta) {
|
||||
// If this is an older event and the delta is divisable by 120,
|
||||
// then we are assuming that the browser is treating this as an
|
||||
// older mouse wheel event and that we should divide the deltas
|
||||
// by 40 to try and get a more usable deltaFactor.
|
||||
// Side note, this actually impacts the reported scroll distance
|
||||
// in older browsers and can cause scrolling to be slower than native.
|
||||
// Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
|
||||
return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
|
||||
}
|
||||
|
||||
}));
|
344
web_app/js/external/jquery.plugin.js
vendored
Normal file
344
web_app/js/external/jquery.plugin.js
vendored
Normal file
|
@ -0,0 +1,344 @@
|
|||
/* Simple JavaScript Inheritance
|
||||
* By John Resig http://ejohn.org/
|
||||
* MIT Licensed.
|
||||
*/
|
||||
// Inspired by base2 and Prototype
|
||||
(function(){
|
||||
var initializing = false;
|
||||
|
||||
// The base JQClass implementation (does nothing)
|
||||
window.JQClass = function(){};
|
||||
|
||||
// Collection of derived classes
|
||||
JQClass.classes = {};
|
||||
|
||||
// Create a new JQClass that inherits from this class
|
||||
JQClass.extend = function extender(prop) {
|
||||
var base = this.prototype;
|
||||
|
||||
// Instantiate a base class (but only create the instance,
|
||||
// don't run the init constructor)
|
||||
initializing = true;
|
||||
var prototype = new this();
|
||||
initializing = false;
|
||||
|
||||
// Copy the properties over onto the new prototype
|
||||
for (var name in prop) {
|
||||
// Check if we're overwriting an existing function
|
||||
prototype[name] = typeof prop[name] == 'function' &&
|
||||
typeof base[name] == 'function' ?
|
||||
(function(name, fn){
|
||||
return function() {
|
||||
var __super = this._super;
|
||||
|
||||
// Add a new ._super() method that is the same method
|
||||
// but on the super-class
|
||||
this._super = function(args) {
|
||||
return base[name].apply(this, args || []);
|
||||
};
|
||||
|
||||
var ret = fn.apply(this, arguments);
|
||||
|
||||
// The method only need to be bound temporarily, so we
|
||||
// remove it when we're done executing
|
||||
this._super = __super;
|
||||
|
||||
return ret;
|
||||
};
|
||||
})(name, prop[name]) :
|
||||
prop[name];
|
||||
}
|
||||
|
||||
// The dummy class constructor
|
||||
function JQClass() {
|
||||
// All construction is actually done in the init method
|
||||
if (!initializing && this._init) {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
// Populate our constructed prototype object
|
||||
JQClass.prototype = prototype;
|
||||
|
||||
// Enforce the constructor to be what we expect
|
||||
JQClass.prototype.constructor = JQClass;
|
||||
|
||||
// And make this class extendable
|
||||
JQClass.extend = extender;
|
||||
|
||||
return JQClass;
|
||||
};
|
||||
})();
|
||||
|
||||
(function($) { // Ensure $, encapsulate
|
||||
|
||||
/** Abstract base class for collection plugins v1.0.1.
|
||||
Written by Keith Wood (kbwood{at}iinet.com.au) December 2013.
|
||||
Licensed under the MIT (https://github.com/jquery/jquery/blob/master/LICENSE.txt) license.
|
||||
@module $.JQPlugin
|
||||
@abstract */
|
||||
JQClass.classes.JQPlugin = JQClass.extend({
|
||||
|
||||
/** Name to identify this plugin.
|
||||
@example name: 'tabs' */
|
||||
name: 'plugin',
|
||||
|
||||
/** Default options for instances of this plugin (default: {}).
|
||||
@example defaultOptions: {
|
||||
selectedClass: 'selected',
|
||||
triggers: 'click'
|
||||
} */
|
||||
defaultOptions: {},
|
||||
|
||||
/** Options dependent on the locale.
|
||||
Indexed by language and (optional) country code, with '' denoting the default language (English/US).
|
||||
@example regionalOptions: {
|
||||
'': {
|
||||
greeting: 'Hi'
|
||||
}
|
||||
} */
|
||||
regionalOptions: {},
|
||||
|
||||
/** Names of getter methods - those that can't be chained (default: []).
|
||||
@example _getters: ['activeTab'] */
|
||||
_getters: [],
|
||||
|
||||
/** Retrieve a marker class for affected elements.
|
||||
@private
|
||||
@return {string} The marker class. */
|
||||
_getMarker: function() {
|
||||
return 'is-' + this.name;
|
||||
},
|
||||
|
||||
/** Initialise the plugin.
|
||||
Create the jQuery bridge - plugin name <code>xyz</code>
|
||||
produces <code>$.xyz</code> and <code>$.fn.xyz</code>. */
|
||||
_init: function() {
|
||||
// Apply default localisations
|
||||
$.extend(this.defaultOptions, (this.regionalOptions && this.regionalOptions['']) || {});
|
||||
// Camel-case the name
|
||||
var jqName = camelCase(this.name);
|
||||
// Expose jQuery singleton manager
|
||||
$[jqName] = this;
|
||||
// Expose jQuery collection plugin
|
||||
$.fn[jqName] = function(options) {
|
||||
var otherArgs = Array.prototype.slice.call(arguments, 1);
|
||||
if ($[jqName]._isNotChained(options, otherArgs)) {
|
||||
return $[jqName][options].apply($[jqName], [this[0]].concat(otherArgs));
|
||||
}
|
||||
return this.each(function() {
|
||||
if (typeof options === 'string') {
|
||||
if (options[0] === '_' || !$[jqName][options]) {
|
||||
throw 'Unknown method: ' + options;
|
||||
}
|
||||
$[jqName][options].apply($[jqName], [this].concat(otherArgs));
|
||||
}
|
||||
else {
|
||||
$[jqName]._attach(this, options);
|
||||
}
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
/** Set default values for all subsequent instances.
|
||||
@param options {object} The new default options.
|
||||
@example $.plugin.setDefauls({name: value}) */
|
||||
setDefaults: function(options) {
|
||||
$.extend(this.defaultOptions, options || {});
|
||||
},
|
||||
|
||||
/** Determine whether a method is a getter and doesn't permit chaining.
|
||||
@private
|
||||
@param name {string} The method name.
|
||||
@param otherArgs {any[]} Any other arguments for the method.
|
||||
@return {boolean} True if this method is a getter, false otherwise. */
|
||||
_isNotChained: function(name, otherArgs) {
|
||||
if (name === 'option' && (otherArgs.length === 0 ||
|
||||
(otherArgs.length === 1 && typeof otherArgs[0] === 'string'))) {
|
||||
return true;
|
||||
}
|
||||
return $.inArray(name, this._getters) > -1;
|
||||
},
|
||||
|
||||
/** Initialise an element. Called internally only.
|
||||
Adds an instance object as data named for the plugin.
|
||||
@param elem {Element} The element to enhance.
|
||||
@param options {object} Overriding settings. */
|
||||
_attach: function(elem, options) {
|
||||
elem = $(elem);
|
||||
if (elem.hasClass(this._getMarker())) {
|
||||
return;
|
||||
}
|
||||
elem.addClass(this._getMarker());
|
||||
options = $.extend({}, this.defaultOptions, this._getMetadata(elem), options || {});
|
||||
var inst = $.extend({name: this.name, elem: elem, options: options},
|
||||
this._instSettings(elem, options));
|
||||
elem.data(this.name, inst); // Save instance against element
|
||||
this._postAttach(elem, inst);
|
||||
this.option(elem, options);
|
||||
},
|
||||
|
||||
/** Retrieve additional instance settings.
|
||||
Override this in a sub-class to provide extra settings.
|
||||
@param elem {jQuery} The current jQuery element.
|
||||
@param options {object} The instance options.
|
||||
@return {object} Any extra instance values.
|
||||
@example _instSettings: function(elem, options) {
|
||||
return {nav: elem.find(options.navSelector)};
|
||||
} */
|
||||
_instSettings: function(elem, options) {
|
||||
return {};
|
||||
},
|
||||
|
||||
/** Plugin specific post initialisation.
|
||||
Override this in a sub-class to perform extra activities.
|
||||
@param elem {jQuery} The current jQuery element.
|
||||
@param inst {object} The instance settings.
|
||||
@example _postAttach: function(elem, inst) {
|
||||
elem.on('click.' + this.name, function() {
|
||||
...
|
||||
});
|
||||
} */
|
||||
_postAttach: function(elem, inst) {
|
||||
},
|
||||
|
||||
/** Retrieve metadata configuration from the element.
|
||||
Metadata is specified as an attribute:
|
||||
<code>data-<plugin name>="<setting name>: '<value>', ..."</code>.
|
||||
Dates should be specified as strings in this format: 'new Date(y, m-1, d)'.
|
||||
@private
|
||||
@param elem {jQuery} The source element.
|
||||
@return {object} The inline configuration or {}. */
|
||||
_getMetadata: function(elem) {
|
||||
try {
|
||||
var data = elem.data(this.name.toLowerCase()) || '';
|
||||
data = data.replace(/'/g, '"');
|
||||
data = data.replace(/([a-zA-Z0-9]+):/g, function(match, group, i) {
|
||||
var count = data.substring(0, i).match(/"/g); // Handle embedded ':'
|
||||
return (!count || count.length % 2 === 0 ? '"' + group + '":' : group + ':');
|
||||
});
|
||||
data = $.parseJSON('{' + data + '}');
|
||||
for (var name in data) { // Convert dates
|
||||
var value = data[name];
|
||||
if (typeof value === 'string' && value.match(/^new Date\((.*)\)$/)) {
|
||||
data[name] = eval(value);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
catch (e) {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
|
||||
/** Retrieve the instance data for element.
|
||||
@param elem {Element} The source element.
|
||||
@return {object} The instance data or {}. */
|
||||
_getInst: function(elem) {
|
||||
return $(elem).data(this.name) || {};
|
||||
},
|
||||
|
||||
/** Retrieve or reconfigure the settings for a plugin.
|
||||
@param elem {Element} The source element.
|
||||
@param name {object|string} The collection of new option values or the name of a single option.
|
||||
@param [value] {any} The value for a single named option.
|
||||
@return {any|object} If retrieving a single value or all options.
|
||||
@example $(selector).plugin('option', 'name', value)
|
||||
$(selector).plugin('option', {name: value, ...})
|
||||
var value = $(selector).plugin('option', 'name')
|
||||
var options = $(selector).plugin('option') */
|
||||
option: function(elem, name, value) {
|
||||
elem = $(elem);
|
||||
var inst = elem.data(this.name);
|
||||
if (!name || (typeof name === 'string' && value == null)) {
|
||||
var options = (inst || {}).options;
|
||||
return (options && name ? options[name] : options);
|
||||
}
|
||||
if (!elem.hasClass(this._getMarker())) {
|
||||
return;
|
||||
}
|
||||
var options = name || {};
|
||||
if (typeof name === 'string') {
|
||||
options = {};
|
||||
options[name] = value;
|
||||
}
|
||||
this._optionsChanged(elem, inst, options);
|
||||
$.extend(inst.options, options);
|
||||
},
|
||||
|
||||
/** Plugin specific options processing.
|
||||
Old value available in <code>inst.options[name]</code>, new value in <code>options[name]</code>.
|
||||
Override this in a sub-class to perform extra activities.
|
||||
@param elem {jQuery} The current jQuery element.
|
||||
@param inst {object} The instance settings.
|
||||
@param options {object} The new options.
|
||||
@example _optionsChanged: function(elem, inst, options) {
|
||||
if (options.name != inst.options.name) {
|
||||
elem.removeClass(inst.options.name).addClass(options.name);
|
||||
}
|
||||
} */
|
||||
_optionsChanged: function(elem, inst, options) {
|
||||
},
|
||||
|
||||
/** Remove all trace of the plugin.
|
||||
Override <code>_preDestroy</code> for plugin-specific processing.
|
||||
@param elem {Element} The source element.
|
||||
@example $(selector).plugin('destroy') */
|
||||
destroy: function(elem) {
|
||||
elem = $(elem);
|
||||
if (!elem.hasClass(this._getMarker())) {
|
||||
return;
|
||||
}
|
||||
this._preDestroy(elem, this._getInst(elem));
|
||||
elem.removeData(this.name).removeClass(this._getMarker());
|
||||
},
|
||||
|
||||
/** Plugin specific pre destruction.
|
||||
Override this in a sub-class to perform extra activities and undo everything that was
|
||||
done in the <code>_postAttach</code> or <code>_optionsChanged</code> functions.
|
||||
@param elem {jQuery} The current jQuery element.
|
||||
@param inst {object} The instance settings.
|
||||
@example _preDestroy: function(elem, inst) {
|
||||
elem.off('.' + this.name);
|
||||
} */
|
||||
_preDestroy: function(elem, inst) {
|
||||
}
|
||||
});
|
||||
|
||||
/** Convert names from hyphenated to camel-case.
|
||||
@private
|
||||
@param value {string} The original hyphenated name.
|
||||
@return {string} The camel-case version. */
|
||||
function camelCase(name) {
|
||||
return name.replace(/-([a-z])/g, function(match, group) {
|
||||
return group.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
/** Expose the plugin base.
|
||||
@namespace "$.JQPlugin" */
|
||||
$.JQPlugin = {
|
||||
|
||||
/** Create a new collection plugin.
|
||||
@memberof "$.JQPlugin"
|
||||
@param [superClass='JQPlugin'] {string} The name of the parent class to inherit from.
|
||||
@param overrides {object} The property/function overrides for the new class.
|
||||
@example $.JQPlugin.createPlugin({
|
||||
name: 'tabs',
|
||||
defaultOptions: {selectedClass: 'selected'},
|
||||
_initSettings: function(elem, options) { return {...}; },
|
||||
_postAttach: function(elem, inst) { ... }
|
||||
}); */
|
||||
createPlugin: function(superClass, overrides) {
|
||||
if (typeof superClass === 'object') {
|
||||
overrides = superClass;
|
||||
superClass = 'JQPlugin';
|
||||
}
|
||||
superClass = camelCase(superClass);
|
||||
var className = camelCase(overrides.name);
|
||||
JQClass.classes[className] = JQClass.classes[superClass].extend(overrides);
|
||||
new JQClass.classes[className]();
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
6
web_app/js/external/jquery.timepicker.js
vendored
6
web_app/js/external/jquery.timepicker.js
vendored
|
@ -99,9 +99,9 @@
|
|||
var list = self.data('timepicker-list');
|
||||
|
||||
// check if input is readonly
|
||||
if (self.prop('readonly')) {
|
||||
return;
|
||||
}
|
||||
// if (self.prop('readonly')) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// check if list needs to be rendered
|
||||
if (!list || list.length === 0 || typeof settings.durationTime === 'function') {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,153 +1,238 @@
|
|||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="apple-touch-icon" href="apple-touch-icon.png" />
|
||||
<meta name="viewport" content="width=320, initial-scale=1, user-scalable=no">
|
||||
<meta name="generator" content="HTML Tidy for HTML5 for Mac OS X version 5.0.0">
|
||||
<link rel="apple-touch-icon" href="apple-touch-icon.png">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes"><!-- width=320 -->
|
||||
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
|
||||
<meta charset="utf-8">
|
||||
<title>SIF Tools</title>
|
||||
<link href="css/external/jquery-ui.css" rel="stylesheet">
|
||||
<link href="css/external/jquery-ui-timepicker-addon.css" rel="stylesheet">
|
||||
<link href="css/external/keyboard.css" rel="stylesheet">
|
||||
<link href="css/external/keyboard-previewkeyset.css" rel="stylesheet">
|
||||
<link href="css/external/jquery.timepicker.css" rel="stylesheet">
|
||||
<link href="css/sif-tools.css" rel="stylesheet">
|
||||
<script src="js/external/jquery.js"></script>
|
||||
<script src="js/external/jquery.keyboard.js"></script>
|
||||
<script src="js/external/jquery.keyboard.extension-all.js"></script>
|
||||
<script src="js/external/jquery-ui.js"></script>
|
||||
<script src="js/external/jquery.timepicker.js"></script>
|
||||
<script src="js/external/jquery-ui-sliderAccess.js"></script>
|
||||
<script src="js/external/moment.js"></script>
|
||||
<script src="js/external/sprintf.js"></script>
|
||||
<script src="js/external/twitterFetcher.js"></script>
|
||||
<script src="js/sif_tools.js"></script>
|
||||
<link href="css/external/jquery.keypad.css" rel="stylesheet">
|
||||
<link href="css/sif_tools.css" rel="stylesheet">
|
||||
<script src="js/external/jquery.js">
|
||||
</script>
|
||||
<script src="js/external/jquery.cookie.js">
|
||||
</script>
|
||||
<script src="js/external/jquery.plugin.js">
|
||||
</script>
|
||||
<script src="js/external/jquery.keypad.js">
|
||||
</script>
|
||||
<script src="js/external/jquery-ui.js">
|
||||
</script>
|
||||
<script src="js/external/jquery.timepicker.js">
|
||||
</script>
|
||||
<script src="js/external/jquery-ui-sliderAccess.js">
|
||||
</script>
|
||||
<script src="js/external/moment.js">
|
||||
</script>
|
||||
<script src="js/external/sprintf.js">
|
||||
</script>
|
||||
<script src="js/external/twitterFetcher.js">
|
||||
</script>
|
||||
<script src="js/sif_tools.js">
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="header" align="center">
|
||||
<h1>SIF Tools</h1>
|
||||
</div>
|
||||
|
||||
<div id="tabs">
|
||||
<ul>
|
||||
<li><a href="#tab-rank">Rank</a></li>
|
||||
<li><a href="#tab-love-gem">Gem</a></li>
|
||||
<li><a href="#tab-card-level">Card</a></li>
|
||||
<li><a href="#tab-event">Event</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="tab-rank">
|
||||
<div id="the-form" align="center">
|
||||
Current Rank: <input type="text" size="5" id="current_rank" name="current_rank" placeholder="rank" value="" />
|
||||
<br />
|
||||
Current EXP: <input type="text" size="5" id="current_exp" name="current_exp" placeholder="optional" value="" />
|
||||
<br />
|
||||
Desired Rank: <input type="text" size="5" id="desired_rank" name="desired_rank" placeholder="rank" value="" />
|
||||
<br />
|
||||
Game Version:
|
||||
<select id="game_version" name="game_version">
|
||||
<option value="EN">EN</option>
|
||||
<option value="JP">JP</option>
|
||||
</select>
|
||||
<br /><br />
|
||||
<div id="button-calculate-rank">Calculate</div>
|
||||
<br /><br />
|
||||
<div id="rank-calc-result-area">
|
||||
<h1>Results</h1>
|
||||
EXP required: <span id="rank-result-exp">-</span><br /><br />
|
||||
You will need to play the following number of songs in order to get this amount of EXP:<br /><br />
|
||||
EASY: <span id="rank-result-songs-easy">-</span><br />
|
||||
NORMAL: <span id="rank-result-songs-normal">-</span><br />
|
||||
HARD: <span id="rank-result-songs-hard">-</span><br />
|
||||
EXPERT: <span id="rank-result-songs-expert">-</span><br /><br/>
|
||||
At this rank you will have <span id="rank-results-lp">-</span> LP and <span id="rank-results-fp">-</span> friend slots.<br /><br />
|
||||
<div id="button-reset-rank">Reset</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-love-gem">
|
||||
<div id="love-gem-form" align="center">
|
||||
Current Gems: <input type="text" size="5" id="current_gems" name="current_gems" placeholder="optional" value="" />
|
||||
<br /><br />
|
||||
Mode:<br />
|
||||
<input type="radio" name="gem-mode" id="gem-mode" value="DATE" checked />Number of gems on date?<br />
|
||||
<input type="radio" name="gem-mode" id="gem-mode" value="GEMS" />Date when you get <i>x</i> gems?<br /><br />
|
||||
<div id="gem-date-area">
|
||||
Date: <input type="text" size="10" id="gem_desired_date" name="gem_desired_date" placeholder="MM/DD/YYYY" value="" />
|
||||
</div>
|
||||
<div id="gem-desired-gems-area">
|
||||
Desired gems: <input type="text" size="5" id="gem_desired_gems" name="gem_desired_gems" placeholder="gems" value="" />
|
||||
</div>
|
||||
<br /><br />
|
||||
<input type="checkbox" name="gems_verbose" id="gems_verbose" value="YES" />Verbose Mode<br />
|
||||
<br /><br />
|
||||
<div id="button-calculate-gems">Calculate</div>
|
||||
<br /><br />
|
||||
<div id="gem-calc-result-area">
|
||||
<h1>Results</h1>
|
||||
<span id="gem-result-summary">-</span><br /><br />
|
||||
<div id="gem-result-verbose-area">
|
||||
<div id="gem-result-textarea">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="button-reset-gems">Reset</div>
|
||||
</div>
|
||||
<div id="header" align="center">
|
||||
<h1>SIF Tools</h1>
|
||||
</div>
|
||||
|
||||
<div id="tab-card-level">
|
||||
<div id="love-gem-form" align="center">
|
||||
Card Rarity:
|
||||
<select id="card_rarity" name="card_rarity">
|
||||
<option value="N">N</option>
|
||||
<option value="R">R</option>
|
||||
<option value="SR">SR</option>
|
||||
<option value="UR">UR</option>
|
||||
</select>
|
||||
<br />
|
||||
Current Level: <input type="text" size="5" id="card_current_level" name="card_current_level" placeholder="level" value="" />
|
||||
<br />
|
||||
Current EXP: <input type="text" size="5" id="card_current_exp" name="card_current_exp" placeholder="optional" value="" />
|
||||
<br /><br />
|
||||
Mode:<br />
|
||||
<input type="radio" name="card-mode" id="card-mode" value="LEVEL" checked />EXP needed to level?<br />
|
||||
<input type="radio" name="card-mode" id="card-mode" value="EXP" />Final level after feeding?<br /><br />
|
||||
<div id="card-level-area">
|
||||
Desired level: <input type="text" size="5" id="card_desired_level" name="card_desired_level" placeholder="level" value="" />
|
||||
</div>
|
||||
<div id="card-exp-area">
|
||||
EXP: <input type="text" size="5" id="card_feed_exp" name="card_feed_exp" placeholder="exp" value="" />
|
||||
</div>
|
||||
<br /><br />
|
||||
<div id="button-calculate-card">Calculate</div>
|
||||
<br /><br />
|
||||
<div id="card-calc-result-area">
|
||||
<h1>Results</h1>
|
||||
<span id="card-result-summary">-</span><br /><br />
|
||||
<div id="button-reset-card">Reset</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tab-event">
|
||||
<div id="event-timer-form" align="center">
|
||||
<h3>Enter Event End Date/Time (in UTC):</h3><br />
|
||||
<input type="text" size="10" id="event_end_date" name="event_end_date" placeholder="MM/DD/YYYY" value="" />
|
||||
<input type="text" size="5" id="event_end_time" name="event_end_time" placeholder="HH:MM" value="" />
|
||||
<br /><br />
|
||||
<div id="button-start-stop-timer">Start Timer</div>
|
||||
<div id="timer_output_area" align="center">
|
||||
<h1>Timer Not Running</h1>
|
||||
<div id="tabs">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#tab-rank">Rank</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#tab-love-gem">Gems</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#tab-card-level">Cards</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#tab-event">Events</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div id="tab-rank">
|
||||
<div id="the-form" align="center">
|
||||
Current Rank: <input type="text" readonly="true" size="5" id="current_rank" name="current_rank" placeholder="rank" value=""><br>
|
||||
Current EXP: <input type="text" readonly="true" size="5" id="current_exp" name="current_exp" placeholder="optional" value=""><br>
|
||||
Desired Rank: <input type="text" readonly="true" size="5" id="desired_rank" name="desired_rank" placeholder="rank" value=""><br>
|
||||
Game Version: <select id="game_version" name="game_version">
|
||||
<option value="EN">
|
||||
EN
|
||||
</option>
|
||||
<option value="JP">
|
||||
JP
|
||||
</option>
|
||||
</select><br>
|
||||
<br>
|
||||
<div id="button-calculate-rank">
|
||||
Calculate
|
||||
</div><br>
|
||||
<br>
|
||||
<div id="rank-calc-result-area">
|
||||
<h1>Results</h1>EXP required: <span id="rank-result-exp">-</span><br>
|
||||
<br>
|
||||
You will need to play the following number of songs in order to get this amount of EXP:<br>
|
||||
<br>(Single / 3xMedFes / 3xMedFes w/EXP boost)<br /><br />
|
||||
EASY: <span id="rank-result-songs-easy">-</span> / <span id="rank-result-songs-easy-mf">-</span> / <span id="rank-result-songs-easy-mfb">-</span><br>
|
||||
NORMAL: <span id="rank-result-songs-normal">-</span> / <span id="rank-result-songs-normal-mf">-</span> / <span id="rank-result-songs-normal-mfb">-</span><br>
|
||||
HARD: <span id="rank-result-songs-hard">-</span> / <span id="rank-result-songs-hard-mf">-</span> / <span id="rank-result-songs-hard-mfb">-</span><br>
|
||||
EXPERT: <span id="rank-result-songs-expert">-</span> / <span id="rank-result-songs-expert-mf">-</span> / <span id="rank-result-songs-expert-mfb">-</span><br>
|
||||
<br>
|
||||
At this rank you will have <span id="rank-results-lp">-</span> LP and <span id="rank-results-fp">-</span> friend slots.<br>
|
||||
<br>
|
||||
<div id="button-reset-rank">
|
||||
Reset
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tier_info_output_area" align="center">
|
||||
<div id="tab-love-gem">
|
||||
<div id="love-gem-form" align="center">
|
||||
Current Gems: <input type="text" readonly="true" size="5" id="current_gems" name="current_gems" placeholder="optional" value=""><br>
|
||||
Game Version: <select id="gem_game_version" name="gem_game_version">
|
||||
<option value="EN">
|
||||
EN
|
||||
</option>
|
||||
<option value="JP">
|
||||
JP
|
||||
</option>
|
||||
</select><br>
|
||||
<br>
|
||||
<span id="gem_jp_daily_gems"><input type="checkbox" name="gems_include_daily_gems" id="gems_include_daily_gems" value="YES">Include daily "quest" gems?
|
||||
(<a href="#" id="gem_quest_readme">What is this?</a>)<br></span>
|
||||
<div id="gem_quest_readme_dialog" title="About JP Daily 'Quest' Gems" style="display: none;">
|
||||
<span id="gem_jp_daily_gems"></span>
|
||||
<p><span id="gem_jp_daily_gems">On JP, you can now obtain a gem every day by completing the following steps, in the following order:</span></p>
|
||||
<ol>
|
||||
<li><span id="gem_jp_daily_gems">Scout three Normal students. (The daily free scout counts.)</span></li>
|
||||
<li><span id="gem_jp_daily_gems">Clear five live shows (any difficulty.)</span></li>
|
||||
<li><span id="gem_jp_daily_gems">Practice ("feed") 5 cards of any kind.</span></li>
|
||||
<li><span id="gem_jp_daily_gems">Play a live show (any difficulty) and get a Full Combo.</span></li>
|
||||
</ol>
|
||||
</div><input type="checkbox" name="gems_include_events" id="gems_include_events" value="YES">Include gems from events? (<a href="#" id=
|
||||
"gem_event_readme">Read this first</a>)<br>
|
||||
<div id="gem-event-options-area" align="center">
|
||||
<div id="gem_event_readme_dialog" title="About the Event Gem Calculator" style="display: none;">
|
||||
<p>Due to the variable nature of events, calculation of gems gotten through events is at best an approximation. To make the calculations simpler,
|
||||
it assumes that each month has 2 events, ending on the 1st and the 15th, and events alternate between token events and score matches (and medley
|
||||
festivals if on JP.) Also, if you are tiering, it assumes that you will spend some gems to tier, and will use an estimate based on your average
|
||||
tier, but this will only be an estimate.)</p>
|
||||
</div>Average tier: <select id="gems_tier_level" name="gems_tier_level">
|
||||
<option value="1">
|
||||
Tier 1
|
||||
</option>
|
||||
<option value="2">
|
||||
Tier 2
|
||||
</option>
|
||||
<option value="0">
|
||||
Event SR only
|
||||
</option>
|
||||
</select>
|
||||
</div><br>
|
||||
Mode:<br>
|
||||
<input type="radio" name="gem-mode" id="gem-mode" class="option-button" value="DATE" checked>Number of gems you'll have on a date?<br>
|
||||
<input type="radio" name="gem-mode" id="gem-mode" class="option-button" value="GEMS">Date you will have this many gems?<br>
|
||||
<br>
|
||||
<div id="gem-date-area">
|
||||
Date: <input type="text" size="10" id="gem_desired_date" name="gem_desired_date" readonly="true" placeholder="MM/DD/YYYY" value="">
|
||||
</div>
|
||||
<div id="gem-desired-gems-area">
|
||||
Desired gems: <input type="text" readonly="true" size="5" id="gem_desired_gems" name="gem_desired_gems" placeholder="gems" value="">
|
||||
</div><br>
|
||||
<br>
|
||||
<input type="checkbox" name="gems_verbose" id="gems_verbose" value="YES">Verbose Mode<br>
|
||||
<br>
|
||||
<br>
|
||||
<div id="button-calculate-gems">
|
||||
Calculate
|
||||
</div><br>
|
||||
<br>
|
||||
<div id="gem-calc-result-area">
|
||||
<h1>Results</h1><span id="gem-result-summary">-</span><br>
|
||||
<br>
|
||||
<div id="gem-result-verbose-area">
|
||||
<div id="gem-result-textarea">
|
||||
-
|
||||
</div>
|
||||
</div>
|
||||
<div id="button-reset-gems">
|
||||
Reset
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="button-clear-timer">Clear Timer</div>
|
||||
</div>
|
||||
|
||||
<div id="error-dialog" title="Error">
|
||||
<p><span id="error-text" /></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tab-card-level">
|
||||
<div id="love-gem-form" align="center">
|
||||
Card Rarity: <select id="card_rarity" name="card_rarity">
|
||||
<option value="N">
|
||||
N
|
||||
</option>
|
||||
<option value="R">
|
||||
R
|
||||
</option>
|
||||
<option value="SR">
|
||||
SR
|
||||
</option>
|
||||
<option value="UR">
|
||||
UR
|
||||
</option>
|
||||
</select><br>
|
||||
Current Level: <input type="text" readonly="true" size="5" id="card_current_level" name="card_current_level" placeholder="level"
|
||||
value=""><br>
|
||||
Current EXP: <input type="text" readonly="true" size="5" id="card_current_exp" name="card_current_exp" placeholder="optional" value=
|
||||
""><br>
|
||||
<br>
|
||||
Mode:<br>
|
||||
<input type="radio" name="card-mode" id="card-mode" class="option-button" value="LEVEL" checked>EXP needed to get card to a level?<br>
|
||||
<input type="radio" name="card-mode" id="card-mode" class="option-button" value="EXP">Final level after feeding an amount of EXP?<br>
|
||||
<br>
|
||||
<div id="card-level-area">
|
||||
Desired level: <input type="text" readonly="true" size="5" id="card_desired_level" name="card_desired_level" placeholder="level"
|
||||
value="">
|
||||
<div id="button-card-max-level">Max</div>
|
||||
</div>
|
||||
<div id="card-exp-area">
|
||||
EXP: <input type="text" readonly="true" size="5" id="card_feed_exp" name="card_feed_exp" placeholder="exp" value="">
|
||||
</div><br>
|
||||
<input type="checkbox" name="card_same_attribute" id="card_same_attribute" value="YES">Assume cards are same attribute<br>
|
||||
<br>
|
||||
<div id="button-calculate-card">
|
||||
Calculate
|
||||
</div><br>
|
||||
<br>
|
||||
<div id="card-calc-result-area">
|
||||
<h1>Results</h1><span id="card-result-summary">-</span><br>
|
||||
<br>
|
||||
<div id="button-reset-card">
|
||||
Reset
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-event">
|
||||
<div id="event-timer-form" align="center">
|
||||
<h3>Enter Event End Date/Time (in UTC):</h3><br>
|
||||
<input type="text" size="10" id="event_end_date" name="event_end_date" readonly="true" placeholder="MM/DD/YYYY" value=""> <input type="text" size="5"
|
||||
id="event_end_time" name="event_end_time" readonly="true" placeholder="HH:MM" value=""><br>
|
||||
<br>
|
||||
<div id="button-start-stop-timer">
|
||||
Start Timer
|
||||
</div>
|
||||
<div id="timer_output_area" align="center">
|
||||
<h1>Timer Not Running</h1>
|
||||
</div>
|
||||
<div id="tier_info_output_area" align="center"></div>
|
||||
<div id="button-clear-timer">
|
||||
Clear Timer
|
||||
</div>
|
||||
</div>
|
||||
<div id="error-dialog" title="Error">
|
||||
<p><span id="error-text"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue