├── README.md
├── Example
├── page.css
└── index.html
├── index.html
├── calculator.min.js
├── calculator.js
├── style.css
└── knockout-2.1.0.js
/README.md:
--------------------------------------------------------------------------------
1 | # HTML5, CSS3 and JavaScript calculator
2 |
3 | This was a small project we did just to play around with some of the
4 | latest web tools, such as KnockoutJS. We wanted to design and build
5 | something that looked clean, used no images and with a small amount of code.
6 |
7 | The result was a simple calculator built with pure CSS and a little bit
8 | of JavaScript and [Knockout](http://knockoutjs.com/) love.
9 |
10 | The calculator also has keyboard support through your keyboard numpad.
11 |
12 | ## License
13 |
14 | Copyright (C) 2012 Ideaviate AB
15 |
16 | Permission is hereby granted, free of charge, to any person obtaining a copy
17 | of this software and associated documentation files (the "Software"), to deal
18 | in the Software without restriction, including without limitation the rights
19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 | copies of the Software, and to permit persons to whom the Software is
21 | furnished to do so, subject to the following conditions:
22 |
23 | The above copyright notice and this permission notice shall be included in all
24 | copies or substantial portions of the Software.
25 |
26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
30 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 |
--------------------------------------------------------------------------------
/Example/page.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | .body {
4 | color: #606471;
5 | font-family: Arial, Helvetica, sans-serif;
6 | font-size: 12px;
7 | }
8 |
9 | .header {
10 | height: 140px;
11 | line-height: 140px;
12 | text-align: center;
13 | }
14 |
15 | .article {
16 | -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.1);
17 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.1);
18 | box-shadow: inset 0 1px 1px rgba(0,0,0,.1);
19 | background-color: #9599AB;
20 | background-image: -moz-linear-gradient(right bottom,#8B92A8 0%,#F6E0CB 100%);
21 | background-image: -webkit-gradient(linear,right bottom, left top,color-stop(0, #8B92A8),color-stop(1, #F6E0CB));
22 | background: -webkit-linear-gradient(right bottom, #8B92A8 0%, #F6E0CB 100%);
23 | background: -o-linear-gradient(right bottom, #8B92A8 0%, #F6E0CB 100%);
24 | background: -ms-linear-gradient(right bottom, #8B92A8 0%, #F6E0CB 100%);
25 | background: linear-gradient(right bottom, #8B92A8 0%, #F6E0CB 100%);
26 | background-repeat: repeat-x;
27 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff8B92A8', endColorstr='#ffF6E0CB', GradientType=0);
28 | border-bottom: 1px solid #BDC0CA;
29 | border-top: 1px solid #BDC0CA;
30 | height: 450px;
31 | position: relative;
32 | }
33 |
34 | .demo.calculator {
35 | -moz-box-shadow: inset 0px 1px #7b839b, 0 2px 5px rgba(0,0,0,.5);
36 | -webkit-box-shadow: inset 0px 1px #7b839b, 0 2px 5px rgba(0,0,0,.5);
37 | box-shadow: inset 0px 1px #7b839b, 0 2px 5px rgba(0,0,0,.5);
38 | position: absolute;
39 | margin: auto;
40 | top: 0;
41 | left: 0;
42 | right: 0;
43 | bottom: 0;
44 | height: 218px;
45 | }
46 |
47 | .footer {
48 | color: #9B9DA7;
49 | padding: 60px 0;
50 | text-align: center;
51 | }
52 |
53 | .bold {
54 | font-weight: bold;
55 | }
56 | .h1 {
57 | font-size: 20px;
58 | }
59 |
60 | .p {
61 | margin-bottom: 8px;
62 | }
63 | .link {
64 | color: #6399F1;
65 | text-decoration: none;
66 | }
67 | .link:hover {
68 | text-decoration: underline;
69 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Calculator
5 |
6 |
7 |
8 |
9 |
10 |
13 |
c
14 |
⇤
15 |
±
16 |
÷
17 |
7
18 |
8
19 |
9
20 |
x
21 |
4
22 |
5
23 |
6
24 |
-
25 |
1
26 |
2
27 |
3
28 |
+
29 |
0
30 |
.
31 |
=
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Calculator
5 |
6 |
7 |
8 |
9 |
10 |
14 |
15 |
18 |
19 |
20 |
23 |
c
24 |
⇤
25 |
±
26 |
÷
27 |
7
28 |
8
29 |
9
30 |
x
31 |
4
32 |
5
33 |
6
34 |
-
35 |
1
36 |
2
37 |
3
38 |
+
39 |
0
40 |
.
41 |
=
42 |
43 |
44 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/calculator.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 Ideaviate AB
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 |
22 | var Calculator = function () {
23 | var a = this, b = 0, e;
24 | a.display = ko.observable("0");
25 | a.isShowingResult = ko.observable(!1);
26 | a.number = function (b, e) {
27 | var d = e.target.innerText;
28 | a.isShowingResult() && (a.clearDisplay(), a.isShowingResult(!1));
29 | "." == d && -1 < a.display().indexOf(".") || (d = "0" === a.display() && "." != d ? d : a.display() + d, a.display(d))
30 | };
31 | a.operator = function (c, f) {
32 | var d = f.target.innerText;
33 | if (!a.isShowingResult()) {
34 | switch (e) {
35 | case "+":
36 | b += parseFloat(a.display(), 10);
37 | break;
38 | case "-":
39 | b -= parseFloat(a.display(), 10);
40 | break;
41 | case "x":
42 | b *= parseFloat(a.display(), 10);
43 | break;
44 | case "\u00f7":
45 | b /= parseFloat(a.display(), 10);
46 | break;
47 | default:
48 | b = parseFloat(a.display(), 10)
49 | }
50 | }
51 | e && a.display(b);
52 | e = "=" === d ? null : d;
53 | a.isShowingResult(!0)
54 | };
55 | a.negate = function () {
56 | if (!(a.isShowingResult() || "0" === a.display())) {
57 | var b = "-" === a.display().substr(0, 1) ? a.display().substr(1) : "-" + a.display();
58 | a.display(b)
59 | }
60 | };
61 | a.backspace = function () {
62 | a.isShowingResult() || (1 < a.display().length ? a.display(a.display().substr(0, a.display().length - 1)) : a.clearDisplay())
63 | };
64 | a.clear = function () {
65 | e = null;
66 | a.clearDisplay();
67 | b = 0
68 | };
69 | a.clearDisplay = function () {
70 | a.display("0")
71 | }
72 | };
73 | ko.applyBindings(new Calculator);
74 | (function () {
75 | var a = { 48: "0", 49: "1", 50: "2", 51: "3", 52: "4", 53: "5", 54: "6", 55: "7", 56: "8", 57: "9", 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7", 104: "8", 105: "9", 106: "x", 107: "+", 109: "-", 110: ".", 111: "\u00f7", 8: "backspace", 13: "=", 46: "c", 67: "c" }, b = function (b) {
76 | if (b.keyCode in a) {
77 | var c = document.getElementById("calculator-button-" + a[b.keyCode]);
78 | c.className.match(/(\s|^)active(\s|$)/) || (c.className += " active");
79 | setTimeout(function () {
80 | c.className.match(/(\s|^)active(\s|$)/) && (c.className = c.className.replace(/(\s|^)active(\s|$)/, " "))
81 | }, 100);
82 | document.createEvent ? (b = document.createEvent("HTMLEvents"), b.initEvent("click", !0, !0), c.dispatchEvent(b)) : (b = document.createEventObject(), c.fireEvent("onclick", b))
83 | }
84 | };
85 | document.addEventListener ? document.addEventListener("keyup", b, !1) : document.attachEvent && document.attachEvent("keyup", b)
86 | })();
--------------------------------------------------------------------------------
/calculator.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2012 Ideaviate AB
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 | */
21 |
22 | var Calculator = function () {
23 |
24 | // Helper variable declarations
25 | var self = this,
26 | decimalMark = ".",
27 | sum = 0,
28 | prevOperator;
29 |
30 | // Define default values
31 | self.display = ko.observable("0");
32 | self.isShowingResult = ko.observable(false);
33 |
34 | // Callback for each number button
35 | self.number = function (item, event) {
36 | var button = event.target.innerText || event.target.textContent;
37 |
38 | // If a result has been shown, make sure we
39 | // clear the display before displaying any new numbers
40 | if (self.isShowingResult()) {
41 | self.clearDisplay();
42 | self.isShowingResult(false);
43 | }
44 |
45 | // Make sure we only add one decimal mark
46 | if (button == decimalMark && self.display().indexOf(decimalMark) > -1)
47 | return;
48 |
49 | // Make sure that we remove the default 0 shown on the display
50 | // when the user press the first number button
51 | var newValue = (self.display() === "0" && button != decimalMark) ? button : self.display() + button;
52 | // Update the display
53 | self.display(newValue);
54 | };
55 |
56 | // Callback for each operator button
57 | self.operator = function (item, event) {
58 | var button = event.target.innerText || event.target.textContent;
59 | // Only perform calculation if numbers
60 | // has been entered since last operator button was pressed
61 | if (!self.isShowingResult()) {
62 | // Perform calculation
63 | switch (prevOperator) {
64 | case "+":
65 | sum = sum + parseFloat(self.display(), 10);
66 | break;
67 | case "-":
68 | sum = sum - parseFloat(self.display(), 10);
69 | break;
70 | case "x":
71 | sum = sum * parseFloat(self.display(), 10);
72 | break;
73 | case "÷":
74 | sum = sum / parseFloat(self.display(), 10);
75 | break;
76 | default:
77 | sum = parseFloat(self.display(), 10);
78 | };
79 | }
80 |
81 | // Avoid showing a result until you have at least
82 | // two terms to perform calculation on
83 | if (prevOperator)
84 | self.display(sum);
85 |
86 | // Make sure we don't try to calculate with the equal sign
87 | prevOperator = (button === "=") ? null : button;
88 | // Always set the calculator into showing result state
89 | // after an operator button has been pressed
90 | self.isShowingResult(true);
91 | };
92 |
93 | // Callback for negating a number
94 | self.negate = function () {
95 | // Disable the negate button when showing a result
96 | if (self.isShowingResult() || self.display() === "0")
97 | return;
98 |
99 | var newValue = (self.display().substr(0, 1) === "-") ? self.display().substr(1) : "-" + self.display();
100 | self.display(newValue);
101 | };
102 |
103 | // Callback for each backspace button
104 | self.backspace = function (item, event) {
105 | // Disable backspace if the calculator is shown a result
106 | if (self.isShowingResult())
107 | return;
108 |
109 | // Remove the last character, and make the display zero when
110 | // last character is removed
111 | if (self.display().length > 1) {
112 | self.display(self.display().substr(0, self.display().length - 1));
113 | } else {
114 | self.clearDisplay();
115 | }
116 | };
117 |
118 | // Clear the entire calculator
119 | self.clear = function () {
120 | prevOperator = null;
121 | self.clearDisplay();
122 | sum = 0;
123 | };
124 |
125 | // Clear just the display
126 | self.clearDisplay = function () {
127 | self.display("0");
128 | };
129 | };
130 |
131 | // Apply knockout bindings
132 | ko.applyBindings(new Calculator());
133 |
134 | // Enable keyboard controll
135 | (function () {
136 | // Key codes and their associated calculator buttons
137 | var calculatorKeys = {
138 | 48: "0", 49: "1", 50: "2", 51: "3", 52: "4", 53: "5", 54: "6",
139 | 55: "7", 56: "8", 57: "9", 96: "0", 97: "1", 98: "2", 99: "3",
140 | 100: "4", 101: "5", 102: "6", 103: "7", 104: "8", 105: "9",
141 | 106: "x", 107: "+", 109: "-", 110: ".", 111: "÷", 8: "backspace",
142 | 13: "=", 46: "c", 67: "c"
143 | };
144 |
145 | // Helper function to fire an event on an element
146 | function fireEvent(element, event) {
147 | if (document.createEvent) {
148 | // Dispatch for firefox + others
149 | var evt = document.createEvent("HTMLEvents");
150 | evt.initEvent(event, true, true);
151 | return !element.dispatchEvent(evt);
152 | } else {
153 | // Dispatch for IE
154 | var evt = document.createEventObject();
155 | return element.fireEvent('on' + event, evt)
156 | }
157 | }
158 |
159 | // Helper functions to add/remove HTML-element classes
160 | // as IE didn't support the classList property prior to IE10
161 | function hasClass(ele, cls) {
162 | return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
163 | }
164 |
165 | function addClass(ele, cls) {
166 | if (!hasClass(ele, cls)) ele.className += " " + cls;
167 | }
168 |
169 | function removeClass(ele, cls) {
170 | if (hasClass(ele, cls)) {
171 | var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
172 | ele.className = ele.className.replace(reg, ' ');
173 | }
174 | }
175 |
176 | // Callback for every key stroke
177 | var keycallback = function (e) {
178 | // Check if the key was one of our calculator keys
179 | if (e.keyCode in calculatorKeys) {
180 | // Get button-element associated with key
181 | var element = document.getElementById("calculator-button-" + calculatorKeys[e.keyCode]);
182 | // Simulate button click on keystroke
183 | addClass(element, "active");
184 | setTimeout(function () { removeClass(element, "active"); }, 100);
185 | // Fire click event
186 | fireEvent(element, "click");
187 | }
188 | }
189 |
190 | // Attach a keyup-event listener on the document
191 | if (document.addEventListener) {
192 | document.addEventListener('keyup', keycallback, false);
193 | } else if (document.attachEvent) {
194 | document.attachEvent('keyup', keycallback);
195 | }
196 | })();
197 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 |
2 | /* #################
3 | * ### CSS Reset ###
4 | * ################# */
5 |
6 | html, body, div, span, applet, object, iframe,
7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8 | a, abbr, acronym, address, big, cite, code,
9 | del, dfn, em, img, ins, kbd, q, s, samp,
10 | small, strike, strong, sub, sup, tt, var,
11 | b, u, i, center,
12 | dl, dt, dd, ol, ul, li,
13 | fieldset, form, label, legend,
14 | table, caption, tbody, tfoot, thead, tr, th, td,
15 | article, aside, canvas, details, embed,
16 | figure, figcaption, footer, header, hgroup,
17 | menu, nav, output, ruby, section, summary,
18 | time, mark, audio, video {
19 | margin: 0;
20 | padding: 0;
21 | border: 0;
22 | font-size: 100%;
23 | font: inherit;
24 | vertical-align: baseline;
25 | }
26 | /* HTML5 display-role reset for older browsers */
27 | article, aside, details, figcaption, figure,
28 | footer, header, hgroup, menu, nav, section {
29 | display: block;
30 | }
31 | body {
32 | line-height: 1;
33 | }
34 | ol, ul {
35 | list-style: none;
36 | }
37 | blockquote, q {
38 | quotes: none;
39 | }
40 | blockquote:before, blockquote:after,
41 | q:before, q:after {
42 | content: '';
43 | content: none;
44 | }
45 | table {
46 | border-collapse: collapse;
47 | border-spacing: 0;
48 | }
49 | /* End of CSS Reset */
50 |
51 |
52 |
53 |
54 | /* #########################
55 | * ### Calculator styles ###
56 | * ######################### */
57 |
58 | /* Grid units */
59 | .u1,
60 | .u2,
61 | .u3,
62 | .u4 {
63 | float: left;
64 | margin: 3px;
65 | }
66 | .u1 {
67 | width: 40px;
68 | }
69 | .u2 {
70 | width: 86px;
71 | }
72 | .u3 {
73 | width: 132px;
74 | }
75 | .u4 {
76 | width: 178px;
77 | }
78 |
79 | .calculator {
80 | -moz-border-radius: 5px;
81 | -webkit-border-radius: 5px;
82 | border-radius: 5px;
83 | -moz-box-shadow: inset 0px 1px #7b839b;
84 | -webkit-box-shadow: inset 0px 1px #7b839b;
85 | box-shadow: inset 0px 1px #7b839b;
86 | background-color: #3C4150;
87 | border: 1px solid #181A20;
88 | float: left;
89 | padding: 6px;
90 | width: 184px;
91 | }
92 |
93 | .display {
94 | -moz-border-radius: 3px;
95 | -webkit-border-radius: 3px;
96 | border-radius: 3px;
97 | -moz-box-shadow: inset 0 1px 1px #0A0B0D, 0px 1px #5E6370;
98 | -webkit-box-shadow: inset 0 1px 1px #0A0B0D, 0px 1px #5E6370;
99 | box-shadow: inset 0 1px 1px #0A0B0D, 0px 1px #5E6370;
100 | -webkit-box-sizing: border-box;
101 | -moz-box-sizing: border-box;
102 | box-sizing: border-box;
103 | background-color: #17181E;
104 | border: 1px solid #181A20;
105 | padding: 0 10px;
106 | text-align: right;
107 | }
108 | .display-text {
109 | color: #fff;
110 | font-size: 22px;
111 | line-height: 42px;
112 | overflow: hidden;
113 | unicode-bidi: embed;
114 | width: 1000px;
115 | float: right;
116 | }
117 | .display-inner {
118 | width: 156px;
119 | overflow: hidden;
120 | }
121 | .button {
122 | -moz-border-radius: 3px;
123 | -webkit-border-radius: 3px;
124 | border-radius: 3px;
125 | -webkit-touch-callout: none;
126 | -webkit-user-select: none;
127 | -khtml-user-select: none;
128 | -moz-user-select: none;
129 | -ms-user-select: none;
130 | user-select: none;
131 | border: 1px solid #181A20;
132 | color: #fff;
133 | cursor: pointer;
134 | float: left;
135 | font-family: Arial, Helvetica, sans-serif;
136 | font-size: 12px;
137 | font-weight: bold;
138 | line-height: 25px;
139 | padding: 0 8px;
140 | text-align: center;
141 | text-decoration: none;
142 | vertical-align: middle;
143 | }
144 | .button:active,
145 | .button-active {
146 | position: relative;
147 | top: 1px;
148 | }
149 | .button:active,
150 | .button:focus {
151 | outline: 0;
152 | }
153 | /* Mozilla fix */
154 | button::-moz-focus-inner {
155 | padding: 0;
156 | border: 0;
157 | }
158 |
159 | /* Buttons styling exceptions */
160 | .button-backspace {
161 | font-size: 17px;
162 | font-weight: normal;
163 | }
164 |
165 |
166 | /* Button skins */
167 | .button-gray {
168 | -moz-box-shadow: inset 0px 1px #9498A3, 0 1px 1px #323643;
169 | -webkit-box-shadow: inset 0px 1px #9498A3, 0 1px 1px #323643;
170 | box-shadow: inset 0px 1px #9498A3, 0 1px 1px #323643;
171 | background-color: #595E6B;
172 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#656976), to(#4B505E));
173 | background-image: -webkit-linear-gradient(top, #656976, #4B505E);
174 | background-image: -o-linear-gradient(top, #656976, #4B505E);
175 | background-image: linear-gradient(to bottom, #656976, #4B505E);
176 | background-image: -moz-linear-gradient(top, #656976, #4B505E);
177 | background-repeat: repeat-x;
178 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff656976', endColorstr='#ff4B505E', GradientType=0);
179 | text-shadow: 0px -1px #181A20;
180 | }
181 | .button-gray:hover {
182 | background-color: #666B78;
183 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#757985), to(#545867));
184 | background-image: -webkit-linear-gradient(top, #757985, #545867);
185 | background-image: -o-linear-gradient(top, #757985, #545867);
186 | background-image: linear-gradient(to bottom, #757985, #545867);
187 | background-image: -moz-linear-gradient(top, #757985, #545867);
188 | background-repeat: repeat-x;
189 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff757985', endColorstr='#ff545867', GradientType=0);
190 | }
191 | .button-gray.active,
192 | .button-gray:active {
193 | -webkit-box-shadow: inset 0 1px 1px #14171E, 0px 1px #5E6370;
194 | -moz-box-shadow: inset 0 1px 1px #14171E, 0px 1px #5E6370;
195 | box-shadow: inset 0 1px 1px #14171E, 0px 1px #5E6370;
196 | background-color: #292D3A;
197 | background-image: none;
198 | filter: progid:dximagetransform.microsoft.gradient(enabled=false);
199 | }
200 | .button-red {
201 | -moz-box-shadow: inset 0px 1px #CA9883, 0 1px 1px #323643;
202 | -webkit-box-shadow: inset 0px 1px #CA9883, 0 1px 1px #323643;
203 | box-shadow: inset 0px 1px #CA9883, 0 1px 1px #323643;
204 | background-color: #965F48;
205 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#A46E57), to(#844D37));
206 | background-image: -webkit-linear-gradient(top, #A46E57, #844D37);
207 | background-image: -o-linear-gradient(top, #A46E57, #844D37);
208 | background-image: linear-gradient(to bottom, #A46E57, #844D37);
209 | background-image: -moz-linear-gradient(top, #A46E57, #844D37);
210 | background-repeat: repeat-x;
211 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffA46E57', endColorstr='#ff844D37', GradientType=0);
212 | text-shadow: 0px -1px #58372A;
213 | }
214 | .button-red:hover {
215 | background-color: #A26B55;
216 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#B4806A), to(#915740));
217 | background-image: -webkit-linear-gradient(top, #B4806A, #915740);
218 | background-image: -o-linear-gradient(top, #B4806A, #915740);
219 | background-image: linear-gradient(to bottom, #B4806A, #915740);
220 | background-image: -moz-linear-gradient(top, #B4806A, #915740);
221 | background-repeat: repeat-x;
222 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffB4806A', endColorstr='#ff915740', GradientType=0);
223 | }
224 | .button-red.active,
225 | .button-red:active {
226 | -webkit-box-shadow: inset 0 1px 1px #2A130C, 0px 1px #5E6370;
227 | -moz-box-shadow: inset 0 1px 1px #2A130C, 0px 1px #5E6370;
228 | box-shadow: inset 0 1px 1px #2A130C, 0px 1px #5E6370;
229 | background-color: #472619;
230 | background-image: none;
231 | filter: progid:dximagetransform.microsoft.gradient(enabled=false);
232 | }
233 | .button-blue {
234 | -moz-box-shadow: inset 0px 1px #BCD6FF, 0 1px 1px #323643;
235 | -webkit-box-shadow: inset 0px 1px #BCD6FF, 0 1px 1px #323643;
236 | box-shadow: inset 0px 1px #BCD6FF, 0 1px 1px #323643;
237 | background-color: #598FE9;
238 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#6DA1F8), to(#427BD8));
239 | background-image: -webkit-linear-gradient(top, #6DA1F8, #427BD8);
240 | background-image: -o-linear-gradient(top, #6DA1F8, #427BD8);
241 | background-image: linear-gradient(to bottom, #6DA1F8, #427BD8);
242 | background-image: -moz-linear-gradient(top, #6DA1F8, #427BD8);
243 | background-repeat: repeat-x;
244 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff6DA1F8', endColorstr='#ff427BD8', GradientType=0);
245 | text-shadow: 0px -1px #2C4E88;
246 | }
247 | .button-blue:hover {
248 | background-color: #6E9EED;
249 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#83B0FC), to(#578ADE));
250 | background-image: -webkit-linear-gradient(top, #83B0FC, #578ADE);
251 | background-image: -o-linear-gradient(top, #83B0FC, #578ADE);
252 | background-image: linear-gradient(to bottom, #83B0FC, #578ADE);
253 | background-image: -moz-linear-gradient(top, #83B0FC, #578ADE);
254 | background-repeat: repeat-x;
255 | filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ff83B0FC', endColorstr='#ff578ADE', GradientType=0);
256 | }
257 | .button-blue.active,
258 | .button-blue:active {
259 | -webkit-box-shadow: inset 0 1px 1px #0E192E, 0px 1px #5E6370;
260 | -moz-box-shadow: inset 0 1px 1px #0E192E, 0px 1px #5E6370;
261 | box-shadow: inset 0 1px 1px #0E192E, 0px 1px #5E6370;
262 | background-color: #1E3357;
263 | background-image: none;
264 | filter: progid:dximagetransform.microsoft.gradient(enabled=false);
265 | }
266 |
267 |
268 |
269 |
--------------------------------------------------------------------------------
/knockout-2.1.0.js:
--------------------------------------------------------------------------------
1 | // Knockout JavaScript library v2.1.0
2 | // (c) Steven Sanderson - http://knockoutjs.com/
3 | // License: MIT (http://www.opensource.org/licenses/mit-license.php)
4 |
5 | (function(window,document,navigator,undefined){
6 | function m(w){throw w;}var n=void 0,p=!0,s=null,t=!1;function A(w){return function(){return w}};function E(w){function B(b,c,d){d&&c!==a.k.r(b)&&a.k.S(b,c);c!==a.k.r(b)&&a.a.va(b,"change")}var a="undefined"!==typeof w?w:{};a.b=function(b,c){for(var d=b.split("."),f=a,g=0;g ",c[0];);return 4a.a.j(c,b[e])&&c.push(b[e]);return c},T:function(a,b){for(var a=a||[],c=[],
9 | e=0,f=a.length;ea.length?t:a.substring(0,b.length)===b},eb:function(a,b){for(var c="return ("+a+")",e=0;e",""]||!d.indexOf(""," "]||(!d.indexOf(" "," "]||[0,"",""];b="ignored"+d[1]+b+d[2]+"
";for("function"==typeof window.innerShiv?c.appendChild(window.innerShiv(b)):c.innerHTML=b;d[0]--;)c=c.lastChild;c=a.a.L(c.lastChild.childNodes)}return c};
24 | a.a.Y=function(b,c){a.a.ga(b);if(c!==s&&c!==n)if("string"!=typeof c&&(c=c.toString()),"undefined"!=typeof jQuery)jQuery(b).html(c);else for(var d=a.a.pa(c),f=0;f"},Va:function(a,b){var c=d[a];c===n&&m(Error("Couldn't find any memo with ID "+a+". Perhaps it's already been unmemoized."));try{return c.apply(s,b||[]),p}finally{delete d[a]}},Wa:function(b,d){var e=[];c(b,e);for(var h=0,j=e.length;hc;c++)b=b();return b})};a.toJSON=function(b,c,e){b=a.Ta(b);return a.a.sa(b,c,e)}})();a.b("toJS",a.Ta);a.b("toJSON",a.toJSON);(function(){a.k={r:function(b){switch(a.a.o(b)){case "option":return b.__ko__hasDomDataOptionValue__===p?a.a.f.get(b,a.c.options.oa):b.getAttribute("value");case "select":return 0<=b.selectedIndex?a.k.r(b.options[b.selectedIndex]):n;default:return b.value}},S:function(b,c){switch(a.a.o(b)){case "option":switch(typeof c){case "string":a.a.f.set(b,a.c.options.oa,
39 | n);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=c;break;default:a.a.f.set(b,a.c.options.oa,c),b.__ko__hasDomDataOptionValue__=p,b.value="number"===typeof c?c:""}break;case "select":for(var d=b.options.length-1;0<=d;d--)if(a.k.r(b.options[d])==c){b.selectedIndex=d;break}break;default:if(c===s||c===n)c="";b.value=c}}}})();a.b("selectExtensions",a.k);a.b("selectExtensions.readValue",a.k.r);a.b("selectExtensions.writeValue",a.k.S);a.g=function(){function b(a,b){for(var d=
40 | s;a!=d;)d=a,a=a.replace(c,function(a,c){return b[c]});return a}var c=/\@ko_token_(\d+)\@/g,d=/^[\_$a-z][\_$a-z0-9]*(\[.*?\])*(\.[\_$a-z][\_$a-z0-9]*(\[.*?\])*)*$/i,f=["true","false"];return{D:[],W:function(c){var e=a.a.w(c);if(3>e.length)return[];"{"===e.charAt(0)&&(e=e.substring(1,e.length-1));for(var c=[],d=s,f,k=0;k$/:
45 | /^\s*ko\s+(.*\:.*)\s*$/,h=g?/^<\!--\s*\/ko\s*--\>$/:/^\s*\/ko\s*$/,j={ul:p,ol:p};a.e={C:{},childNodes:function(a){return b(a)?d(a):a.childNodes},ha:function(c){if(b(c))for(var c=a.e.childNodes(c),e=0,d=c.length;e "),t))}};a.c.uniqueName.gb=0;a.c.checked={init:function(b,c,d){a.a.n(b,"click",function(){var f;if("checkbox"==b.type)f=b.checked;else if("radio"==b.type&&b.checked)f=b.value;else return;var g=c();"checkbox"==b.type&&a.a.d(g)instanceof Array?(f=a.a.j(a.a.d(g),b.value),
62 | b.checked&&0>f?g.push(b.value):!b.checked&&0<=f&&g.splice(f,1)):a.g.$(g,d,"checked",f,p)});"radio"==b.type&&!b.name&&a.c.uniqueName.init(b,A(p))},update:function(b,c){var d=a.a.d(c());"checkbox"==b.type?b.checked=d instanceof Array?0<=a.a.j(d,b.value):d:"radio"==b.type&&(b.checked=b.value==d)}};var F={"class":"className","for":"htmlFor"};a.c.attr={update:function(b,c){var d=a.a.d(c())||{},f;for(f in d)if("string"==typeof f){var g=a.a.d(d[f]),e=g===t||g===s||g===n;e&&b.removeAttribute(f);8>=a.a.ja&&
63 | f in F?(f=F[f],e?b.removeAttribute(f):b[f]=g):e||b.setAttribute(f,g.toString())}}};a.c.hasfocus={init:function(b,c,d){function f(b){var e=c();a.g.$(e,d,"hasfocus",b,p)}a.a.n(b,"focus",function(){f(p)});a.a.n(b,"focusin",function(){f(p)});a.a.n(b,"blur",function(){f(t)});a.a.n(b,"focusout",function(){f(t)})},update:function(b,c){var d=a.a.d(c());d?b.focus():b.blur();a.a.va(b,d?"focusin":"focusout")}};a.c["with"]={p:function(b){return function(){var c=b();return{"if":c,data:c,templateEngine:a.q.K}}},
64 | init:function(b,c){return a.c.template.init(b,a.c["with"].p(c))},update:function(b,c,d,f,g){return a.c.template.update(b,a.c["with"].p(c),d,f,g)}};a.g.D["with"]=t;a.e.C["with"]=p;a.c["if"]={p:function(b){return function(){return{"if":b(),templateEngine:a.q.K}}},init:function(b,c){return a.c.template.init(b,a.c["if"].p(c))},update:function(b,c,d,f,g){return a.c.template.update(b,a.c["if"].p(c),d,f,g)}};a.g.D["if"]=t;a.e.C["if"]=p;a.c.ifnot={p:function(b){return function(){return{ifnot:b(),templateEngine:a.q.K}}},
65 | init:function(b,c){return a.c.template.init(b,a.c.ifnot.p(c))},update:function(b,c,d,f,g){return a.c.template.update(b,a.c.ifnot.p(c),d,f,g)}};a.g.D.ifnot=t;a.e.C.ifnot=p;a.c.foreach={p:function(b){return function(){var c=a.a.d(b());return!c||"number"==typeof c.length?{foreach:c,templateEngine:a.q.K}:{foreach:c.data,includeDestroyed:c.includeDestroyed,afterAdd:c.afterAdd,beforeRemove:c.beforeRemove,afterRender:c.afterRender,templateEngine:a.q.K}}},init:function(b,c){return a.c.template.init(b,a.c.foreach.p(c))},
66 | update:function(b,c,d,f,g){return a.c.template.update(b,a.c.foreach.p(c),d,f,g)}};a.g.D.foreach=t;a.e.C.foreach=p;a.t=function(){};a.t.prototype.renderTemplateSource=function(){m(Error("Override renderTemplateSource"))};a.t.prototype.createJavaScriptEvaluatorBlock=function(){m(Error("Override createJavaScriptEvaluatorBlock"))};a.t.prototype.makeTemplateSource=function(b,c){if("string"==typeof b){var c=c||document,d=c.getElementById(b);d||m(Error("Cannot find template with ID "+b));return new a.l.i(d)}if(1==
67 | b.nodeType||8==b.nodeType)return new a.l.M(b);m(Error("Unknown template type: "+b))};a.t.prototype.renderTemplate=function(a,c,d,f){return this.renderTemplateSource(this.makeTemplateSource(a,f),c,d)};a.t.prototype.isTemplateRewritten=function(a,c){return this.allowTemplateRewriting===t||!(c&&c!=document)&&this.V&&this.V[a]?p:this.makeTemplateSource(a,c).data("isRewritten")};a.t.prototype.rewriteTemplate=function(a,c,d){var f=this.makeTemplateSource(a,d),c=c(f.text());f.text(c);f.data("isRewritten",
68 | p);!(d&&d!=document)&&"string"==typeof a&&(this.V=this.V||{},this.V[a]=p)};a.b("templateEngine",a.t);a.Z=function(){function b(b,c,e){for(var b=a.g.W(b),d=a.g.D,j=0;j/g;return{mb:function(b,c,e){c.isTemplateRewritten(b,e)||c.rewriteTemplate(b,function(b){return a.Z.zb(b,c)},e)},zb:function(a,g){return a.replace(c,function(a,c,d,f,i,l,q){return b(q,c,g)}).replace(d,function(a,c){return b(c,"<\!-- ko --\>",g)})},Za:function(b){return a.s.na(function(c,
70 | e){c.nextSibling&&a.ya(c.nextSibling,b,e)})}}}();a.b("templateRewriting",a.Z);a.b("templateRewriting.applyMemoizedBindingsToNextSibling",a.Z.Za);(function(){a.l={};a.l.i=function(a){this.i=a};a.l.i.prototype.text=function(){var b=a.a.o(this.i),b="script"===b?"text":"textarea"===b?"value":"innerHTML";if(0==arguments.length)return this.i[b];var c=arguments[0];"innerHTML"===b?a.a.Y(this.i,c):this.i[b]=c};a.l.i.prototype.data=function(b){if(1===arguments.length)return a.a.f.get(this.i,"templateSourceData_"+
71 | b);a.a.f.set(this.i,"templateSourceData_"+b,arguments[1])};a.l.M=function(a){this.i=a};a.l.M.prototype=new a.l.i;a.l.M.prototype.text=function(){if(0==arguments.length){var b=a.a.f.get(this.i,"__ko_anon_template__")||{};b.ua===n&&b.da&&(b.ua=b.da.innerHTML);return b.ua}a.a.f.set(this.i,"__ko_anon_template__",{ua:arguments[0]})};a.l.i.prototype.nodes=function(){if(0==arguments.length)return(a.a.f.get(this.i,"__ko_anon_template__")||{}).da;a.a.f.set(this.i,"__ko_anon_template__",{da:arguments[0]})};
72 | a.b("templateSources",a.l);a.b("templateSources.domElement",a.l.i);a.b("templateSources.anonymousTemplate",a.l.M)})();(function(){function b(b,c,d){for(var f,c=a.e.nextSibling(c);b&&(f=b)!==c;)b=a.e.nextSibling(f),(1===f.nodeType||8===f.nodeType)&&d(f)}function c(c,d){if(c.length){var f=c[0],g=c[c.length-1];b(f,g,function(b){a.xa(d,b)});b(f,g,function(b){a.s.Wa(b,[d])})}}function d(a){return a.nodeType?a:0a.a.ja)&&b.nodes?b.nodes():s;
83 | if(c)return a.a.L(c.cloneNode(p).childNodes);b=b.text();return a.a.pa(b)};a.q.K=new a.q;a.ra(a.q.K);a.b("nativeTemplateEngine",a.q);(function(){a.ma=function(){var a=this.vb=function(){if("undefined"==typeof jQuery||!jQuery.tmpl)return 0;try{if(0<=jQuery.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b,f,g){g=g||{};2>a&&m(Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later."));var e=b.data("precompiled");
84 | e||(e=b.text()||"",e=jQuery.template(s,"{{ko_with $item.koBindingContext}}"+e+"{{/ko_with}}"),b.data("precompiled",e));b=[f.$data];f=jQuery.extend({koBindingContext:f},g.templateOptions);f=jQuery.tmpl(e,b,f);f.appendTo(document.createElement("div"));jQuery.fragments={};return f};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){document.write("