· 6 years ago · Feb 27, 2020, 12:16 PM
1doogs dice prettied up by Nix
2(function e(t, n, r) {
3 function s(o, u) {
4 if (!n[o]) {
5 if (!t[o]) {
6 var a = typeof require == "function" && require;
7 if (!u && a) return a(o, !0);
8 if (i) return i(o, !0);
9 var f = new Error("Cannot find module '" + o + "'");
10 throw f.code = "MODULE_NOT_FOUND", f
11 }
12 var l = n[o] = {
13 exports: {}
14 };
15 t[o][0].call(l.exports, function(e) {
16 var n = t[o][1][e];
17 return s(n ? n : e)
18 }, l, l.exports, e, t, n, r)
19 }
20 return n[o].exports
21 }
22 var i = typeof require == "function" && require;
23 for (var o = 0; o < r.length; o++) s(r[o]);
24 return s
25})({
26 1: [function(require, module, exports) {
27 module.exports = function(window, undefined) {
28 "use strict";
29 var _valueRanges = {
30 rgb: {
31 r: [0, 255],
32 g: [0, 255],
33 b: [0, 255]
34 },
35 hsv: {
36 h: [0, 360],
37 s: [0, 100],
38 v: [0, 100]
39 },
40 hsl: {
41 h: [0, 360],
42 s: [0, 100],
43 l: [0, 100]
44 },
45 alpha: {
46 alpha: [0, 1]
47 },
48 HEX: {
49 HEX: [0, 16777215]
50 }
51 },
52 _instance = {},
53 _colors = {},
54 grey = {
55 r: .298954,
56 g: .586434,
57 b: .114612
58 },
59 luminance = {
60 r: .2126,
61 g: .7152,
62 b: .0722
63 },
64 Colors = window.Colors = function(options) {
65 this.colors = {
66 RND: {}
67 };
68 this.options = {
69 color: "rgba(204, 82, 37, 0.8)",
70 grey: grey,
71 luminance: luminance,
72 valueRanges: _valueRanges
73 };
74 initInstance(this, options || {})
75 },
76 initInstance = function(THIS, options) {
77 var importColor, _options = THIS.options,
78 customBG;
79 focusInstance(THIS);
80 for (var option in options) {
81 if (options[option] !== undefined) _options[option] = options[option]
82 }
83 customBG = _options.customBG;
84 _options.customBG = typeof customBG === "string" ? ColorConverter.txt2color(customBG).rgb : customBG;
85 _colors = setColor(THIS.colors, _options.color, undefined, true)
86 },
87 focusInstance = function(THIS) {
88 if (_instance !== THIS) {
89 _instance = THIS;
90 _colors = THIS.colors
91 }
92 };
93 Colors.prototype.setColor = function(newCol, type, alpha) {
94 focusInstance(this);
95 if (newCol) {
96 return setColor(this.colors, newCol, type, undefined, alpha)
97 } else {
98 if (alpha !== undefined) {
99 this.colors.alpha = alpha
100 }
101 return convertColors(type)
102 }
103 };
104 Colors.prototype.setCustomBackground = function(col) {
105 focusInstance(this);
106 this.options.customBG = typeof col === "string" ? ColorConverter.txt2color(col).rgb : col;
107 return setColor(this.colors, undefined, "rgb")
108 };
109 Colors.prototype.saveAsBackground = function() {
110 focusInstance(this);
111 return setColor(this.colors, undefined, "rgb", true)
112 };
113
114 function setColor(colors, color, type, save, alpha) {
115 if (typeof color === "string") {
116 var color = ColorConverter.txt2color(color);
117 type = color.type;
118 _colors[type] = color[type];
119 alpha = alpha !== undefined ? alpha : color.alpha
120 } else if (color) {
121 for (var n in color) {
122 colors[type][n] = limitValue(color[n] / _valueRanges[type][n][1], 0, 1)
123 }
124 }
125 if (alpha !== undefined) {
126 colors.alpha = +alpha
127 }
128 return convertColors(type, save ? colors : undefined)
129 }
130
131 function saveAsBackground(RGB, rgb, alpha) {
132 var grey = _instance.options.grey,
133 color = {};
134 color.RGB = {
135 r: RGB.r,
136 g: RGB.g,
137 b: RGB.b
138 };
139 color.rgb = {
140 r: rgb.r,
141 g: rgb.g,
142 b: rgb.b
143 };
144 color.alpha = alpha;
145 color.equivalentGrey = Math.round(grey.r * RGB.r + grey.g * RGB.g + grey.b * RGB.b);
146 color.rgbaMixBlack = mixColors(rgb, {
147 r: 0,
148 g: 0,
149 b: 0
150 }, alpha, 1);
151 color.rgbaMixWhite = mixColors(rgb, {
152 r: 1,
153 g: 1,
154 b: 1
155 }, alpha, 1);
156 color.rgbaMixBlack.luminance = getLuminance(color.rgbaMixBlack, true);
157 color.rgbaMixWhite.luminance = getLuminance(color.rgbaMixWhite, true);
158 if (_instance.options.customBG) {
159 color.rgbaMixCustom = mixColors(rgb, _instance.options.customBG, alpha, 1);
160 color.rgbaMixCustom.luminance = getLuminance(color.rgbaMixCustom, true);
161 _instance.options.customBG.luminance = getLuminance(_instance.options.customBG, true)
162 }
163 return color
164 }
165
166 function convertColors(type, colorObj) {
167 var colors = colorObj || _colors,
168 convert = ColorConverter,
169 options = _instance.options,
170 ranges = _valueRanges,
171 RND = colors.RND,
172 modes, mode = "",
173 from = "",
174 exceptions = {
175 hsl: "hsv",
176 rgb: type
177 },
178 RGB = RND.rgb,
179 SAVE, SMART;
180 if (type !== "alpha") {
181 for (var typ in ranges) {
182 if (!ranges[typ][typ]) {
183 if (type !== typ) {
184 from = exceptions[typ] || "rgb";
185 colors[typ] = convert[from + "2" + typ](colors[from])
186 }
187 if (!RND[typ]) RND[typ] = {};
188 modes = colors[typ];
189 for (mode in modes) {
190 RND[typ][mode] = Math.round(modes[mode] * ranges[typ][mode][1])
191 }
192 }
193 }
194 RGB = RND.rgb;
195 colors.HEX = convert.RGB2HEX(RGB);
196 colors.equivalentGrey = options.grey.r * colors.rgb.r + options.grey.g * colors.rgb.g + options.grey.b * colors.rgb.b;
197 colors.webSave = SAVE = getClosestWebColor(RGB, 51);
198 colors.webSmart = SMART = getClosestWebColor(RGB, 17);
199 colors.saveColor = RGB.r === SAVE.r && RGB.g === SAVE.g && RGB.b === SAVE.b ? "web save" : RGB.r === SMART.r && RGB.g === SMART.g && RGB.b === SMART.b ? "web smart" : "";
200 colors.hueRGB = ColorConverter.hue2RGB(colors.hsv.h);
201 if (colorObj) {
202 colors.background = saveAsBackground(RGB, colors.rgb, colors.alpha)
203 }
204 }
205 var rgb = colors.rgb,
206 alpha = colors.alpha,
207 luminance = "luminance",
208 background = colors.background,
209 rgbaMixBlack, rgbaMixWhite, rgbaMixCustom, rgbaMixBG, rgbaMixBGMixBlack, rgbaMixBGMixWhite, rgbaMixBGMixCustom;
210 rgbaMixBlack = mixColors(rgb, {
211 r: 0,
212 g: 0,
213 b: 0
214 }, alpha, 1);
215 rgbaMixBlack[luminance] = getLuminance(rgbaMixBlack, true);
216 colors.rgbaMixBlack = rgbaMixBlack;
217 rgbaMixWhite = mixColors(rgb, {
218 r: 1,
219 g: 1,
220 b: 1
221 }, alpha, 1);
222 rgbaMixWhite[luminance] = getLuminance(rgbaMixWhite, true);
223 colors.rgbaMixWhite = rgbaMixWhite;
224 if (options.customBG) {
225 rgbaMixBGMixCustom = mixColors(rgb, background.rgbaMixCustom, alpha, 1);
226 rgbaMixBGMixCustom[luminance] = getLuminance(rgbaMixBGMixCustom, true);
227 rgbaMixBGMixCustom.WCAG2Ratio = getWCAG2Ratio(rgbaMixBGMixCustom[luminance], background.rgbaMixCustom[luminance]);
228 colors.rgbaMixBGMixCustom = rgbaMixBGMixCustom;
229 rgbaMixBGMixCustom.luminanceDelta = Math.abs(rgbaMixBGMixCustom[luminance] - background.rgbaMixCustom[luminance]);
230 rgbaMixBGMixCustom.hueDelta = getHueDelta(background.rgbaMixCustom, rgbaMixBGMixCustom, true)
231 }
232 colors.RGBLuminance = getLuminance(RGB);
233 colors.HUELuminance = getLuminance(colors.hueRGB);
234 if (options.convertCallback) {
235 options.convertCallback(colors, type)
236 }
237 return colors
238 }
239 var ColorConverter = {
240 txt2color: function(txt) {
241 var color = {},
242 parts = txt.replace(/(?:#|\)|%)/g, "").split("("),
243 values = (parts[1] || "").split(/,\s*/),
244 type = parts[1] ? parts[0].substr(0, 3) : "rgb",
245 m = "";
246 color.type = type;
247 color[type] = {};
248 if (parts[1]) {
249 for (var n = 3; n--;) {
250 m = type[n] || type.charAt(n);
251 color[type][m] = +values[n] / _valueRanges[type][m][1]
252 }
253 } else {
254 color.rgb = ColorConverter.HEX2rgb(parts[0])
255 }
256 color.alpha = values[3] ? +values[3] : 1;
257 return color
258 },
259 RGB2HEX: function(RGB) {
260 return ((RGB.r < 16 ? "0" : "") + RGB.r.toString(16) + (RGB.g < 16 ? "0" : "") + RGB.g.toString(16) + (RGB.b < 16 ? "0" : "") + RGB.b.toString(16)).toUpperCase()
261 },
262 HEX2rgb: function(HEX) {
263 HEX = HEX.split("");
264 return {
265 r: parseInt(HEX[0] + HEX[HEX[3] ? 1 : 0], 16) / 255,
266 g: parseInt(HEX[HEX[3] ? 2 : 1] + (HEX[3] || HEX[1]), 16) / 255,
267 b: parseInt((HEX[4] || HEX[2]) + (HEX[5] || HEX[2]), 16) / 255
268 }
269 },
270 hue2RGB: function(hue) {
271 var h = hue * 6,
272 mod = ~~h % 6,
273 i = h === 6 ? 0 : h - mod;
274 return {
275 r: Math.round([1, 1 - i, 0, 0, i, 1][mod] * 255),
276 g: Math.round([i, 1, 1, 1 - i, 0, 0][mod] * 255),
277 b: Math.round([0, 0, i, 1, 1, 1 - i][mod] * 255)
278 }
279 },
280 rgb2hsv: function(rgb) {
281 var r = rgb.r,
282 g = rgb.g,
283 b = rgb.b,
284 k = 0,
285 chroma, min, s;
286 if (g < b) {
287 g = b + (b = g, 0);
288 k = -1
289 }
290 min = b;
291 if (r < g) {
292 r = g + (g = r, 0);
293 k = -2 / 6 - k;
294 min = Math.min(g, b)
295 }
296 chroma = r - min;
297 s = r ? chroma / r : 0;
298 return {
299 h: s < 1e-15 ? _colors && _colors.hsl && _colors.hsl.h || 0 : chroma ? Math.abs(k + (g - b) / (6 * chroma)) : 0,
300 s: r ? chroma / r : _colors && _colors.hsv && _colors.hsv.s || 0,
301 v: r
302 }
303 },
304 hsv2rgb: function(hsv) {
305 var h = hsv.h * 6,
306 s = hsv.s,
307 v = hsv.v,
308 i = ~~h,
309 f = h - i,
310 p = v * (1 - s),
311 q = v * (1 - f * s),
312 t = v * (1 - (1 - f) * s),
313 mod = i % 6;
314 return {
315 r: [v, q, p, p, t, v][mod],
316 g: [t, v, v, q, p, p][mod],
317 b: [p, p, t, v, v, q][mod]
318 }
319 },
320 hsv2hsl: function(hsv) {
321 var l = (2 - hsv.s) * hsv.v,
322 s = hsv.s * hsv.v;
323 s = !hsv.s ? 0 : l < 1 ? l ? s / l : 0 : s / (2 - l);
324 return {
325 h: hsv.h,
326 s: !hsv.v && !s ? _colors && _colors.hsl && _colors.hsl.s || 0 : s,
327 l: l / 2
328 }
329 },
330 rgb2hsl: function(rgb, dependent) {
331 var hsv = ColorConverter.rgb2hsv(rgb);
332 return ColorConverter.hsv2hsl(dependent ? hsv : _colors.hsv = hsv)
333 },
334 hsl2rgb: function(hsl) {
335 var h = hsl.h * 6,
336 s = hsl.s,
337 l = hsl.l,
338 v = l < .5 ? l * (1 + s) : l + s - s * l,
339 m = l + l - v,
340 sv = v ? (v - m) / v : 0,
341 sextant = ~~h,
342 fract = h - sextant,
343 vsf = v * sv * fract,
344 t = m + vsf,
345 q = v - vsf,
346 mod = sextant % 6;
347 return {
348 r: [v, q, m, m, t, v][mod],
349 g: [t, v, v, q, m, m][mod],
350 b: [m, m, t, v, v, q][mod]
351 }
352 }
353 };
354
355 function getClosestWebColor(RGB, val) {
356 var out = {},
357 tmp = 0,
358 half = val / 2;
359 for (var n in RGB) {
360 tmp = RGB[n] % val;
361 out[n] = RGB[n] + (tmp > half ? val - tmp : -tmp)
362 }
363 return out
364 }
365
366 function getHueDelta(rgb1, rgb2, nominal) {
367 return (Math.max(rgb1.r - rgb2.r, rgb2.r - rgb1.r) + Math.max(rgb1.g - rgb2.g, rgb2.g - rgb1.g) + Math.max(rgb1.b - rgb2.b, rgb2.b - rgb1.b)) * (nominal ? 255 : 1) / 765
368 }
369
370 function getLuminance(rgb, normalized) {
371 var div = normalized ? 1 : 255,
372 RGB = [rgb.r / div, rgb.g / div, rgb.b / div],
373 luminance = _instance.options.luminance;
374 for (var i = RGB.length; i--;) {
375 RGB[i] = RGB[i] <= .03928 ? RGB[i] / 12.92 : Math.pow((RGB[i] + .055) / 1.055, 2.4)
376 }
377 return luminance.r * RGB[0] + luminance.g * RGB[1] + luminance.b * RGB[2]
378 }
379
380 function mixColors(topColor, bottomColor, topAlpha, bottomAlpha) {
381 var newColor = {},
382 alphaTop = topAlpha !== undefined ? topAlpha : 1,
383 alphaBottom = bottomAlpha !== undefined ? bottomAlpha : 1,
384 alpha = alphaTop + alphaBottom * (1 - alphaTop);
385 for (var n in topColor) {
386 newColor[n] = (topColor[n] * alphaTop + bottomColor[n] * alphaBottom * (1 - alphaTop)) / alpha
387 }
388 newColor.a = alpha;
389 return newColor
390 }
391
392 function getWCAG2Ratio(lum1, lum2) {
393 var ratio = 1;
394 if (lum1 >= lum2) {
395 ratio = (lum1 + .05) / (lum2 + .05)
396 } else {
397 ratio = (lum2 + .05) / (lum1 + .05)
398 }
399 return Math.round(ratio * 100) / 100
400 }
401
402 function limitValue(value, min, max) {
403 return value > max ? max : value < min ? min : value
404 }
405 }
406 }, {}],
407 2: [function(require, module, exports) {
408 "use strict";
409 var CryptoJS = require("./sha256"),
410 moment = require("./moment");
411 require("./jquery.animate-colors")($);
412 require("./jquery.hotkeys")($);
413 require("./jquery.fancybox")(window, document, $);
414 require("./colors")(window);
415 require("./jqColorPicker")($, Colors);
416 window.moment = moment;
417 var client_version = 379,
418 currency = "CLAM",
419 re = new RegExp("^\\s*([0-9]+[.]?[0-9]*|[0-9]*[.]?[0-9]+)\\s*$"),
420 re2 = new RegExp("^\\s*$"),
421 re3 = new RegExp("^\\s*[.0]+\\s*$"),
422 re4 = new RegExp("^\\s*0[0-9]"),
423 chat_scroll_freeze_time = 60,
424 scroll_on_chat, fixup_delay = 3,
425 bet_wait_timeout = 15 * 1e3,
426 nick, socket, investment, invest_pct, fee, csrf, profit_offset = 0,
427 real_profit = 0,
428 username, offsite = 0,
429 stake_profit = 0,
430 max_profit = 0,
431 withdraw_address = "",
432 current_tab, chatlog, chatbets, chatbets_showing = false,
433 chatscroll, chatbetscroll, chatinput, google_auth, settings = {},
434 default_alert_words, ignores = [],
435 news, edge, max_chance, default_chat_min = 8,
436 lastchat = [""],
437 lastchat_index = 0,
438 lastchat_max = 100,
439 lastwhich, nonce, uid, chatbetcount = 0,
440 chatbetmin = 500,
441 chatbetmax = 600,
442 chatlogcount = 0,
443 chatlogmin = 500,
444 chatlogmax = 600,
445 chatinput_class = 0,
446 debug_chat_scrolling = false,
447 user_regexp, style, template, color_editor;
448 var edge_mult = 1.01,
449 seed_length = 24,
450 max_name_length = 15,
451 results_to_keep = 100,
452 luck_precision = 2,
453 ga_fields = ["login", "withdraw", "invest", "divest", "edit", "manage api keys", "play", "randomize"];
454
455 function global_bindings_enabled() {
456 if ($.fancybox.isOpen) {
457 msg("Keyboard shortcuts are disabled while a dialog box is open.");
458 return false
459 }
460 if (current_tab == "#chat" || current_tab == "#account") {
461 msg("Keyboard shortcuts are disabled in the '" + current_tab.substring(1) + "' tab to prevent accidental betting.");
462 return false
463 }
464 if (!settings.shortcuts) {
465 msg("You have disabled keyboard shortcuts using a setting in the 'accounts' tab.");
466 return false
467 }
468 clear_msg();
469 return true
470 }
471 var styles = {
472 style_default: {},
473 style_dark: {
474 body_bgcolor: "#000",
475 body_fgcolor: "#090",
476 link_fgcolor: "inherit",
477 input_fgcolor: "inherit",
478 input_bgcolor: "#000",
479 input_border_color: "#999999",
480 selection_color: "#666",
481 ad_border_color: "#000000",
482 logo_bgcolor: "#333",
483 logo_border_color: "#666",
484 msg_bgcolor: "#333",
485 msg_border_color: "#666",
486 bet_button_fgcolor: "inherit",
487 bet_button_bgcolor_normal: "#333",
488 bet_button_bgcolor_hover: "#555",
489 bet_button_bgcolor_active: "#666",
490 bet_button_border_color: "#999",
491 bet_button_invalid_bgcolor: "#633",
492 bet_button_invalid_border_color: "#966",
493 bet_button_waiting_bgcolor: "#363",
494 bet_button_inactive_bgcolor: "#242",
495 shortcut_shadow_color: "#000000",
496 shortcut_bgcolor: "#448844",
497 shortcut_border_color: "#000000",
498 button_group_outline_bgcolor: "#666",
499 button_group_outline_border_color: "#666",
500 bet_toggle_button_bgcolor_normal: "#333",
501 bet_toggle_button_bgcolor_hover: "#666",
502 bet_toggle_button_bgcolor_active: "#999",
503 bet_toggle_button_border_color: "#999",
504 bet_inputs_group_bgcolor: "#666",
505 bet_inputs_label_bgcolor: "#333",
506 bet_inputs_label_border_color: "#666",
507 bet_inputs_border_color: "#777",
508 bet_invalid_color: "#600",
509 bet_warning_color: "#640",
510 balance_bgcolor: "#333",
511 balance_color: "#inherit",
512 balance_border_color: "#666",
513 mono_bgcolor: "#444",
514 mono_border_color: "#777",
515 max_profit_bgcolor: "#333",
516 max_profit_border_color: "#666",
517 tab_attention_color_normal: "#633",
518 tab_attention_color_hover: "#744",
519 tab_mentioned_color_normal: "#363",
520 tab_mentioned_color_hover: "#474",
521 tab_color_normal: "inherit",
522 tab_bgcolor_normal: "#222",
523 tab_color_hover: "inherit",
524 tab_bgcolor_hover: "#333",
525 tab_color_active: "inherit",
526 tab_bgcolor_active: "#444",
527 tab_border_color: "#555",
528 tabbed_panel_bgcolor: "#222",
529 tabbed_panel_border_color: "#666",
530 results_header_bgcolor: "#333",
531 results_header_border_color: "#666",
532 all_results_bgcolor: "#111",
533 my_results_bgcolor: "#222",
534 result_all_lose_color: "#444",
535 result_all_win_color: "#960",
536 result_lose_color: "#bd1d1d",
537 result_win_color: "#008800",
538 trailing_zero_color_all: "#131",
539 trailing_zero_color_me: "#242",
540 chat_ding_bgcolor: "#000",
541 chat_ding_color: "#0b0",
542 chat_emote_bgcolor: "#000",
543 chat_emote_color: "inherit",
544 chat_info_bgcolor: "#000",
545 chat_info_color: "inherit",
546 chat_lose_bgcolor: "#000",
547 chat_lose_color: "inherit",
548 chat_me_bgcolor: "#000",
549 chat_me_color: "inherit",
550 chat_mod_bgcolor: "#000",
551 chat_mod_color: "inherit",
552 chat_pm_bgcolor: "#000",
553 chat_pm_color: "inherit",
554 chat_princess_bgcolor: "#000",
555 chat_princess_color: "#500060",
556 chat_princess_emote_bgcolor: "#000",
557 chat_princess_emote_color: "#500060",
558 chat_stake_bgcolor: "#000",
559 chat_stake_color: "inherit",
560 chat_win_bgcolor: "#000",
561 chat_win_color: "inherit",
562 chat_name_bgcolor_normal: "inherit",
563 chat_name_bgcolor_hover: "#e5ceed",
564 chat_bgcolor: "#222",
565 chat_border_color: "#666",
566 chat_input_border_color: "#666",
567 button_fgcolor: "inherit",
568 button_bgcolor_normal: "#333",
569 button_bgcolor_hover: "#555",
570 button_bgcolor_active: "#666",
571 button_border_color: "#666",
572 mono_fgcolor: "inherit",
573 edit_ga_border_color: "inherit",
574 history_header_bgcolor: "#333",
575 history_table_even_bgcolor: "#444",
576 history_table_odd_bgcolor: "#555",
577 faq_bgcolor: "#333",
578 faq_border_color: "#666",
579 welcome_border_color: "#444444",
580 roll_border_color: "#444444",
581 deposit_border_color: "#444444",
582 withdraw_border_color: "#444444",
583 fb_bgcolor: "#222222"
584 }
585 };
586 var default_style = {
587 body_bgcolor: "#999999",
588 body_fgcolor: "#000000",
589 link_fgcolor: "inherit",
590 input_fgcolor: "inherit",
591 input_bgcolor: "#ffffff",
592 input_border_color: "#999999",
593 selection_color: "#ccffcc",
594 ad_border_color: "#000000",
595 logo_bgcolor: "#bbbbbb",
596 logo_border_color: "#777777",
597 msg_bgcolor: "#bbbbbb",
598 msg_border_color: "#777777",
599 bet_button_fgcolor: "inherit",
600 bet_button_bgcolor_normal: "#ccffcc",
601 bet_button_bgcolor_hover: "#aaddaa",
602 bet_button_bgcolor_active: "#88bb88",
603 bet_button_border_color: "#88aa88",
604 bet_button_invalid_bgcolor: "#ffcccc",
605 bet_button_invalid_border_color: "#cc9999",
606 bet_button_waiting_bgcolor: "#66aa66",
607 bet_button_inactive_bgcolor: "#66aa66",
608 shortcut_shadow_color: "#000000",
609 shortcut_bgcolor: "#448844",
610 shortcut_border_color: "#000000",
611 button_group_outline_bgcolor: "#777777",
612 button_group_outline_border_color: "#777777",
613 bet_toggle_button_bgcolor_normal: "#dddddd",
614 bet_toggle_button_bgcolor_hover: "#bbbbbb",
615 bet_toggle_button_bgcolor_active: "#999999",
616 bet_toggle_button_border_color: "#bbbbbb",
617 bet_inputs_group_bgcolor: "#999999",
618 bet_inputs_label_bgcolor: "#dddddd",
619 bet_inputs_label_border_color: "#999999",
620 bet_inputs_border_color: "#777777",
621 bet_invalid_color: "#ffcccc",
622 bet_warning_color: "#ffcc00",
623 balance_bgcolor: "#cccccc",
624 balance_color: "#448844",
625 balance_border_color: "#888888",
626 mono_bgcolor: "#cccccc",
627 mono_border_color: "#777777",
628 max_profit_bgcolor: "#aaaaaa",
629 max_profit_border_color: "#888888",
630 tab_attention_color_normal: "#ddaaaa",
631 tab_attention_color_hover: "#ffcccc",
632 tab_mentioned_color_normal: "#aaddaa",
633 tab_mentioned_color_hover: "#ccffcc",
634 tab_color_normal: "#444444",
635 tab_bgcolor_normal: "#aaaaaa",
636 tab_color_hover: "#222222",
637 tab_bgcolor_hover: "#cccccc",
638 tab_color_active: "#000000",
639 tab_bgcolor_active: "#eeeeee",
640 tab_border_color: "#444444",
641 tabbed_panel_bgcolor: "#b0b0b0",
642 tabbed_panel_border_color: "#777777",
643 results_header_bgcolor: "#aaaaaa",
644 results_header_border_color: "#000000",
645 all_results_bgcolor: "#b0b0b0",
646 my_results_bgcolor: "#d0d0d0",
647 result_all_lose_color: "#444444",
648 result_all_win_color: "#996600",
649 result_lose_color: "#bd1d1d",
650 result_win_color: "#008800",
651 trailing_zero_color_all: "#888888",
652 trailing_zero_color_me: "#909090",
653 chat_ding_bgcolor: "#eeeedd",
654 chat_ding_color: "inherit",
655 chat_emote_bgcolor: "#ffddaa",
656 chat_emote_color: "inherit",
657 chat_info_bgcolor: "#e5ceed",
658 chat_info_color: "inherit",
659 chat_lose_bgcolor: "#ffe8e8",
660 chat_lose_color: "inherit",
661 chat_me_bgcolor: "#eeeedd",
662 chat_me_color: "inherit",
663 chat_mod_bgcolor: "#ffffc0",
664 chat_mod_color: "inherit",
665 chat_pm_bgcolor: "#e0e0ff",
666 chat_pm_color: "inherit",
667 chat_princess_bgcolor: "inherit",
668 chat_princess_color: "#500060",
669 chat_princess_emote_bgcolor: "#ef9fff",
670 chat_princess_emote_color: "#700080",
671 chat_stake_bgcolor: "#d7dcfa",
672 chat_stake_color: "inherit",
673 chat_win_bgcolor: "#e8ffe8",
674 chat_win_color: "inherit",
675 chat_name_bgcolor_normal: "inherit",
676 chat_name_bgcolor_hover: "#e5ceed",
677 chat_bgcolor: "#ffffff",
678 chat_border_color: "#000000",
679 chat_input_border_color: "#000000",
680 button_fgcolor: "#000000",
681 button_bgcolor_normal: "#cccccc",
682 button_bgcolor_hover: "#aaaaaa",
683 button_bgcolor_active: "#888888",
684 button_border_color: "#888888",
685 mono_fgcolor: "inherit",
686 edit_ga_border_color: "#777777",
687 history_header_bgcolor: "#888888",
688 history_table_even_bgcolor: "#aaaaaa",
689 history_table_odd_bgcolor: "#bbbbbb",
690 faq_bgcolor: "#cccccc",
691 faq_border_color: "#666666",
692 welcome_border_color: "#444444",
693 roll_border_color: "#444444",
694 deposit_border_color: "#444444",
695 withdraw_border_color: "#444444",
696 fb_bgcolor: "#f9f9f9"
697 };
698
699 function init_pickers() {
700 $(".picker").colorPicker({
701 buildCallback: function($elm) {
702 var colorInstance = this.color,
703 colorPicker = this;
704 $elm.prepend('<div class="cp-panel">' + 'R <input type="text" class="cp-r" /><br>' + 'G <input type="text" class="cp-g" /><br>' + 'B <input type="text" class="cp-b" /><hr>' + 'H <input type="text" class="cp-h" /><br>' + 'S <input type="text" class="cp-s" /><br>' + 'B <input type="text" class="cp-v" /><hr>' + '<input type="text" class="cp-HEX" />' + "</div>").on("change", "input", function(e) {
705 var value = this.value,
706 className = this.className,
707 type = className.split("-")[1],
708 color = {};
709 color[type] = value;
710 colorInstance.setColor(type === "HEX" ? value : color, type === "HEX" ? "HEX" : /(?:r|g|b)/.test(type) ? "rgb" : "hsv");
711 colorPicker.render();
712 this.blur()
713 })
714 },
715 cssAddon: ".cp-color-picker{box-sizing:border-box; width:250px;}" + ".cp-color-picker .cp-panel {line-height: 21px; float:right;" + "padding:0 1px 0 8px; margin-top:-1px; overflow:visible}" + ".cp-xy-slider:active {cursor:none;}" + ".cp-xy-slider{width:152px; height:152px;}" + ".cp-z-slider{height:152px}" + ".cp-panel, .cp-panel input {color:#bbb; font-family:monospace," + '"Courier New",Courier,mono; font-size:12px; font-weight:bold;}' + ".cp-panel input {width:32px; padding:2px 3px 1px;" + "text-align:right; line-height:12px; background:transparent;" + "border:1px solid; border-color:#222 #666 #666 #222;}" + ".cp-panel hr {margin:0 -2px 2px; height:1px; border:0;" + "background:#666; border-top:1px solid #222;}" + ".cp-panel .cp-HEX {width:50px; position:absolute; margin:1px -3px 0 -2px;}",
716 renderCallback: function($elm, toggled) {
717 var colors = this.color.colors.RND,
718 hex = this.color.colors.HEX,
719 modes = {
720 r: colors.rgb.r,
721 g: colors.rgb.g,
722 b: colors.rgb.b,
723 h: colors.hsv.h,
724 s: colors.hsv.s,
725 v: colors.hsv.v,
726 HEX: this.color.colors.HEX
727 };
728 $("input", ".cp-panel").each(function() {
729 this.value = modes[this.className.substr(3)]
730 });
731 hex = "#" + hex;
732 $elm.css({
733 background: hex,
734 color: this.color.colors.rgbaMixBGMixCustom.luminance > .22 ? "#222" : "#ddd"
735 });
736 current_style[$elm.html()] = hex;
737 switch_style(current_style);
738 return true
739 },
740 opacity: false
741 })
742 }
743 $(document).ready(function() {
744 template = '::selection { background: {selection_color};}::-moz-selection { background: {selection_color};}body { font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; overflow-y: scroll; opacity: 1; background: {body_bgcolor} url(/images/bg.png) left top; background-size: 63.5%; color: {body_fgcolor};}.wrapper { width: 950px; margin: 0 auto;}.wrapper2 { width: 840px; margin: 0 auto;}h1 { padding: 0 40px 0 30px;}h2 { margin-top: 0px;}h3 { margin: 1ex 0 2ex 0; padding: 0 40px 0 30px;}pre { font-size: 90%;}.panel li { margin: 1em;}.panel p { line-height: 140%;}#invest_error, #divest_error { font-weight: bold;}.important { font-weight: bold;}a { color: {link_fgcolor}; font-weight: bold; outline: none; -moz-outline-style: none;}input { color: {input_fgcolor};}button { color: {button_fgcolor};}.s1 { font-size: 150%;}.s2 { font-size: 120%;}.s3 { font-size: 80%;}div.clear { clear: both;}div.aleft { text-align: left;}div.aright { text-align: right;}div.fleft { float: left;}span.fleft { float: left;}div.fright { float: right;}div.indent { padding-left: 20px;}div.rindent { padding-right: 20px;}div.rpad { padding-right: 10px;}div.pad { padding: 10px;}.realcontent { width: 468px; height: 60px; margin: 0 1px; border: 1px solid {ad_border_color};}.allcodes { font-family: monospace;}.nodisplay { display: none; position:absolute; left:-9999px; visibility: hidden;}.skinny { width: 1px; overflow: hidden; display: inline-block;}.code { font-family: monospace; white-space: nowrap; overflow: auto;}.play { width: 70px;}/* ------------------------------ site name ------------------------------ */.header { float: left; display: block; border: 3px solid {logo_border_color}; background: {logo_bgcolor}; border-radius: 12px; font-size: 2em; font-weight: bold; padding: 0.3em 0.7em;}.header a { text-decoration: none;}/* ------------------------------ welcome ------------------------------ */.welcome { border: 3px solid {welcome_border_color}; font-size: 130%; font-weight: bold; padding: 20px; border-radius: 12px;}.welcome button { padding: 5px 10px; margin: 0px 20px;}.welcome input { margin: 2px 0; width: auto; font-family: monospace;}/* ------------------------------ message area ------------------------------ */div.log { width: 673px; height: 50px; background: {msg_bgcolor}; float: left}.log2 { padding: 8px;}.log span { vertical-align: baseline; align: center; text-align: center;}/* ------------------------------ tabs ------------------------------ */ul.tabs { margin: 17px 0 0.5em 0; padding: 0 0 0 17px;}.tabs li { list-style: none; display: inline; margin: 0px;}.tabs a.attention { background: {tab_attention_color_normal};}.tabs a.attention:hover { background: {tab_attention_color_hover};}.tabs a.mentioned { background: {tab_mentioned_color_normal};}.tabs a.mentioned:hover { background: {tab_mentioned_color_hover};}.tabs a { border-left: 1px solid {tab_border_color}; border-right: 1px solid {tab_border_color}; border-top: 1px solid {tab_border_color}; padding: 9px 10px 7px 8px; color: {tab_color_normal}; border-radius: 12px 12px 0 0; font-weight: bold; text-decoration: none; margin: -3px; background: {tab_bgcolor_normal};}.tabs a:hover { text-decoration: none; background: {tab_bgcolor_hover}; color: {tab_color_hover};}.tabs a.active { color: {tab_color_active}; background: {tab_bgcolor_active}; border-bottom: 0px;}/* ------------------------------ stats box ------------------------------ */.winlose div { float: right; font-size: 130%; margin: 0; padding: 3px; margin-top: 0; border-radius: 12px; font-weight: bold;}div.winlose { float: right;}div.wins { color: green;}div.losses { color: rgb(189, 29, 29);}div.wins, div.losses { min-width: 30px;}div.slash { padding-left: 0px; padding-right: 0px; text-align: center;}.mp { padding: 3px; vertical-align: baseline;}.mp span { font-size: 130%; padding: 3px 3px 3px 3px; font-weight: bold;}.mp, .winlose { margin: 0; text-align: right;}.stats { border-left: 3px solid {max_profit_border_color}; border-right: 3px solid {max_profit_border_color}; border-top: 3px solid {max_profit_border_color}; background: {max_profit_bgcolor}; border-radius: 12px 12px 0 0; padding: 3px 3px 2px 3px; margin: 5px; margin-bottom: 0; margin-right: 17px;}/* ------------------------------ invest ------------------------------ */#invest_edit { font-size: 130%; margin-top: 7px; margin-left: 20px; font-weight: bold;}/* ------------------------------ chat ------------------------------ */.chatscroll, .chatbetscroll { border: 1px solid {chat_border_color}; background: {chat_bgcolor}; overflow-x:hidden; overflow-y:scroll;}.chatscroll { height: 320px;}.chatbetscroll { height: 80px; resize: vertical;}.chatbase { margin-top: 10px; width: 100%;}.autowidth { width: auto;}.chatinput { border: 1px solid {chat_input_border_color}; text-align: left; width: auto;}.chatstat th { padding: 0.5ex 1ex 0.5ex 1ex;}.chatstat td { padding: 0.5ex 1ex}.chatstat td, .chatstat th { text-align: right; font-size: 120%;}#chatbets { display: none;}/* ------------------------------ history table ------------------------------ */.hist_table { font-size: 12px;}.hist_table { text-align: right;}.hist_table th, .hist_table td { padding: 4px;}.hist_table th { text-align: center; background: {history_header_bgcolor};}.hist_table tr { background: {history_table_odd_bgcolor};}.hist_table tr:nth-child(even) {background: {history_table_even_bgcolor};}/* ------------------------------ results box ------------------------------ */.result.me { background: {my_results_bgcolor};}.result .zero { color: {trailing_zero_color_all};}.result.me .zero { color: {trailing_zero_color_me};}.result.win .lucky, .result.win .profit { color: {result_win_color}; font-weight: bold;}.result.lose.imp .lucky { color: {result_all_lose_color}; font-weight: bold;}.result.win.gold .lucky { color: {result_all_win_color}; font-weight: bold;}.result.lose .lucky, .result.lose .profit { color: {result_lose_color}; font-weight: bold;}.bet, .chance { width: 90px;}.betid { width: 85px;}.betid a { font-size: 70%; text-decoration: none; font-weight: normal;}.lucky { width: 75px;}.who { width: 140px;}.when, .compare, .profit, .payout { width: 150px;}.results .when { font-size: 80%;}.results_header .profit, .results_header .bet { text-align: center;}.bet, .profit { display: inline-block; padding: 0px; text-align: right;}.when, .who, .betid, .chance, .lucky, .compare, .payout { display: inline-block; padding: 0px; text-align: center;}fieldset p { display: inline-block; background: {bet_inputs_label_bgcolor}; border: 1px solid {bet_inputs_label_border_color}; padding: 5px; margin: 5px 0px;}.container { padding-bottom: 10px;}.llabel { border-radius: 6px 0 0 6px; min-width: 12ex; text-align: right;}.rlabel { min-width: 17px; border-radius: 0 12px 12px 0;}.edit_ga input { width: auto;}input { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; background: {input_bgcolor}; border: 1px solid {input_border_color}; font-size: 100%; margin: 0; padding: 5px; text-align: right; vertical-align: baseline; width: 15ex;}.button_inner_group { margin: 0; padding: 0; display: inline-block;}.button_group { overflow: hidden; margin-right: 5px; margin-top: 0; padding: 0; float: left; border: 5px solid {button_group_outline_border_color}; border-radius: 12px; background-color: {button_group_outline_bgcolor};}.button_group button.button_label:hover { background: {bet_toggle_button_bgcolor_hover};}.button_group button.button_label:active { background: {bet_toggle_button_bgcolor_active};}.button_group button.button_label { border: 3px solid {bet_toggle_button_border_color}; border-radius: 12px 0 0 12px; background: {bet_toggle_button_bgcolor_normal}; width: auto;}.button_inner_group .key { font-size: 80%; border: 2px solid {shortcut_border_color}; border-radius: 3px; background: {shortcut_bgcolor}; color: white; width: 3ex; margin: auto; margin-top: 2px; text-shadow: 1px 1px {shortcut_shadow_color};}.button_group button.right, .button_group button.right:hover { border-radius: 0 12px 12px 0;}.button_group button.waiting, .button_group button.waiting:hover { background-color: {bet_button_waiting_bgcolor}; cursor: auto;}.button_group button.inactive, .button_group button.inactive:hover { background-color: {bet_button_inactive_bgcolor}; cursor: auto;}.button_group button.invalid, .button_group button.invalid:hover { background-color: {bet_button_invalid_bgcolor}; border: 5px solid {bet_button_invalid_border_color}; cursor: auto;}.button_group button { vertical-align: top; height: 48px; border-radius: 0; color: {bet_button_fgcolor}; background-color: {bet_button_bgcolor_normal}; font-size: 100%; border: 3px solid {bet_button_border_color}; padding: 0 1px; min-width: 5ex;}.button_group button:hover { background-color: {bet_button_bgcolor_hover};}.button_group button:active { background-color: {bet_button_bgcolor_active};}input[type="submit"], button { font-size: 100%; border: 3px solid {button_border_color}; border-radius: 6px; padding: 1px 6px; margin: 1px 2px; width: auto; background-color: {button_bgcolor_normal};}input[type="submit"]:hover, button:hover { background-color: {button_bgcolor_hover}; cursor: pointer;}input[type="submit"]:active, button:active { background-color: {button_bgcolor_active};}.target { font-size: 60%; height: 13px;}fieldset { display: inline-block; background-color: {bet_inputs_group_bgcolor};}.results { overflow:auto}.results_header { font-weight: bold; font-size: 120%; padding: 1ex 0; border-radius: 12px 12px 0 0; border-bottom: 1px solid {results_header_border_color}; background: {results_header_bgcolor};}.roll { border: 3px solid {roll_border_color}; padding: 15px 10px 0px 10px; border-radius: 12px;}.gap { height: 10px;}.roll span { font-size: 110%;}.roll .slabel { width: 170px;}.slabel { float: left; padding: 0px 5px 5px 0; font-size: 130%; text-align: right; width: 150px;}.statspanel h2 { padding-left: 35px;}.statspanel { float: left; width: 400px;}.panel, .results_container { border-radius: 12px; border: 3px solid {tabbed_panel_border_color}; margin: 0px;}.panel { background: {tabbed_panel_bgcolor};}.results_container { background: {all_results_bgcolor};}#blank .panel { height: 200px;}fieldset { vertical-align: top; padding: 0 5px; margin-right: 5px; margin-bottom: 5px; border: 3px solid {bet_inputs_border_color}; border-radius: 12px;}.log { vertical-align: top; padding: 0 5px; margin-right: 5px; margin-bottom: 5px; border: 3px solid {msg_border_color}; border-radius: 12px;}.warning { background-color: {bet_warning_color};}.invalid { background-color: {bet_invalid_color};}.hilite { display: inline;}.big { padding: 0; font-size: 125%; display: inline-block;}.big button { border: 5px solid green; border-radius: 12px;}.big .button_group button { height: 77px; min-width: 75px;}.big .button_inner_group .key { font-size: 61.538%;}.balance { padding-top: 5px; padding-left: 5px;}.bal_text { padding: 0; text-align: left;}.big input { margin: 0; font-size: 120%; border: 3px solid {balance_border_color}; background: {balance_bgcolor}; font-weight: bold; color: {balance_color}; width: 190px; border-radius: 12px;}div.panel { padding: 1em;}#stats .panel span { font-size: 120%; font-weight: normal;}.chatline { text-indent: -2em; margin-left: 2em;}.chatwin, .chatlose, .chatmod, .chatpm, .chatemote, .chatprincess, .chatstake, .chatinfo, .chatme, .ding { text-indent: 0; margin-left: 0;}.ding { font-weight: bold; background: {chat_ding_bgcolor}; color: {chat_ding_color};}.chatme { font-style: oblique; background: {chat_me_bgcolor}; color: {chat_me_color};}.chatwin { background: {chat_win_bgcolor}; color: {chat_win_color};}.chatlose { background: {chat_lose_bgcolor}; color: {chat_lose_color};}.chatmod { background: {chat_mod_bgcolor}; color: {chat_mod_color};}.chatpm { background: {chat_pm_bgcolor}; color: {chat_pm_color};}.chatemote { background: {chat_emote_bgcolor}; color: {chat_emote_color};}.chatprincess { background: {chat_princess_bgcolor}; color: {chat_princess_color};}.chatprincess.chatemote { background: {chat_princess_emote_bgcolor}; color: {chat_princess_emote_color};}.chatstake { background: {chat_stake_bgcolor}; color: {chat_stake_color};}.chatinfo { background: {chat_info_bgcolor}; color: {chat_info_color};}#chat span:hover { background: {chat_name_bgcolor_hover};}#chat span { font-family: inherit; padding: 1px; margin: 0; font-weight: inherit; background: {chat_name_bgcolor_normal}; border: inherit; border-radius: inherit;}.mono span, .roll span, .panel span, .chatstat span { font-family: monospace; padding: 2px 4px; margin: 2px; font-weight: bold; background: {mono_bgcolor}; border: 1px dashed {mono_border_color}; border-radius: 12px;}.deposit { border: 3px solid {deposit_border_color}; padding: 5px; border-radius: 12px;}.setup_ga .secret, .deposit .address { font-family: monospace; color: {mono_fgcolor}; font-weight: bold; font-size: 130%;}.w200 { width: 200px;}.deposit #desc { width: 500px;}.edit_ga .boxes { border-radius: 12px; border: 3px solid {edit_ga_border_color}; margin: 10px; padding-left: 10px;}.setup_ga #desc, .edit_ga .desc { width: 400px; padding-left: 20px;}.monospace { font-size: 90%; font-weight: bold; padding: 3px; display: inline-block; font-family: monospace; border-radius: 12px;}.input_ok { font-size: 150%;}.setup_ga .input_ok_button { padding-left: 10px;}.withdraw p, .deposit p { margin: 10px 20px;}.deposit img { margin-left: 20px;}.withdraw .input_ok_button { font-size: 150%; padding-right: 10px;}div.input_ok_input { float: left;}.input_ok_input input { font-family: monospace; width: 100%;}.autowidth { width: auto;}input.name_input { font-family: monospace; margin-left: 10px; width: auto;}.withdraw { width: 650px; border: 3px solid {withdraw_border_color}; padding: 5px; border-radius: 12px;}.withdraw .fleft { text-align: right; padding-right: 5px; width: 120px;}#form_error { margin: 10px;}#faq h4 { padding: 10px; background: {faq_bgcolor}; border: 1px solid {faq_border_color}; border-radius: 12px;}#space { height: 100px; }.picker { border: 1px solid black; cursor: pointer; display: inline-block; font-size: 12px; font-weight: bold; margin: 2px; padding: 0px 4px; }.fancybox-skin { background: {fb_bgcolor};}';
745 style = $("#style");
746 template = template_compile(template);
747 var dark = false;
748 if (dark) switch_style(styles.style_dark);
749 else switch_style({});
750 window.socket = socket = io();
751 init()
752 });
753 var current_style;
754
755 function switch_style(mods) {
756 var obj = $.extend({}, default_style);
757 $.extend(obj, mods);
758 style.html(template(current_style = obj))
759 }
760 var fixup_timeout, invalid_state = {};
761
762 function fixup() {
763 if (fixup_timeout) clearTimeout(fixup_timeout);
764 fixup_timeout = setTimeout(function() {
765 if (!invalid_state["#pct_payout"] && !invalid_state["#pct_chance"]) {
766 var prefix = "pct";
767 var bet_o = find_object(prefix, "bet");
768 var bet = get_float_string(prefix, "bet", bet_o);
769 if (bet !== false) {
770 bet = bet.replace(/^0*([1-9])/, "$1").replace(/([.][0-9]*[1-9])0*/, "$1").replace(/([0-9])[.]0*$/, "$1").replace(/^[.]/, "0.");
771 bet_o.val(bet)
772 }
773 changed_chance("pct")
774 }
775 }, fixup_delay * 1e3)
776 }
777
778 function commaify(num) {
779 if (typeof num != "string") {
780 return num
781 }
782 var num2;
783 num = num.replace(/^([0-9]+)([0-9]{3})$/, "$1,$2");
784 while (true) {
785 num2 = num.replace(/([0-9])([0-9]{3}[,.])/, "$1,$2");
786 if (num == num2) break;
787 num = num2
788 }
789 return num
790 }
791
792 function clear_msg() {
793 msg(news ? "News: " + news : "")
794 }
795
796 function msg(txt) {
797 $("#msg").html(txt || "")
798 }
799
800 function find_object(prefix, id) {
801 return id ? $("#" + prefix + "_" + id) : prefix
802 }
803
804 function validate() {
805 return $(".invalid").length === 0
806 }
807
808 function set_invalid(obj, state) {
809 var selector = obj.selector;
810 if (state) {
811 if (!invalid_state[selector]) {
812 obj.addClass("invalid");
813 $(".play").addClass("invalid");
814 invalid_state[selector] = true
815 }
816 } else if (invalid_state[selector]) {
817 obj.removeClass("invalid");
818 if ($(".invalid").length == 2) $(".play").removeClass("invalid");
819 invalid_state[selector] = false
820 }
821 }
822
823 function set_warning(obj, state) {
824 if (state) {
825 if (!invalid_state["#pct_chance"]) msg("That exact payout multiplier is not available.<br/>The closest available multiplier will be selected if you stop typing for " + fixup_delay + " seconds.");
826 obj.addClass("warning")
827 } else {
828 clear_msg();
829 obj.removeClass("warning")
830 }
831 }
832
833 function get_waiting() {
834 return $("#a_hi.waiting").length > 0
835 }
836 var waiting_timeout;
837
838 function set_waiting(which) {
839 if (which === false) {
840 clearTimeout(waiting_timeout);
841 $(".play").removeClass("waiting");
842 $(".play").removeClass("inactive")
843 } else {
844 waiting_timeout = setTimeout(function() {
845 msg('It is taking a long time for the server to respond. Check your Internet connection or <a href=".">reload this page</a>.')
846 }, bet_wait_timeout);
847 $(".play").addClass("waiting");
848 if (which == "hi") $("#a_lo").addClass("inactive");
849 else $("#a_hi").addClass("inactive")
850 }
851 }
852 window.send_bet = function send_bet(which) {
853 if (!validate()) return;
854 if (fixup_timeout) clearTimeout(fixup_timeout);
855 set_waiting(which);
856 var chance = $("#pct_chance").val();
857 var bet = $("#pct_bet").val();
858 socket.emit("bet", csrf, {
859 chance: chance,
860 bet: tidy(bet),
861 which: which
862 })
863 };
864
865 function round_down(num) {
866 return Math.floor(num * 1e8 + 1e-6) / 1e8
867 }
868
869 function format_chance(chance) {
870 chance = chance.toFixed(0);
871 chance = "00000".substring(0, 6 - chance.length) + chance;
872 return chance.substring(0, 2) + "." + chance.substring(2, 4) + " " + chance.substring(4, 6)
873 }
874
875 function maybe_update_targets() {
876 var chance = $("#pct_chance");
877 if (chance.val().match(/^ *$/) || chance.hasClass("invalid")) {
878 $("#hi").html("");
879 $("#lo").html("")
880 } else update_targets(chance.val())
881 }
882
883 function update_targets(chance) {
884 chance = parseFloat(chance) * 1e4;
885 $("#hi").html("> " + format_chance(999999 - chance));
886 $("#lo").html("< " + format_chance(chance))
887 }
888
889 function set_nonce(n) {
890 if (typeof n == "number") n = n.toFixed(0);
891 $("#nonce").html(nonce = n)
892 }
893
894 function set_balance(bal) {
895 $("#pct_balance").val(bal);
896 $("#inv_balance").add("#wd_bal").html(bal);
897 if (bal === 0 && $(".investment").html() === 0 && $(".invest_pft").html() === 0 && $(".wagered").html() === 0) $("#a_deposit").css({
898 background: "#fa3",
899 border: "3px solid #f40"
900 });
901 else $("#a_deposit").css({
902 background: "",
903 border: ""
904 })
905 }
906
907 function set_chance(chance) {
908 $("#pct_chance").val(chance);
909 update_targets(chance)
910 }
911
912 function clicked_chance_min() {
913 set_chance("0.0001");
914 clear_msg();
915 changed_chance("pct");
916 fixup();
917 return false
918 }
919
920 function clicked_chance_minus() {
921 var val = $("#pct_chance").val() - 1;
922 if (isNaN(val) || val < 1e-4) val = 1e-4;
923 set_chance(val);
924 clear_msg();
925 changed_chance("pct");
926 fixup()
927 }
928
929 function clicked_chance_half() {
930 var val = $("#pct_chance").val() / 2;
931 if (isNaN(val) || val < 1e-4) val = 1e-4;
932 set_chance(val);
933 clear_msg();
934 changed_chance("pct");
935 fixup()
936 }
937
938 function clicked_chance_double() {
939 var val = parseFloat($("#pct_chance").val()) * 2;
940 if (isNaN(val) || val > max_chance) val = max_chance;
941 set_chance(val);
942 clear_msg();
943 changed_chance("pct");
944 fixup()
945 }
946
947 function clicked_chance_plus() {
948 var val = parseFloat($("#pct_chance").val()) + 1;
949 if (val == 1.0001) val = 1;
950 if (isNaN(val) || val > max_chance) val = max_chance;
951 set_chance(val);
952 clear_msg();
953 changed_chance("pct");
954 fixup()
955 }
956
957 function clicked_chance_max() {
958 set_chance(max_chance);
959 clear_msg();
960 changed_chance("pct");
961 fixup()
962 }
963
964 function clicked_chance_toggle() {
965 $(".button_inner_group#chance").toggle()
966 }
967
968 function clicked_bet_toggle() {
969 $(".button_inner_group#bet").toggle()
970 }
971
972 function clicked_action_toggle() {
973 $(".button_inner_group#action").toggle()
974 }
975
976 function clicked_login() {
977 socket.emit("login", csrf, $("#myuser").val(), $("#mypass").val(), $("#mycode").val())
978 }
979
980 function clicked_reset_profit() {
981 socket.emit("reset_profit", csrf)
982 }
983
984 function clicked_real_profit() {
985 socket.emit("real_profit", csrf)
986 }
987
988 function clicked_forget_max_warning() {
989 socket.emit("forget_max_warning", csrf);
990 delete settings.max_bet
991 }
992
993 function clicked_logout() {
994 document.location = "logout"
995 }
996
997 function clicked_bet_min() {
998 $("#pct_bet").val("0.00000001");
999 changed_bet("pct");
1000 if ($("#pct_profit").val() === 0) {
1001 $("#pct_profit").val("0.00000001");
1002 changed_profit("pct")
1003 }
1004 fixup()
1005 }
1006
1007 function clicked_bet_half() {
1008 $("#pct_bet").val(tidy($("#pct_bet").val() / 2));
1009 changed_bet("pct");
1010 fixup()
1011 }
1012
1013 function clicked_bet_double() {
1014 var bet = $("#pct_bet").val() * 2;
1015 var bal = parseFloat($("#pct_balance").val());
1016 if (bet > bal) bet = bal;
1017 if (settings.max_double && bet >= settings.max_double) bet = settings.max_double;
1018 $("#pct_bet").val(tidy(bet));
1019 changed_bet("pct");
1020 fixup()
1021 }
1022
1023 function confirm_tip(cmd, desc) {
1024 $.fancybox("<div><p>" + quote_html(desc) + "?</p>" + '<button id="tipyes">yes</button> ' + '<button id="tipno">no</button>' + "</div>", {
1025 keys: {
1026 close: []
1027 },
1028 closeBtn: false,
1029 helpers: {
1030 overlay: {
1031 closeClick: false,
1032 css: {
1033 background: "rgba(0, 0, 0, 0.5)"
1034 }
1035 }
1036 }
1037 });
1038 $("#tipyes").click(function(e) {
1039 $.fancybox.close();
1040 socket.emit("chat", csrf, cmd)
1041 });
1042 $("#tipno").click(function(e) {
1043 $.fancybox.close()
1044 })
1045 }
1046
1047 function clicked_bet_max(force) {
1048 if (force != "force") {
1049 if (settings.max_bet === undefined) {
1050 $.fancybox("<div>" + "<p>You clicked 'max' or hit 'B', the maximum bet option.</p>" + "<p>Are you sure you want to proceed?</p>" + '<label><input id="maxask" style="width:auto;" type="checkbox" /> don\'t ask me again</label> ' + '<button id="maxyes">yes</button> ' + '<button id="maxno">no</button>' + "</div><br/>", {
1051 keys: {
1052 close: []
1053 },
1054 closeBtn: false,
1055 helpers: {
1056 overlay: {
1057 closeClick: false,
1058 css: {
1059 background: "rgba(0, 0, 0, 0.5)"
1060 }
1061 }
1062 }
1063 });
1064 var ask = $("#maxask");
1065 $("#maxyes").click(function(e) {
1066 if (ask.prop("checked")) {
1067 settings.max_bet = "1";
1068 socket.emit("setting", csrf, "bool", "max_bet", "1")
1069 }
1070 $.fancybox.close();
1071 clicked_bet_max("force")
1072 });
1073 $("#maxno").click(function(e) {
1074 if (ask.prop("checked")) {
1075 settings.max_bet = "0";
1076 socket.emit("setting", csrf, "bool", "max_bet", "0")
1077 }
1078 $.fancybox.close()
1079 });
1080 return
1081 } else if (settings.max_bet == "0") {
1082 msg("you have disabled the max bet feature");
1083 return
1084 }
1085 }
1086 $("#pct_profit").val(max_profit);
1087 changed_profit("pct");
1088 var bet = parseFloat($("#pct_bet").val());
1089 var bal = parseFloat($("#pct_balance").val());
1090 if (bet > bal) {
1091 $("#pct_bet").val(tidy(bal));
1092 clear_msg()
1093 }
1094 changed_bet("pct")
1095 }
1096
1097 function validchance(c) {
1098 if (isNaN(c)) return "not a number";
1099 if (c < 1e-4) return c + "% is too low";
1100 if (c > 98.99) return c + "% is too high";
1101 return true
1102 }
1103
1104 function randomchance(range) {
1105 var range = [settings.min_randchance, settings.max_randchance];
1106 range.sort();
1107 var valid;
1108 for (var r in range) {
1109 if ((valid = validchance(range[r])) !== true) {
1110 msg("random chance range limit is " + valid);
1111 return false
1112 }
1113 }
1114 var a = Math.floor(range[0] * 1e4 + .5);
1115 var b = Math.floor(range[1] * 1e4 + .5);
1116 set_chance((parseInt(CryptoJS.SHA256(uid + ":" + nonce).toString(CryptoJS.enc.Hex).substr(0, 8), 16) % (b - a + 1) + a) / 1e4);
1117 clear_msg();
1118 changed_chance("pct");
1119 fixup();
1120 return true
1121 }
1122
1123 function halfthetime() {
1124 var hash = CryptoJS.SHA256(uid + ":" + nonce).toString(CryptoJS.enc.Hex).substr(0, 1);
1125 return hash.match(/[0-7]/)
1126 }
1127
1128 function clicked_action_bet_random_chance() {
1129 if (!settings.randchancekey) msg("Enable the 'e for random chance' shortcut at the end of the 'Account' tab");
1130 else if (lastwhich == "lo") {
1131 if (randomchance()) clicked_action_bet_lo()
1132 } else if (lastwhich == "hi") {
1133 if (randomchance()) clicked_action_bet_hi()
1134 } else msg("Bet 'hi' or 'lo' before using 'random chance'")
1135 }
1136
1137 function clicked_action_bet_random_hi_lo() {
1138 if (!settings.randomkey) msg("Enable the 'r for random' shortcut at the end of the 'Account' tab");
1139 else if (halfthetime()) clicked_action_bet_lo();
1140 else clicked_action_bet_hi()
1141 }
1142
1143 function clicked_action_bet_toggle() {
1144 if (!settings.togglekey) msg("Enable the 't to toggle' shortcut at the end of the 'Account' tab");
1145 else if (lastwhich == "lo") clicked_action_bet_hi();
1146 else if (lastwhich == "hi") clicked_action_bet_lo();
1147 else msg("Bet 'hi' or 'lo' before using 'toggle'")
1148 }
1149
1150 function clicked_action_bet_same() {
1151 if (!settings.samekey) msg("Enable the 'y to repeat' shortcut at the end of the 'Account' tab");
1152 else if (lastwhich == "lo") clicked_action_bet_lo();
1153 else if (lastwhich == "hi") clicked_action_bet_hi();
1154 else msg("Bet 'hi' or 'lo' before using 'repeat'")
1155 }
1156
1157 function clicked_action_bet_hi() {
1158 clicked_action_bet("hi")
1159 }
1160
1161 function clicked_action_bet_lo() {
1162 clicked_action_bet("lo")
1163 }
1164
1165 function clicked_action_bet(which) {
1166 $("#pct_balance").focus();
1167 if (get_waiting()) {
1168 msg("Please wait for previous bet to finish.");
1169 return
1170 }
1171 send_bet(lastwhich = which)
1172 }
1173
1174 function clicked_action_deposit() {
1175 socket.emit("deposit", csrf)
1176 }
1177
1178 function need_ga(action) {
1179 if (!google_auth.active) return false;
1180 return google_auth.flags[action]
1181 }
1182 var wd_button_enabled = true;
1183
1184 function send_withdraw_request(address, amount, speech, code) {
1185 if (wd_button_enabled) {
1186 var wd_button = $("#wd_button");
1187 wd_button.attr("disabled", "disabled").animate({
1188 opacity: 0
1189 });
1190 wd_button_enabled = false;
1191 setTimeout(function() {
1192 wd_button.removeAttr("disabled").animate({
1193 opacity: 1
1194 });
1195 wd_button_enabled = true
1196 }, 2e3);
1197 socket.emit("withdraw", csrf, address.val(), amount.val(), code.val(), speech.val())
1198 } else console.log("not withdrawing")
1199 }
1200
1201 function clicked_action_withdraw() {
1202 var msg = fee === 0 ? "" : '<p>You have <span id="wd_bal" /> ' + currency + ".</p><p>Clicking the withdraw button multiple times will cause multiple withdrawals.</p><p>" + fee + " " + currency + " will be deducted from the amount you type for use as a transaction fee.</p>";
1203 var auth = "";
1204 if (need_ga("withdraw")) auth = '<div class="clear"></div>' + '<div class="fleft">Google Auth:</div>' + '<div class="fleft input_ok_input"><input id="ga_code"></div>';
1205 withdraw_address = "";
1206 $.fancybox("<div class='withdraw'>" + "<h1>Withdraw " + currency + "s</h1>" + "<p><b>Note:</b> Your withdrawal will be sent from a random address in the hot wallet. Do not withdraw directly to any site that uses the 'sending address' as a 'return address' because any coins they return to you will be credited to a random Just-Dice account.</p>" + '<div class="fleft">' + currency + " Address:</div>" + '<div class="input_ok_input"><input id="wd_address" value="' + withdraw_address + '" size="40"></div>' + '<div class="clear"></div>' + '<div class="fleft">Amount:</div>' + '<div class="input_ok_input"><input id="wd_amount" size="40"></div>' + '<div class="clear"></div>' + '<div class="fleft">CLAMspeech:</div>' + '<div class="input_ok_input"><input id="wd_speech" size="40"></div>' + '<div class="fleft"> (optional text)</div>' + auth + '<div class="fleft input_ok_button"><button id="wd_button">withdraw</button></div>' + '<div class="clear"></div>' + '<div id="form_error">' + msg + "</div>" + "</div>", {
1207 helpers: {
1208 overlay: {
1209 closeClick: true,
1210 css: {
1211 background: "rgba(0, 0, 0, 0.5)"
1212 }
1213 }
1214 }
1215 });
1216 var address = $("#wd_address");
1217 var amount = $("#wd_amount");
1218 var speech = $("#wd_speech");
1219 var button = $("#wd_button");
1220 var code = $("#ga_code");
1221 $("#wd_bal").html($("#pct_balance").val());
1222 if (need_ga("withdraw")) code.keypress(function(e) {
1223 if (e.which == 13) send_withdraw_request(address, amount, speech, code)
1224 });
1225 address.keypress(function(e) {
1226 if (e.which == 13) send_withdraw_request(address, amount, speech, code)
1227 });
1228 amount.keypress(function(e) {
1229 if (e.which == 13) send_withdraw_request(address, amount, speech, code)
1230 });
1231 speech.keypress(function(e) {
1232 if (e.which == 13) send_withdraw_request(address, amount, speech, code)
1233 });
1234 button.click(function(e) {
1235 send_withdraw_request(address, amount, speech, code)
1236 })
1237 }
1238
1239 function clicked_action_random() {
1240 socket.emit("random", csrf)
1241 }
1242
1243 function clicked_action_invest() {
1244 socket.emit("invest_box", csrf)
1245 }
1246 var color_editor_showing = false;
1247
1248 function clicked_toggle_color_editor(html) {
1249 if (!(color_editor_showing = !color_editor_showing)) {
1250 color_editor.fadeOut();
1251 return
1252 }
1253 var editor = "<p>Any changes you make here won't currently be saved. This will be fixed soon...ish.</p>";
1254 for (var v in current_style) editor += '<div class="picker" value="' + current_style[v] + '">' + v + "</div>";
1255 color_editor.html(editor);
1256 color_editor.css({
1257 border: "3px solid #888",
1258 padding: "10px",
1259 margin: "10px 0px",
1260 borderRadius: "6px"
1261 });
1262 color_editor.fadeIn();
1263 init_pickers()
1264 }
1265
1266 function clicked_action_name() {
1267 $.fancybox("<div>" + "<h2>Change Name</h2>" + "<p>Type your new name!</p>" + '<div class="input_ok">' + '<div class="input_ok_input"><input class="name_input" value="' + nick + '" size="' + max_name_length + '" maxlength="' + max_name_length + '"></div>' + '<div class="fleft indent"><button class="name_button">ok</button></div>' + '<div class="clear"></div>' + "</div>" + "</div>");
1268 handle_name_input($(".name_input"));
1269 $(".name_button").click(function(e) {
1270 $.fancybox.close()
1271 })
1272 }
1273
1274 function handle_name_input(obj) {
1275 var emit_name_timeout;
1276 obj.select().keyup(function(e) {
1277 var tmp = obj.val();
1278 if (tmp !== "") {
1279 clearTimeout(emit_name_timeout);
1280 nick = tmp.replace(/[+]/g, "");
1281 if (default_alert_words) {
1282 $("#alert_words").val(nick + "," + uid);
1283 build_user_regexp(nick + "," + uid)
1284 }
1285 $("#nick").html(quote_html(nick));
1286 emit_name_timeout = setTimeout(function() {
1287 socket.emit("name", csrf, nick)
1288 }, 3e3);
1289 if (e.which == 13) $.fancybox.close()
1290 }
1291 })
1292 }
1293
1294 function mono(h, id) {
1295 return '<div id="' + id + '" class="monospace">' + h + "</div>"
1296 }
1297
1298 function random_number(length) {
1299 var ret = "";
1300 for (var i = 0; i < length; i++) {
1301 var r = Math.floor(Math.random() * 10);
1302 ret += "0123456789".substring(r, r + 1)
1303 }
1304 return ret
1305 }
1306
1307 function update_my_stats(bets, wins, losses, luck, wagered, profit) {
1308 real_profit = profit;
1309 $(".bets").html(commaify(bets));
1310 $("#luck").html(luck);
1311 $(".wagered").html(commaify(wagered));
1312 $(".myprofit").html(fixed(real_profit - profit_offset));
1313 if (wins !== null) {
1314 $("#wins,#wins2").html(commaify(wins));
1315 $("#losses,#losses2").html(commaify(losses))
1316 }
1317 }
1318
1319 function update_settings(s) {
1320 settings = s;
1321 if (settings.chat_min_risk === undefined) settings.chat_min_risk = default_chat_min;
1322 if (settings.chat_min_change === undefined) settings.chat_min_change = default_chat_min;
1323 if (settings.allbetsme === undefined) settings.allbetsme = true;
1324 if (settings.shortcuts === undefined) settings.shortcuts = true;
1325 if (settings.chatstake === undefined) settings.chatstake = true;
1326 if (settings.alert === undefined) settings.alert = false;
1327 if (settings.hilite === undefined) settings.hilite = true;
1328 if (settings.pmding === undefined) settings.pmding = false;
1329 if (settings.styleme === undefined) settings.styleme = true;
1330 if (settings.chatbets === undefined) settings.chatbets = true;
1331 if (settings.min_randchance === undefined) settings.min_randchance = 1e-4;
1332 if (settings.max_randchance === undefined) settings.max_randchance = 98.99;
1333 if (default_alert_words = !settings.alert_words) settings.alert_words = nick + "," + uid;
1334 for (var setting in s) {
1335 var obj = $("#" + setting);
1336 if (obj.is(":checkbox")) obj.prop("checked", s[setting]);
1337 else if (typeof s[setting] === "number") obj.val(s[setting].toFixed(8).replace(/([.].*[^0])0*$/, "$1").replace(/[.]0*$/, ""));
1338 else obj.val(s[setting])
1339 }
1340 build_user_regexp(settings.alert_words)
1341 }
1342
1343 function build_user_regexp(words) {
1344 user_regexp = new RegExp("\\b(" + words.split(/[,]+/).join("|").replace(/([.^$*+()[\]])/g, "\\$1") + ")\\b", "i")
1345 }
1346
1347 function update_site_stats(site) {
1348 $(".sbets").html(commaify(site.bets.toString()));
1349 $("#swins").html(commaify(site.wins.toString()));
1350 $("#slosses").html(commaify(site.losses.toString()));
1351 $("#sluck").html((site.bets === 0 ? 100 : site.luck * 100 / site.bets).toFixed(luck_precision) + "%");
1352 $(".swagered").html(fixed(site.wagered));
1353 $(".sprofitraw").html(fixed(-site.profit));
1354 $(".sprofitpct").html((-site.profit * 100 / site.wagered).toFixed(6) + "%");
1355 if (site.profit > 0) {
1356 $(".sprofit_label").html("site is down:");
1357 $(".sprofit").html(fixed(site.profit))
1358 } else {
1359 $(".sprofit_label").html("site is up:");
1360 $(".sprofit").html(fixed(-site.profit))
1361 }
1362 }
1363 var quote_html = window.quote_html = function(html) {
1364 return $(".tmpbuffer").text(html).html()
1365 };
1366
1367 function break_long_words(txt) {
1368 return txt.replace(/(\w{20})/g, "$1<wbr>")
1369 }
1370
1371 function unescape_html(html) {
1372 return html.replace(///g, "/").replace(/'/g, "'").replace(/"/g, '"').replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&")
1373 }
1374
1375 function update_investment(i, p, pft, off, stk) {
1376 $(".investment").html(fixed(investment = i));
1377 $(".invest_pct").html(fixed(invest_pct = p, 6) + "%");
1378 if (stk !== undefined) {
1379 stake_profit = stk;
1380 $(".stake_pft").html(fixed(stk))
1381 }
1382 if (pft !== null) {
1383 $(".bankroll_pft").html(fixed(pft - stake_profit));
1384 $(".invest_pft").html(fixed(pft))
1385 }
1386 if (off !== undefined) {
1387 offsite = off;
1388 $(".invest_offsite").html(fixed(offsite))
1389 }
1390 $(".invest_total").html(fixed(i + offsite));
1391 $(".invest_mult").html(fixed(i ? (i + offsite) / i : 1) + "x")
1392 }
1393 var active_tab, tab_content, chattab, chatscroll_height;
1394 window.select_tab = function select_tab(tabname) {
1395 active_tab.removeClass("active");
1396 tab_content.hide();
1397 active_tab = $('ul.tabs > li > a[href="' + tabname + '"]');
1398 active_tab.addClass("active");
1399 current_tab = tabname;
1400 tab_content = $(current_tab);
1401 tab_content.show();
1402 if (current_tab == "#chat" || current_tab == "#account") {
1403 if (current_tab == "#chat") {
1404 if (scroll_on_chat) scroll_to_bottom_of_chat();
1405 chatinput.focus();
1406 chattab.removeClass("mentioned");
1407 chattab.removeClass("attention")
1408 }
1409 $(".key").animate({
1410 opacity: .25
1411 })
1412 } else $(".key").animate({
1413 opacity: 1
1414 })
1415 };
1416
1417 function init() {
1418 chatscroll = $(".chatscroll");
1419 chatbetscroll = $(".chatbetscroll");
1420 chatlog = $(".chatlog");
1421 chatbets = $(".chatbets");
1422 chattab = $('ul.tabs > li > a[href="#chat"]');
1423 chatscroll_height = chatscroll.height();
1424 color_editor = $(".editcolor");
1425 var chatbets_base = $("#chatbets"),
1426 scroll_on_chat_timeout;
1427 scroll_on_chat = true;
1428 chatinput = $(".chatinput");
1429 $("ul.tabs").each(function() {
1430 var links = $(this).find("a");
1431 active_tab = $(links[0]);
1432 active_tab.addClass("active");
1433 current_tab = active_tab.attr("href");
1434 tab_content = $(current_tab);
1435 links.not(active_tab).each(function() {
1436 $($(this).attr("href")).hide()
1437 });
1438 $(this).on("click", "a", function(e) {
1439 select_tab($(this).attr("href"));
1440 e.preventDefault()
1441 })
1442 });
1443 socket.on("dark", function(key) {
1444 switch_style(styles.style_dark)
1445 });
1446 socket.on("light", function(key) {
1447 switch_style(styles.style_default)
1448 });
1449 socket.on("edit", function(key) {
1450 clicked_toggle_color_editor()
1451 });
1452 socket.on("getver", function(key) {
1453 socket.emit("version", csrf, key, client_version)
1454 });
1455 socket.on("version", function(version) {
1456 $.fancybox('<div class="panel">' + "<p>A new version of the site is available.</p>" + "<p>Reloading in <span id=countdown>10 seconds</span>.</p>" + '<button id="doit">Reload Now</button>' + "</div>", {
1457 keys: {
1458 close: []
1459 },
1460 closeBtn: false,
1461 helpers: {
1462 overlay: {
1463 closeClick: false,
1464 css: {
1465 background: "rgba(0, 0, 0, 0.5)"
1466 }
1467 }
1468 }
1469 });
1470 var count = 10;
1471 var interval = setInterval(function() {
1472 count--;
1473 $("#countdown").html(count == 1 ? count + " second" : count + " seconds");
1474 if (count === 0) {
1475 clearInterval(interval);
1476 document.location = "."
1477 }
1478 }, 1e3);
1479 $("#doit").click(function(e) {
1480 document.location = "."
1481 })
1482 });
1483 socket.on("welcome", function(name, html) {
1484 nick = name;
1485 $.fancybox(html, {
1486 keys: {
1487 close: []
1488 },
1489 helpers: {
1490 overlay: {
1491 closeClick: false,
1492 css: {
1493 background: "rgba(0, 0, 0, 0.5)"
1494 }
1495 }
1496 }
1497 });
1498 var name_o = $("#welcome_name");
1499 name_o.attr("value", nick);
1500 name_o.attr("size", max_name_length);
1501 name_o.attr("maxlength", max_name_length);
1502 handle_name_input(name_o);
1503 $(".name_button").click(function(e) {
1504 $.fancybox.close()
1505 })
1506 });
1507 socket.on("dismiss", function() {
1508 $.fancybox.close()
1509 });
1510 socket.on("timeout", function() {
1511 $.fancybox("<div><p>Your session has timed out due to inactivity.</p>" + '<button id="reconnect">Reconnect</button></div>', {
1512 keys: {
1513 close: []
1514 },
1515 closeBtn: false,
1516 helpers: {
1517 overlay: {
1518 closeClick: false,
1519 css: {
1520 background: "rgba(0, 0, 0, 0.5)"
1521 }
1522 }
1523 }
1524 });
1525 $("#reconnect").click(function(e) {
1526 socket.emit("reconnect", csrf);
1527 $.fancybox.close()
1528 })
1529 });
1530 socket.on("invest_box", function(html) {
1531 var invest_ga = need_ga("invest");
1532 var divest_ga = need_ga("divest");
1533 $.fancybox(html, {
1534 helpers: {
1535 overlay: {
1536 closeClick: true,
1537 css: {
1538 background: "rgba(0, 0, 0, 0.5)"
1539 }
1540 }
1541 }
1542 });
1543 if (!invest_ga) $("#invest_auth").hide();
1544 if (!divest_ga) $("#divest_auth").hide();
1545 $("#inv_balance").html($("#pct_balance").val());
1546 var invest_code = $("#invest_code");
1547 var divest_code = $("#divest_code");
1548 $("#invest_input").focus();
1549 update_investment(investment, invest_pct, null);
1550 var invest_input = $("#invest_input"),
1551 divest_input = $("#divest_input");
1552 invest_input.add(invest_code).keypress(function(e) {
1553 if (e.which == 13) socket.emit("invest", csrf, invest_input.val(), invest_code.val())
1554 });
1555 divest_input.add(divest_code).keypress(function(e) {
1556 if (e.which == 13) socket.emit("divest", csrf, divest_input.val(), divest_code.val())
1557 });
1558 $("#invest_button").click(function(e) {
1559 socket.emit("invest", csrf, invest_input.val(), invest_code.val())
1560 });
1561 $("#divest_button").click(function(e) {
1562 socket.emit("divest", csrf, divest_input.val(), divest_code.val())
1563 });
1564 $("#invest_all").click(function(e) {
1565 socket.emit("invest", csrf, "all", invest_code.val())
1566 });
1567 $("#divest_all").click(function(e) {
1568 socket.emit("divest", csrf, "all", divest_code.val())
1569 })
1570 });
1571 socket.on("invest", function(i, p, pft, offsite) {
1572 update_investment(i, p, pft, offsite)
1573 });
1574 socket.on("news", function(n) {
1575 update_news(n)
1576 });
1577 socket.on("staked", function(r) {
1578 update_investment(r.investment, r.percent, r.invest_pft, undefined, r.stake_pft);
1579 update_max_profit(r.max_profit, r.bankroll);
1580 if (settings.chatstake) {
1581 var ourstake = r.stake_pft ? "; your share = " + fixed(r.stake_share) + "; your total = " + fixed(r.stake_pft) + "" : "";
1582 add_chat(Date(parseInt(r.date) * 1e3), "INFO: we just staked " + fixed(r.stake) + " " + currency + " (total = " + fixed(r.total) + ourstake + ")", "chatinfo", true)
1583 }
1584 });
1585 socket.on("invest_error", function(msg) {
1586 $("#invest_error").html(msg)
1587 });
1588 socket.on("divest_error", function(msg) {
1589 $("#divest_error").html(msg)
1590 });
1591 socket.on("setup_account", function(html) {
1592 $("#login").html(html);
1593 $("#change_password").click(show_change_password)
1594 });
1595 $(".chatbutton").click(function(e) {
1596 chatinput.focus();
1597 return send_chat(chatinput)
1598 });
1599 var betton = $(".chatbetton");
1600 betton.click(function(e) {
1601 if (chatbets_base.css("display") == "none") {
1602 betton.html("^");
1603 chatbets_base.css("display", "block");
1604 chatbets_showing = true
1605 } else {
1606 betton.html("v");
1607 chatbets_base.css("display", "none");
1608 chatbets_showing = false
1609 }
1610 socket.emit("setting", csrf, "bool", "chatbets", chatbets_showing ? "1" : "0")
1611 });
1612 chatscroll.scroll(function() {
1613 var offset = Math.ceil(chatscroll_height - chatlog.offset().top + chatscroll.offset().top) - chatlog.outerHeight();
1614 if (offset > -2) {
1615 if (debug_chat_scrolling) chatscroll.css({
1616 background: "white"
1617 });
1618 clearTimeout(scroll_on_chat_timeout);
1619 scroll_on_chat = true
1620 } else {
1621 scroll_on_chat = false;
1622 if (debug_chat_scrolling) chatscroll.css({
1623 background: "cyan"
1624 });
1625 clearTimeout(scroll_on_chat_timeout);
1626 scroll_on_chat_timeout = setTimeout(function() {
1627 if (debug_chat_scrolling) chatscroll.css({
1628 background: "yellow"
1629 });
1630 scroll_on_chat = true
1631 }, chat_scroll_freeze_time * 1e3)
1632 }
1633 });
1634 socket.on("tip", function(from, name, amount, comment, ignored, priv) {
1635 if (settings.mutechat) return;
1636 if (!ignored) {
1637 if (current_tab != "#chat") chattab.addClass("attention");
1638 add_chat(undefined, "INFO: you received a " + (priv ? "private " : "") + amount + " " + currency + " tip from (" + from + ") <" + name + ">" + (comment ? " [" + comment + "]" : ""), false, false, true, true)
1639 }
1640 });
1641 socket.on("chat", function(txt, date) {
1642 var matches;
1643 if (matches = txt.match(/^INFO: (\/tip auth=.*) -- to c(onfirm a tip .*)$/)) return confirm_tip(matches[1], "C" + matches[2]);
1644 if (settings.mutechat) return;
1645 if (current_tab != "#chat") chattab.addClass("attention");
1646 add_chat(date, txt, false, false, true, true)
1647 });
1648 socket.on("reload", function() {
1649 document.location = "."
1650 });
1651 socket.on("offset", function(offset) {
1652 reset_profit(offset)
1653 });
1654 socket.on("set_hash", function(hash) {
1655 document.location = hash
1656 });
1657 var seen_init = false,
1658 seen_results = false;
1659 socket.on("init", function(data) {
1660 if (seen_init) return;
1661 if (data.offset) reset_profit(data.offset);
1662 seen_init = true;
1663 window.csrf = csrf = data.csrf;
1664 uid = data.uid;
1665 $("#uid").html(uid);
1666 $("#nick").html(quote_html(nick = data.name.replace(/[+]/g, "")));
1667 withdraw_address = data.wdaddr;
1668 fee = data.fee;
1669 update_my_stats(data.bets, data.wins, data.losses, data.luck, data.wagered, data.profit);
1670 update_site_stats(data.stats);
1671 update_settings(data.settings);
1672 update_news(data.news);
1673 if (settings.chatbets) {
1674 betton.html("^");
1675 chatbets_base.css("display", "block");
1676 chatbets_showing = true
1677 }
1678 $("#api_num").html(data.api);
1679 max_profit = parseFloat(data.max_profit);
1680 $("#max_profit").html(commaify(max_profit.toFixed(2)));
1681 $(".bankroll").html(commaify(data.bankroll));
1682 update_investment(data.investment, data.percent, data.invest_pft, data.offsite, data.stake_pft);
1683 set_balance(data.balance);
1684 set_chance(tidy(data.chance));
1685 $("#pct_bet").val(tidy(data.bet));
1686 edge = data.edge;
1687 max_chance = 100 - edge_mult * edge;
1688 $("#pct_edge").val(edge);
1689 $("#pct_edge").html(edge + "%");
1690 $("#shash").html(data.shash);
1691 set_nonce(data.nonce);
1692 $("#seed").html(data.seed);
1693 $("#login").html(data.login);
1694 if (data.username) {
1695 $("#change_password").click(show_change_password);
1696 username = data.username
1697 } else {
1698 $("#setup_account").click(function() {
1699 $.fancybox("<div class='setup_account'>" + "<h1>Set Username and Password</h1>" + "<p>Please note that both username and password are <b>case sensitive</b>.</p>" + "<p>Also note that your browser probably <b>will not save your password</b>; make a note of it.</p>" + '<form onSubmit="return setup_account(this);">' + '<div class="fleft w200 aright rpad">Username</div> ' + '<div class="input_ok_input"><input size=40 id="username"></div>' + '<div class="clear"></div>' + '<div class="fleft w200 aright rpad">Password</div>' + '<div class="input_ok_input"><input type="password" size=40 id="password"></div>' + '<div class="clear"></div>' + '<div class="fleft w200 aright rpad">Repeat Password</div>' + '<div class="input_ok_input"><input type="password" size=40 id="password2"></div>' + '<div class="clear"></div>' + '<div class="fright input_ok_button"><input type="submit" value="OK"></div>' + '<div class="clear"></div>' + '<div id="form_error"></div>' + "</form></div>", {
1700 helpers: {
1701 overlay: {
1702 closeClick: true,
1703 css: {
1704 background: "rgba(0, 0, 0, 0.5)"
1705 }
1706 }
1707 }
1708 });
1709 $("#username").focus()
1710 })
1711 }
1712 var prefix = "pct";
1713 get_float_string(prefix, "bet", find_object(prefix, "bet"));
1714 changed_chance("pct");
1715 if (data.ignores) ignores = data.ignores;
1716 while (data.chat.length) {
1717 var c = JSON.parse(data.chat.shift());
1718 var date = data.chat.shift();
1719 if (ignores.indexOf(c.user) == -1) {
1720 var chattxt;
1721 if (c.emote) chattxt = "(" + c.user + ") * <" + c.name.replace(/>/g, "]").replace(/</g, "[") + "> " + c.txt;
1722 else chattxt = "(" + c.user + ") <" + c.name.replace(/>/g, "]").replace(/</g, "[") + "> " + c.txt;
1723 add_chat(new Date(parseInt(date)), chattxt, false, false, true)
1724 }
1725 }
1726 set_google_auth_status(data.ga);
1727 $("#ga_edit, .edit_locked").click(function() {
1728 socket.emit("edit_ga", csrf)
1729 });
1730 var history_types = ["deposit", "withdraw", "invest", "commission", "offchain"];
1731 for (var i in history_types) bind_history(history_types[i])
1732 });
1733 socket.on("history", function(type, fields) {
1734 var report = '<table class="hist_table"><tr>';
1735 report += "<th>id</th>";
1736 report += "<th>when</th>";
1737 var date, data;
1738 switch (type) {
1739 case "commission":
1740 report += "<th>profit</th>";
1741 report += "<th>commission</th>";
1742 report += "<th>reason</th>";
1743 break;
1744 case "deposit":
1745 case "offchain":
1746 report += "<th>amount</th>";
1747 report += "<th>note</th>";
1748 break;
1749 case "invest":
1750 report += "<th>what</th>";
1751 report += "<th>commission</th>";
1752 report += "<th>% of site</th>";
1753 report += "<th>investment</th>";
1754 report += "<th>profit</th>";
1755 report += "<th>base</th>";
1756 break;
1757 case "withdraw":
1758 report += "<th>amount</th>";
1759 report += "<th>address</th>";
1760 report += "<th>txid</th>";
1761 break;
1762 default:
1763 return
1764 }
1765 report += "</tr>";
1766 while (true) {
1767 if ((data = fields.pop()) === undefined) break;
1768 date = moment(parseInt(data.date)).format(type == "invest" ? "YY-MM-DD<br/>HH:mm" : "YY-MM-DD HH:mm");
1769 report += "<tr><td>" + data.eid + "</td><td>" + date + "</td>";
1770 switch (type) {
1771 case "commission":
1772 report += "<td>" + data.profit.toFixed(8) + "</td>";
1773 report += "<td>" + data.commission.toFixed(8) + "</td>";
1774 report += "<td>" + data.reason.replace(/(\d+[.]\d{8})\d+/g, "$1").replace(/ = \d+[.]\d+/, "") + "</td>";
1775 break;
1776 case "deposit":
1777 case "offchain":
1778 report += "<td>" + data.amount.toFixed(8) + "</td>";
1779 report += "<td>" + break_long_words(quote_html(unescape_html(data.note ? data.note : ""))) + "</td>";
1780 break;
1781 case "invest":
1782 report += "<td>" + (data.amount === 0 ? "end-of-period<br/>commission" : data.amount > 0 ? "invest " + data.amount.toFixed(8) : "divest " + (-data.amount).toFixed(8)) + "</td>";
1783 report += "<td>" + data.commission.toFixed(8) + "</td>";
1784 var from = (data.share_old * 100).toFixed(6);
1785 var to = (data.share_new * 100).toFixed(6);
1786 if (from == to) report += "<td>" + to + "</td>";
1787 else report += "<td>from " + from + "<br/>to " + to + "</td>";
1788 from = data.investment_old.toFixed(8);
1789 to = data.investment_new.toFixed(8);
1790 if (from == to) report += "<td>" + to + "</td>";
1791 else report += "<td>from " + from + "<br/>to " + to + "</td>";
1792 from = (data.investment_old - data.prin_old).toFixed(8);
1793 to = (data.investment_new - data.prin_new).toFixed(8);
1794 if (from == to || data.commission === 0) report += "<td>" + to + "</td>";
1795 else report += "<td>from " + from + "<br/>to " + to + "</td>";
1796 to = data.base_new.toFixed(8);
1797 report += "<td>" + to + "</td>";
1798 break;
1799 case "withdraw":
1800 report += "<td>" + data.amount.toFixed(8) + "</td>";
1801 report += "<td>" + quote_html(data.address) + "</td>";
1802 if (data.txid) {
1803 report += "<td>";
1804 report += '<a href="http://khashier.com/tx/' + data.txid + '" target="_blank">' + data.txid.substring(0, 20) + "...</a>";
1805 if (data.note) report += " " + break_long_words(quote_html(data.note));
1806 report += "</td>"
1807 } else if (data.note) report += "<td>" + break_long_words(quote_html(data.note)) + "</td>";
1808 else report += "<td></td>";
1809 break
1810 }
1811 report += "</tr>"
1812 }
1813 report += "</table>";
1814 $("#hist_report").html(report)
1815 });
1816 socket.on("setup_ga", function(ga) {
1817 $.fancybox('<div class="setup_ga">' + "<h1>Set Up Google Authenticator</h1>" + '<div class="fleft">' + ga.qrcode + '<div class="secret">' + ga.secret + "</div>" + "</div>" + '<div class="fleft" id="desc">' + "<p>To enable two-factor security on Just-Dice, find and install " + '"Google Authenticator" from your smartphone\'s app store ' + 'then go to "Set up account" and then "Scan a barcode" and scan the code to the left, ' + 'or "Enter provided key", and enter the key under it.</p>' + "<p>Finally, type the 6 digit code it gives you and click the OK button.</p>" + '<div class="input_ok_input"><input id="ga_code"></div>' + '<div class="fleft input_ok_button"><button id="ga_button">OK</button></div>' + "</div>" + '<div class="clear"></div>' + '<div class="gap"></div>' + '<div class="important">Make a backup copy of the code under the QR code on paper for when you lose or reset your phone!</div>' + '<div id="form_error"></div>' + "</div>");
1818 var code = $("#ga_code");
1819 var button = $("#ga_button");
1820 code.focus();
1821 code.keypress(function(e) {
1822 if (e.which == 13) socket.emit("setup_ga_code", csrf, code.val())
1823 });
1824 button.click(function(e) {
1825 socket.emit("setup_ga_code", csrf, code.val())
1826 })
1827 });
1828 socket.on("edit_ga", function(ga) {
1829 edit_ga(ga)
1830 });
1831 socket.on("ga_info", function(ga) {
1832 set_google_auth_status(ga)
1833 });
1834 socket.on("ga_code_ok", function(ga) {
1835 $.fancybox.close();
1836 edit_ga(ga)
1837 });
1838 socket.on("ga_code_done", function() {
1839 $.fancybox.close()
1840 });
1841 socket.on("wdaddr", function(wdaddr) {
1842 withdraw_address = wdaddr
1843 });
1844 socket.on("balance", function(data) {
1845 set_balance(data);
1846 var prefix = "pct";
1847 get_float_string(prefix, "bet", find_object(prefix, "bet"))
1848 });
1849 socket.on("details", function(html) {
1850 $.fancybox(html, {
1851 helpers: {
1852 overlay: {
1853 closeClick: true,
1854 css: {
1855 background: "rgba(0, 0, 0, 0.5)"
1856 }
1857 }
1858 }
1859 })
1860 });
1861 socket.on("max_profit", function(max_profit, bankroll) {
1862 update_max_profit(max_profit, bankroll)
1863 });
1864 socket.on("shash", function(data) {
1865 $("#shash").html(data)
1866 });
1867 socket.on("seed", function(data) {
1868 $("#seed").html(data)
1869 });
1870 socket.on("bad_seed", function(data) {
1871 $.fancybox.close();
1872 msg("You have already made " + data + " bet(s) since you last clicked 'randomize' so can't change client seed until you re-randomize,")
1873 });
1874 socket.on("nonce", function(data) {
1875 set_nonce(data)
1876 });
1877 socket.on("clamour", function(data) {
1878 $("#clamours").val(data)
1879 });
1880 var clamerr_timeout;
1881 socket.on("clamerr", function(data) {
1882 $("#clamerr").html(data);
1883 if (clamerr_timeout) clearTimeout(clamerr_timeout);
1884 clamerr_timeout = setTimeout(function() {
1885 $("#clamerr").html("")
1886 }, 1e3 * 3)
1887 });
1888 socket.on("address", function(address, img, confs) {
1889 $.fancybox('<div class="deposit">' + "<h1>Deposit " + currency + "s</h1>" + "<p><b>Note:</b> Before depositing, please confirm that this type of gambling is legal in your jurisdiction.</p>" + '<div class="fleft">' + '<a href="clam:' + address + '">' + img + "</a>" + "</div>" + '<div class="fleft" id="desc">' + "<p>To deposit, send " + currency + "s to:</p>" + '<p class="address">' + address + "</p>" + "<p>" + confs + "</p>" + "<p>Any deposits of less than 0.001 CLAMs will be ignored.</p>" + "<p>You can reuse old deposit addresses <b>from 1st April 2017 or later</b>. Deposits to addresses created before then will be credited to your account but it can take 24 hours or more.</p>" + "</div>" + '<div class="clear">' + "</div>" + "</div>", {
1890 helpers: {
1891 overlay: {
1892 closeClick: true,
1893 css: {
1894 background: "rgba(0, 0, 0, 0.5)"
1895 }
1896 }
1897 }
1898 })
1899 });
1900 socket.on("new_client_seed", function(old_secret, old_shash, old_seed, old_nonce, shash) {
1901 var random_seed = random_number(seed_length);
1902 $.fancybox("<div>" + "<h2>Randomize Your Rolls</h2>" + "<p>The last server seed was:</p>" + mono(old_secret, "old_sseed") + "<p>The last server seed hash was:</p>" + mono(old_shash, "old_shash") + "<p>Your client seed for that server seed was:</p>" + mono(old_seed, "old_cseed") + "<p>The number of rolls you made with the last pair of seeds was:</p>" + mono(old_nonce, "old_nonce") + "<p>Here are the previous four values in a single field for easy copy/pasting into a verification tool:</p>" + '<textarea rows=3 cols=66 class="allcodes" onclick="this.select();">"' + old_secret + '" "' + old_shash + '" "' + old_seed + '" "' + old_nonce + '"</textarea>' + "<p>We've picked a new server seed with this hash:</p>" + mono(shash, "new_shash") + '<p class="important">Type up to ' + seed_length + " random characters (0-9, a-z, A-Z) to re-randomize with your own seed:</p>" + '<div class="input_ok">' + '<div class="input_ok_input"><input id="new_cseed" class="seed_input" size="' + seed_length + '" maxlength="' + seed_length + '" value="' + random_seed + '"></div>' + '<div class="fleft indent"><button class="seed_button">ok</button></div>' + '<div class="clear"></div>' + "</div>" + '<div class="important" id="form_error"></div>' + "</div>", {
1903 keys: {
1904 close: []
1905 },
1906 closeBtn: true,
1907 helpers: {
1908 overlay: {
1909 closeClick: false,
1910 css: {
1911 background: "rgba(0, 0, 0, 0.5)"
1912 }
1913 }
1914 }
1915 });
1916 var msg = "Please type some random characters (0-9, a-z, A-Z) in the box to ensure a fair game!";
1917 var seed_o = $(".seed_input");
1918 var emit_seed_timeout;
1919 socket.emit("seed", csrf, random_seed, false);
1920 $(".seed_button").click(function(e) {
1921 if (seed_o.filter(".invalid").length) $("#form_error").html("<p>" + msg + "</p>");
1922 else {
1923 clearTimeout(emit_seed_timeout);
1924 socket.emit("seed", csrf, seed_o.val(), true)
1925 }
1926 });
1927 seed_o.focus().keyup(function(e) {
1928 var seed = seed_o.val();
1929 if (seed.replace(/[^0-9a-z]/gi, "") != seed || seed === "") seed_o.addClass("invalid");
1930 else {
1931 seed_o.removeClass("invalid");
1932 clearTimeout(emit_seed_timeout);
1933 emit_seed_timeout = setTimeout(function() {
1934 socket.emit("seed", csrf, seed, false)
1935 }, 1e3)
1936 }
1937 if (e.which == 13 || e.which == 27) {
1938 if (seed_o.filter(".invalid").length) $("#form_error").html("<p>" + msg + "</p>");
1939 else {
1940 clearTimeout(emit_seed_timeout);
1941 socket.emit("seed", csrf, seed_o.val(), true)
1942 }
1943 }
1944 })
1945 });
1946 socket.on("jderror", function(data) {
1947 set_waiting(false);
1948 msg(data)
1949 });
1950 socket.on("jdmsg", function(data) {
1951 msg(data)
1952 });
1953 socket.on("form_error", function(data) {
1954 form_error(data)
1955 });
1956 socket.on("login_error", function(data) {
1957 $("#login_error").html(data)
1958 });
1959 socket.on("wins", function(data) {
1960 $("#wins,#wins2").html(commaify(data))
1961 });
1962 socket.on("losses", function(data) {
1963 $("#losses,#losses2").html(commaify(data))
1964 });
1965 var hi = 255;
1966 var lo = 224;
1967 var on_green = "rgba(" + lo + ", " + hi + ", " + lo + ", 1)";
1968 var on_red = "rgba(" + hi + ", " + lo + ", " + lo + ", 1)";
1969 var off = "#aaa";
1970 var wins = $("#wins");
1971 var losses = $("#losses");
1972 wins.css({
1973 backgroundColor: off
1974 });
1975 losses.css({
1976 backgroundColor: off
1977 });
1978 socket.on("pong", function() {
1979 console.log("pong")
1980 });
1981 socket.on("result", function(data) {
1982 if ("error" in data) {
1983 msg(data.error);
1984 set_waiting(false);
1985 return
1986 }
1987 var me = data.uid == uid;
1988 if (bet_interesting_p(data.bet, data.this_profit, data.uid, me)) add_result(data, me);
1989 if (bet_chat_interesting_p(data.bet, data.this_profit, data.uid)) add_result_to_chat(data);
1990 max_profit = parseFloat(data.max_profit);
1991 $("#max_profit").html(commaify(max_profit.toFixed(2)));
1992 $(".bankroll").html(commaify(data.bankroll));
1993 var prefix = "pct";
1994 var profit_o = find_object(prefix, "profit");
1995 var profit = get_float_string(prefix, "profit", profit_o);
1996 update_site_stats(data.stats);
1997 update_investment(data.investment, data.percent, data.invest_pft);
1998 if (me) {
1999 clear_msg();
2000 wins.stop();
2001 losses.stop();
2002 if (data.win) {
2003 wins.animate({
2004 backgroundColor: on_green
2005 });
2006 losses.animate({
2007 backgroundColor: off
2008 })
2009 } else {
2010 wins.animate({
2011 backgroundColor: off
2012 });
2013 losses.animate({
2014 backgroundColor: on_red
2015 })
2016 }
2017 set_waiting(false);
2018 update_my_stats(data.bets, null, null, data.luck, data.wagered, data.profit);
2019 set_balance(data.balance);
2020 set_nonce(data.nonce);
2021 changed_bet("pct")
2022 } else if (settings.alarm && data.this_profit.substring(1) >= 10) $("#whale").get(0).play()
2023 });
2024 socket.on("old_results", function(data) {
2025 if (seen_results) return;
2026 seen_results = true;
2027 for (var index in data) {
2028 var result = data[index];
2029 var me = result.uid == uid;
2030 if (bet_interesting_p(result.bet, result.this_profit, result.uid, me)) add_result(result, me, true)
2031 }
2032 });
2033 socket.on("css", function(selector, json) {
2034 try {
2035 $(selector).css(JSON.parse(json))
2036 } catch (err) {}
2037 });
2038 socket.on("animate", function(selector, json, delay) {
2039 try {
2040 $(selector).animate(JSON.parse(json), parseInt(delay))
2041 } catch (err) {}
2042 });
2043 socket.on("withdraw", function() {
2044 clicked_action_withdraw()
2045 });
2046 handle_events("pct");
2047 $(".readonly").attr("tabindex", "-1").attr("readonly", true);
2048 $("#c_min").click(clicked_chance_min);
2049 $("#c_minus").click(clicked_chance_minus);
2050 $("#c_half").click(clicked_chance_half);
2051 $("#c_double").click(clicked_chance_double);
2052 $("#c_plus").click(clicked_chance_plus);
2053 $("#c_max").click(clicked_chance_max);
2054 $(".chance_toggle").click(clicked_chance_toggle);
2055 $("#b_min").click(clicked_bet_min);
2056 $("#b_half").click(clicked_bet_half);
2057 $("#b_double").click(clicked_bet_double);
2058 $("#b_max").click(clicked_bet_max);
2059 $(".bet_toggle").click(clicked_bet_toggle);
2060 $("#a_hi").click(clicked_action_bet_hi);
2061 $("#a_lo").click(clicked_action_bet_lo);
2062 $("#a_deposit").click(clicked_action_deposit);
2063 $("#a_withdraw").click(clicked_action_withdraw);
2064 $("#a_random").click(clicked_action_random);
2065 $(".action_toggle").click(clicked_action_toggle);
2066 $("#mypass").val("");
2067 $("#mycode").val("");
2068 $("#myuser").val("").add("#mypass").add("#mycode").keypress(function(e) {
2069 if (e.which == 13) clicked_login()
2070 });
2071 $("#myok").click(clicked_login);
2072 $("#reset_profit").click(clicked_reset_profit);
2073 $("#real_profit").click(clicked_real_profit);
2074 $("#forget_max_warning").click(clicked_forget_max_warning);
2075 $("#logout").click(clicked_logout);
2076 $("#name").click(clicked_action_name);
2077 $("#invest_edit").click(clicked_action_invest);
2078 $("#toggle_color_editor").click(clicked_toggle_color_editor);
2079 $("button.style").each(function() {
2080 var button = $(this);
2081 button.click(function() {
2082 switch_style(styles[button.attr("id")])
2083 })
2084 });
2085 init_keybindings(chatinput);
2086 clear_msg()
2087 }
2088
2089 function reset_profit(offset) {
2090 profit_offset = offset;
2091 $(".myprofit").html(fixed(real_profit - profit_offset))
2092 }
2093
2094 function update_news(n) {
2095 news = linkify_text(quote_html(n).substring(0, 300));
2096 clear_msg()
2097 }
2098
2099 function update_max_profit(max, bankroll) {
2100 max_profit = parseFloat(max);
2101 $("#max_profit").html(commaify(max_profit.toFixed(2)));
2102 $(".bankroll").html(commaify(bankroll));
2103 var prefix = "pct";
2104 var profit_o = find_object(prefix, "profit");
2105 var profit = get_float_string(prefix, "profit", profit_o)
2106 }
2107
2108 function in_array(element, array) {
2109 if (typeof array == "number") return element == array;
2110 if (!array.match(/\d/)) return true;
2111 return $.inArray(element, array.split(/\D+/)) != -1
2112 }
2113
2114 function bet_interesting_p(bet, profit, uid, me) {
2115 return me || (!settings.min_risk && !settings.min_change || settings.min_risk && bet >= settings.min_risk || settings.min_change && Math.abs(profit) >= settings.min_change) && (!settings.watch_player || in_array(uid, settings.watch_player))
2116 }
2117
2118 function bet_chat_interesting_p(bet, profit, uid) {
2119 return (!settings.chat_min_risk && !settings.chat_min_change || settings.chat_min_risk && bet >= settings.chat_min_risk || settings.chat_min_change && Math.abs(profit) >= settings.chat_min_change) && (!settings.chat_watch_player || in_array(uid, settings.chat_watch_player))
2120 }
2121
2122 function bind_history(type) {
2123 $("#hist_" + type).click(function() {
2124 socket.emit("history", csrf, type)
2125 })
2126 }
2127
2128 function form_error(txt) {
2129 $("#form_error").html("<p>" + txt + "</p>");
2130 return false
2131 }
2132
2133 function show_change_password() {
2134 $.fancybox("<div class='setup_account'>" + "<h1>Change Password</h1>" + '<form onSubmit="return change_password(this);"><input type="hidden" id="username" value="' + username + '">' + '<div class="fleft w200 aright rpad">Current Password</div> ' + '<div class="input_ok_input"><input type="password" size=40 id="current"></div>' + '<div class="clear"></div>' + '<div class="fleft w200 aright rpad">New Password</div>' + '<div class="input_ok_input"><input type="password" size=40 id="password"></div>' + '<div class="clear"></div>' + '<div class="fleft w200 aright rpad">Repeat New Password</div>' + '<div class="input_ok_input"><input type="password" size=40 id="password2"></div>' + '<div class="clear"></div>' + '<div class="fright input_ok_button"><input type="submit" value="OK"></div>' + '<div class="clear"></div>' + '<div id="form_error"></div>' + "</form></div>", {
2135 helpers: {
2136 overlay: {
2137 closeClick: true,
2138 css: {
2139 background: "rgba(0, 0, 0, 0.5)"
2140 }
2141 }
2142 }
2143 });
2144 $("#current").focus()
2145 }
2146 window.change_password = function(f) {
2147 var current = f.current.value,
2148 password1 = f.password.value,
2149 password2 = f.password2.value;
2150 if (current === "" || password1 === "") return form_error("Please enter details into all fields.");
2151 if (password1 != password2) return form_error("New passwords aren't the same." + password1 + password2);
2152 socket.emit("change_password", csrf, current, password1);
2153 return false
2154 };
2155 window.setup_account = function(f) {
2156 var username = f.username.value,
2157 password1 = f.password.value,
2158 password2 = f.password2.value;
2159 if (username === "") return form_error("Username must not be empty.");
2160 if (password1 === "" || password2 === "") return form_error("Password must not be empty.");
2161 if (password1 != password2) return form_error("Passwords aren't the same.");
2162 socket.emit("setup_account", csrf, username, password1);
2163 return false
2164 };
2165
2166 function edit_ga(ga) {
2167 var flags = "";
2168 for (var i in ga_fields) {
2169 var field = ga_fields[i];
2170 var flag = ga.flags[field];
2171 var field_id = field.replace(/ /g, "_");
2172 if (field == "edit") field = "edit emergency withdrawal and email addresses";
2173 flags += '<p><input type="checkbox" id="' + field_id + '_box"' + (flag ? ' checked="checked"' : "") + "> " + field + "</p>"
2174 }
2175 $.fancybox('<div class="edit_ga">' + '<div class="desc">You can change which of the following activities will require you to enter a Google Auth code:</div>' + '<div class="boxes">' + flags + "</div>" + '<div class="desc">Enter your 6 digit Google Auth code to confirm any changes, or just close the dialog to leave things unchanged.<br/><br/></div>' + '<div class="input_ok_input"><input id="ga_code"></div>' + '<div class="fleft input_ok_button"><button id="ga_button">OK</button></div>' + '<div class="fleft input_ok_button"><button id="ga_disable">Disable Google-Auth</button></div>' + '<div class="clear"></div>' + '<div id="form_error"></div>' + "</div>");
2176 var code = $("#ga_code");
2177 var button = $("#ga_button");
2178 var disable = $("#ga_disable");
2179 code.keypress(function(e) {
2180 if (e.which == 13) done_edit_ga(code)
2181 });
2182 button.click(function(e) {
2183 done_edit_ga(code)
2184 });
2185 disable.click(function(e) {
2186 socket.emit("disable_ga", csrf, code.val())
2187 })
2188 }
2189
2190 function done_edit_ga(code) {
2191 var flags = {};
2192 for (var i in ga_fields) {
2193 var field = ga_fields[i];
2194 var field_id = field.replace(/ /g, "_");
2195 flags[field] = $("#" + field_id + "_box").prop("checked")
2196 }
2197 socket.emit("done_edit_ga", csrf, code.val(), flags)
2198 }
2199
2200 function set_google_auth_status(ga) {
2201 if (ga.active) {
2202 $(".edit_locked").show();
2203 if (ga.flags.edit === false) {
2204 $(".edit_locked").html("lock");
2205 $("#btcaddr, #emailaddr").attr("readonly", false)
2206 } else {
2207 $(".edit_locked").html("unlock");
2208 $("#btcaddr, #emailaddr").attr("readonly", true)
2209 }
2210 } else {
2211 $(".edit_locked").hide()
2212 }
2213 google_auth = ga;
2214 var info = "";
2215 var status = "enabled";
2216 if (ga.active) {
2217 var enabled = [];
2218 for (var i in ga.flags)
2219 if (ga.flags[i]) enabled.push(i);
2220 if (enabled.length) info = "Authentication is required for " + enabled.join(", ") + ".";
2221 else info = "Authentication is not required for any activity."
2222 } else status = "not " + status;
2223 $("#ga_info").html(info);
2224 $("#ga_status").html(status)
2225 }
2226 window.u = function(uid) {
2227 var txt = chatinput.val();
2228 var matches;
2229 if (txt.match(/^\s*$/)) {
2230 txt = "/msg " + uid + " ";
2231 chatinput_class = 3;
2232 chatinput.addClass("chatpm").removeClass("chatmod chatinfo")
2233 } else if (matches = txt.match(/^(\s*\/tip)\s*$/)) txt = matches[1] + " " + uid + " ";
2234 else if (matches = txt.match(/^(\s*\/tip\s+[0-9,]+)\s*$/)) txt = matches[1] + "," + uid + " ";
2235 else txt += uid + " ";
2236 chatinput.val(txt);
2237 chatinput.focus()
2238 };
2239 window.n = function(name) {
2240 var txt = chatinput.val();
2241 txt += name + ", ";
2242 chatinput.val(txt);
2243 chatinput.focus()
2244 };
2245
2246 function linkify_uid(txt) {
2247 var matches = txt.match(/^[(]([0-9]+)[)] <([@+]?)(.*)>$/);
2248 if (!matches) return [txt, "0"];
2249 var uid = matches[1],
2250 op = matches[2],
2251 name = matches[3];
2252 return ['<span onclick="u(' + uid + ');">(' + uid + ')</span> <span onclick="n(' + "'" + name + "'" + ');"><' + op + name + "></span>", uid]
2253 }
2254
2255 function linkify_bet(txt) {
2256 return txt.replace(/\[#([0-9]+)\]/, '[<a target="_blank" href="/roll/$1">#$1</a>]')
2257 }
2258
2259 function linkify_text(txt) {
2260 return txt.replace(/(^|[^0-9a-z#])((?:betid|roll):? |#)([1-9][0-9]{4,9})\b/gi, '$1<a target="_blank" href="/roll/$3">$2$3</a>').replace(/(https:\/\/just-dice[.]com\/roll\/)([1-9][0-9]{0,9})/gi, ' <a target="_blank" href="/roll/$2">$2</a> ').replace(/(bitcoin-talk|bticointakl)(\b[^<]*$)/gi, "$1 (a phishing site, do not visit)$2").replace(/dicen[o0]w/gi, "dice-now").replace(/letsdice/gi, "lets-dice").replace(/grindabit/gi, "spamalot").replace(/bitdice[.]de/gi, "[yet more spam]").replace(/(http:\/\/just-dice[.]blogspot[.](?:ca|com)\/[0-9]+\/[0-9]+\/([a-z0-9-]+)(?:_[0-9]+)?[.]html)/gi, '[<a target="_blank" href="$1">$2</a>]').replace(/(?:https?:\/\/)?(?:www[.])?cryptodouble[.]com(?:\/(?:[?]?ref=[0-9a-z]*)?)?\b/gi, "[Ponzi spam]").replace(/([\/#?]|&)(id|from|code|partner|bonus|r|ref[_a-z]*)\s*=\s*(?:.+?\b)/gi, "$1$2= [spam link] ").replace(/(\/ref\/[0-9a-z\/]*)/gi, " [spam link]").replace(/(speedy[.]sh|bit\s*[.]\s*ly|gg\s*[.]\s*gg|cc4\s*[.]\s*co|fkref\s*[.]\s*com|cur\s*[.]\s*lv|goo\s*[.]\s*gl|is\s*[.]\s*gd|tinyurl\s*[.]\s*com|ge\s*[.]\s*tt)\/[?]?[a-z0-9-]{4,}/gi, "[suspicious link]").replace(/\bbitwars\b/gi, "[spam link]").replace(/\bmegaapp\b/gi, "[suspicious link]").replace(/\b(javascript:)/i, "[potential scam warning] $1").replace(/([a-z0-9.-_]*buybtc[a-z0-9.-_]*@gmail[.])com/gi, "I am a scammer and will steal your coins! $1cum to meet your sticky end!").replace(/([a-z0-9.-_]*buybtc[a-z0-9.-_]*@gmail[.])com/gi, "").replace(/(^|[^a-z])[á´¦rг]â *(h*)[aäΑÐÉ‘]â *[pÑ€]â *[eеΕ]/gi, "$1t$2ickle").replace(/(^|[^a-z])[á´¦rг]â *(h*)[aäΑÐÉ‘]â *[pÑ€]â *iâ *([^d])/gi, "$1t$2ickli$3").replace(/(^|[^a-z])[á´¦rг]â *(h*)[aäΑÐÉ‘]â *[eеΕ]â *[pÑ€]/gi, "$1t$2ickel").replace(/(^|[^a-z])[á´¦rг]â *(h*)[aäΑÐÉ‘]â *[eеΕ]â *[pÑ€]â *i/gi, "$1t$2ickeli").replace(/(^|[^s])((?:(?:[nñṉɴâ“Î]|[1iá¸Ñ–lɪ!|\\\/]â *[1iá¸Ñ–lɪ!|\\\/]â *[1iá¸Ñ–lɪ!|\\\/])(?:[â ]*))+)((?:[1iá¸Ñ–lɪ!|ⓘ][â ]*)+)([gḡǥɢⓖ9][â ]*)((?:[gḡǥɢⓖ9][â ]*)+)((?:(?:[3eḛееΕᴇuâ“”aäá¸Ð°@iá¸Ñ–][â ]*)+)(?:[á´¦rá¹™Ñгʀⓡ][â ]*)+|(?:[a@äá¸Ð°á´€4â“][â ]*)+)/gi, "$1$4$3$2$5$6").replace(/\b(butthurt)\b/gi, '<a target="_blank" href="https://just-dice.com/images/form.jpg">$1</a>').replace(/\b(pony|ponies|mlp)\b/gi, '<a target="_blank" href="http://theevildragon.imgur.com/">$1</a>').replace(/(^|[^\/])\b(biggest)\b/gi, '$1<a target="_blank" href="misc/biggest.txt">$2</a>').replace(/\bhttps:\/\/just-dice[.]com\/misc\/biggest[.]txt\b/gi, '<a target="_blank" href="misc/biggest.txt">biggest bets</a>').replace(/\b(milestones)\b/gi, '<a target="_blank" href="misc/milestones.htm">$1</a>').replace(/\bhttps:\/\/just-dice[.]com\/misc\/milestones[.]htm\b/gi, '<a target="_blank" href="misc/milestones.htm">milestone bets</a>').replace(/\b(https:\/\/just-dice[.]com\/images\/bg[.]png|wallpaper)\b/gi, '<a target="_blank" href="images/bg.png">wallpaper</a>').replace(/\bhttps:\/\/just-dice[.]com\/(user\/(\d+))\b/i, '[<a target="_blank" href="$1">user $2 stats</a>]').replace(/\b(list of petitions)\b/gi, '<a target="_blank" href="http://txti.es/clamour">$1</a>').replace(/\b(?:daily stats|https:\/\/just-dice[.]com\/misc\/wagered[.]txt)\b/gi, '<a target="_blank" href="misc/wagered.txt">daily stats</a>').replace(/\b(dice[.]js)\b/gi, '<a target="_blank" href="/javascripts/dice.js">$1</a>').replace(/\b(dice[.]css)\b/gi, '<a target="_blank" href="/stylesheets/dice.css">$1</a>').replace(/\b(recent profit(?: chart|s)?)\b/i, '<a target="_blank" href="images/recent_profit.png">$1</a>').replace(/\bhttps:\/\/just-dice[.]com\/images\/recent_profit[.]png\b/i, '<a target="_blank" href="images/recent_profit.png">recent profit chart</a>').replace(/\b(all.?time profit(?: chart|s)?)\b/i, '<a target="_blank" href="images/all_time_profit.png">$1</a>').replace(/\bhttps:\/\/just-dice[.]com\/images\/all_time_profit[.]png\b/i, '<a target="_blank" href="images/all_time_profit.png">all-time profit chart</a>').replace(/\b(percentage profit(?: chart)?)\b/i, '<a target="_blank" href="images/percentage_profit.png">$1</a>').replace(/\bhttps:\/\/just-dice[.]com\/images\/percentage_profit[.]png\b/i, '<a target="_blank" href="images/percentage_profit.png">percentage profit chart</a>').replace(/\b(investor stats)\b/i, '<a target="_blank" href="http://just-dice.blogspot.com/search/label/bankroll">$1</a>').replace(/\b(IRC)\b/, '<a target="_blank" href="http://webchat.freenode.net/?channels=clams">$1</a>').replace(/\b(?:(?:https?:\/\/)?(?:just-agar(?:[.]com)?|agar(?:[.]io)?)(?:\/(?:[?][0-9]+[.][0-9]+[.][0-9]+[.][0-9]+(?::[0-9]+)?)?)?)(\b|\s|$)/gi, '[<a target="_blank" href="http://just-agar.com/">agar</a>]$1').replace(/(?:(?:https?:\/\/)?(?:www[.])?clamsight(?:[.]com)?)(\b[^<\/]*(\s|$))/gi, '[<a target="_blank" href="http://clamsight.com/">clamsight</a>]$1').replace(/(?:(?:https?:\/\/)?(?:www[.])?blocktree(?:[.]io(?:\/e\/CLAM\/?)?)?)([^<\/]*(\s|$))/gi, '[<a target="_blank" href="http://blocktree.io/e/CLAM">blocktree</a>] $1').replace(/(blockchain[.]info\/)(?:[a-w]{2}|zh-cn)\//g, "$1").replace(/\b(?:(?:https?:\/\/)?(?:www[.])?blockchain[.]com\/(?:[a-z]+\/)?btc\/tx\/|btc:)([0-9a-f]{8})([0-9a-f]{56})\b/gi, '[<a target="_blank" href="https://www.blockchain.com/btc/tx/$1$2">BTC:$1</a>]').replace(/\b(?:(?:https?:\/\/)?live[.]blockcypher[.]com\/ltc\/tx\/|ltc:)([0-9a-f]{8})([0-9a-f]{56})\b[\/]?/gi, '[<a target="_blank" href="https://live.blockcypher.com/ltc/tx/$1$2/">LTC:$1</a>]').replace(/\b(?:(?:https?:\/\/)?dogechain.info\/tx\/|doge:)([0-9a-f]{8})([0-9a-f]{56})\b/gi, '[<a target="_blank" href="https://dogechain.info/tx/$1$2">DOGE:$1</a>]').replace(/\b(?:https?:\/\/)?((?:clamsight[.]com\/tx\/|khashier[.]com\/tx\/|(?:www[.])?presstab[.]pw\/phpexplorer\/CLAM\/tx[.]php[?]tx=|(?:www[.])?blocktree[.]io\/(?:tx|transaction)\/CLAM\/)([0-9a-f]{8})([0-9a-f]{56}))\b/g, '[<a target="_blank" href="http://khashier.com/tx/$2$3">$2</a>]').replace(/(^|[^\/:=\b])(?:(?:tx(?:id)?|clam)?:)?([0-9a-f]{8})([0-9a-f]{56})\b/g, '$1[<a target="_blank" href="http://khashier.com/tx/$2$3">$2</a>]').replace(/(^|[^a-zA-Z0-9\/=?])(?:(?:https?:\/\/)?(?:www[.])?blockchain[.]com\/(?:[a-z]+\/)?btc\/address\/)?([13][1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{19,26})\b/g, '$1[<a target="_blank" href="http://www.blockchain.com/btc/address/$2$3">$2</a>]').replace(/\b(?:(?:https?:\/\/)?dogechain[.]info\/address\/)?(D[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '[<a target="_blank" href="http://dogechain.info/address/$1$2">$1</a>]').replace(/\b(?:(?:https?:\/\/)?live[.]blockcypher[.]com\/ltc\/address\/)?(L[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})(?:\/|\b)/g, '[<a target="_blank" href="http://live.blockcypher.com/ltc/address/$1$2/">$1</a>]').replace(/\b(?:(?:https?:\/\/)?clamsight[.]com\/address\/)(x[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '[<a target="_blank" href="http://khashier.com/address/$1$2">$1</a>]').replace(/\b(?:(?:https?:\/\/)?khashier[.]com\/address\/)(x[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '[<a target="_blank" href="http://khashier.com/address/$1$2">$1</a>]').replace(/\b(?:(?:https?:\/\/)?(?:www[.])?presstab[.]pw\/phpexplorer\/CLAM\/address.php[?]address=)(x[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '[<a target="_blank" href="http://khashier.com/address/$1$2">$1</a>]').replace(/(^|[^a-zA-Z0-9\/=?])(?:(?:https?:\/\/)?(?:www[.])?blocktree[.]io\/address\/CLAM\/)?(x[1-9A-HJ-NP-Za-km-z]{7})([1-9A-HJ-NP-Za-km-z]{24,26})\b/g, '$1[<a target="_blank" href="http://khashier.com/address/$2$3">$2</a>]').replace(/\b(hot wallet(?: balance)?)\b/i, '<a target="_blank" href="http://khashier.com/chain/Clam/q/addressbalance/xJDCLAMZBRAhGZognJfhqa5YpAobQGNTXT">$1</a>').replace(/\b(warm wallet(?: balance)?)\b/i, '<a target="_blank" href="http://khashier.com/chain/Clam/q/addressbalance/xJDCLAMZGCSLgHtDXE7hJK6faxxvWsSwGo">$1</a>').replace(/\b(?:xchange|(?:https?:\/\/)?(?:www[.])?freebitcoins[.]com\/xchange(?:\/(?:market\/BTC_CLAM)?)?)/gi, '[<a target="_blank" href="https://freebitcoins.com/xchange/market/BTC_CLAM?akey=8425fa8d74074c0b876cc034fcbb9bcc20674ae2">xchange</a>]').replace(/\b(?:clam markets|https?:\/\/(?:www[.])?coinmarketcap[.]com\/currencies\/clams\/#markets)\b/gi, '<a target="_blank" href="https://coinmarketcap.com/currencies/clams/#markets">CLAM markets</a>').replace(/\bhttps:\/\/gourl[.]io\/coin-voting[.]html\b/, '<a target="_blank" href="https://gourl.io/coin-voting.html">https://gourl.io/coin-voting.html</a>').replace(/\bhttps?:\/\/imgur[.]com\/a\/sFhLx\b/g, "klyeart").replace(/\bhttps:\/\/ip[.]bitcointalk[.]org\/[?]u=http%3A%2F%2F(i[.]imgur[.]com)%2F([^&]*)&t=[a-z0-9=&_;]*\b/gi, "https://$1/$2").replace(/\b(?:https?:\/\/)?((?:i|www)[.]imgur[.]com\/[0-9a-z]{5,9}[.](?:jpe?g|png|gifv?)(?:[?][0-9]+)?)\b/gi, '[<a target="_blank" href="https://$1">img</a>]').replace(/\b(?:https?:\/\/)?((?:i|www)[.]imgur[.]com\/[0-9a-z]{5,9}[.](?:webm|mp4)(?:[?][0-9]+)?)\b/gi, '[<a target="_blank" href="https://$1">video</a>]').replace(/\b(https?:\/\/imgur[.]com\/(?:a|gallery)\/[0-9a-z]{5,9}\/?(?:#\d+)?)(?:\b|$)/gi, '[<a target="_blank" href="$1">imgs</a>]').replace(/\bk(?:ly|yl)e(?:'?s)?\s*art(?:\s*[:#]?\s*([0-9]+))?\b/gi, function(match, p1) {
2261 return '<a target="_blank" href="http://imgur.com/a/sFhLx' + (p1 ? "#" + p1 : "") + '">KLYE ART' + (p1 ? ":" + p1 : "") + "</a>"
2262 }).replace(/\b((?:https?:\/\/)?(?:(?:www[.])?youtube[.]com\/watch[?]v=|youtu[.]be\/)[0-9a-z_-]{11}[?]?(?:(?:&)?(?:wide|(?:feature|list)=[a-z.0-9]*|t=[0-9msh]+))*)\b/gi, '[<a target="_blank" href="$1">video</a>]').replace(/\b(vid\b[.]\bme\/[a-z0-9]{3,8})\b/i, "$1 (beware: vid.me is used to spam coin-stealing malware)").replace(/\b(way she goes)\b/i, '<a target="_blank" href="https://youtu.be/gtM9xD-Ky7E">$1</a>').replace(/\b((?:my|your) dick)\b/i, '<a target="_blank" href="https://youtu.be/TNgWQfOd-1M">$1</a>').replace(/\b(bubble)\b/i, '<a target="_blank" href="https://youtu.be/KTf5j9LDObk">$1</a>').replace(/\b((?:you|u) have no power here)\b/i, '<a target="_blank" href="https://youtu.be/UuKsnsrQxVo">$1</a>').replace(/\b(?:https?:\/\/)?(mudi)(?:[.]mylittleponies[.]org)?(?:\b|\/)?/i, '<a target="_blank" href="http://mudi.mylittleponies.org/">$1</a>').replace(/\b((?:(?:(?:(?:do\s+)?you\s+)?want\s+to\s+)?trade\s+some\s+)?shit\s*coins?\b[?]{0,3})/gi, '<a target="_blank" href="https://youtu.be/3gfntBEI3Aw">$1</a>').replace(/\b(?:you(?:r|'re| are) (?:all )?gay)\b/i, '<a target="_blank" href="https://youtu.be/aO_DV1mw-Xo">your all gay</a>').replace(/\b(https?:\/\/(?:(?:www|r2)[.])?reddit[.]com\/r\/([a-z0-9]+)\/comments\/[a-z0-9]+\/([a-z0-9_]+)(?:\/[0-9a-z]+)?\/?)(\b| |$)/gi, '[<a target="_blank" href="$1">reddit:$2 $3</a>]$4').replace(/\b(https?:\/\/(?:www[.])?steemit[.]com\/(@[a-z0-9]+))(?:\b| |$)/gi, '<a target="_blank" href="$1">$2</a>').replace(/\b(https?:\/\/(?:www[.])?steemit[.]com\/[a-z0-9]+\/@[a-z0-9]+\/[a-z0-9-]+)(?:\b| |$)/gi, '[<a target="_blank" href="$1">steemit post</a>]').replace(/\b(https:\/\/bitcointalk[.]org\/(?:index[.]php)?[?]topic=[0-9]+(?:[.](?:new#new|(?:msg)?[0-9]+))?(?:;(?:all|topicseen))?(?:#new|#msg[0-9]+)?)\b/gi, '[<a target="_blank" href="$1">thread</a>]').replace(/\b(bootstrap[.]dat)\b/i, '<a target="_blank" href="https://bitcointalk.org/index.php?topic=623147.msg9772191#msg9772191">$1</a>')
2263 }
2264
2265 function add_chat(date, txt, look, is_bet, hilite, ding) {
2266 var matches, log, p, i;
2267 if (settings.mutechat) return;
2268 var prefix = "";
2269 var sender, name, tmp, tmp2, dinged = false;
2270 txt = quote_html(txt);
2271 if (!look) {
2272 var direct = txt.match(/^[[] (.*?) → (.*?) ](.*)$/);
2273 if (direct) {
2274 if (direct[2] == "@mods") {
2275 look = "chatmod";
2276 matches = direct[3].match(/^ ([(][0-9]+[)] <[@+]?.*?>) and ([(][0-9]+[)] <[@+]?.*?>)(.*)$/);
2277 if (matches) {
2278 prefix = linkify_uid(direct[1])[0] + " " + linkify_uid(matches[1])[0] + " and " + linkify_uid(matches[2])[0];
2279 txt = matches[3]
2280 } else {
2281 tmp = linkify_uid(direct[1]);
2282 prefix = tmp[0];
2283 sender = tmp[1];
2284 txt = direct[3]
2285 }
2286 } else {
2287 look = "chatpm";
2288 tmp = linkify_uid(direct[1]);
2289 tmp2 = linkify_uid(direct[2]);
2290 prefix = tmp[0] + " → " + tmp2[0];
2291 sender = tmp[1];
2292 txt = direct[3];
2293 if (tmp2[1] == uid) {
2294 if (settings.pmding) {
2295 dinged = true;
2296 $("#ding").get(0).play()
2297 }
2298 if (current_tab != "#chat") chattab.addClass("mentioned")
2299 }
2300 }
2301 } else {
2302 if (matches = txt.match(/^[(]([0-9]+)[)] <([@+]?)(.*?)> (.*)$/)) {
2303 sender = matches[1];
2304 name = matches[3];
2305 prefix = '<span onclick="u(' + sender + ');">(' + sender + ')</span> <span onclick="n(' + "'" + name + "'" + ');"><' + matches[2] + name + "></span> ";
2306 txt = matches[4];
2307 if (sender == 2) look = "chatprincess"
2308 } else if (matches = txt.match(/^[(]([0-9]+)[)] [*] <([@+]?)(.*?)> (.*)$/)) {
2309 sender = matches[1];
2310 name = matches[3];
2311 prefix = '<span onclick="u(' + sender + ');">(' + sender + ')</span> <span onclick="n(' + "'" + name + "'" + ');"> * <' + matches[2] + name + "></span> ";
2312 txt = matches[4];
2313 look = "chatemote";
2314 if (sender == 2) look = "chatprincess chatemote"
2315 } else if (txt.match(/^INFO:/)) look = "chatinfo"
2316 }
2317 }
2318 if (sender == uid) {
2319 if (settings.styleme) {
2320 if (look) look += " chatme";
2321 else look = "chatme"
2322 }
2323 } else if (txt.match(user_regexp)) {
2324 if (hilite && current_tab != "#chat") chattab.addClass("mentioned");
2325 if (ding && settings.alert && !dinged) $("#ding").get(0).play();
2326 if (hilite && settings.hilite) {
2327 if (look) look += " ding";
2328 else look = "ding"
2329 }
2330 }
2331 txt = '<div class="chatline' + (look ? " " + look : "") + '">' + moment(date).format("HH:mm:ss") + " " + prefix + (is_bet ? linkify_bet(txt) : linkify_text(txt)) + "</div>";
2332 if (is_bet && chatbets_showing) {
2333 chatbets.prepend(txt);
2334 chatbetcount++;
2335 if (chatbetcount >= chatbetmax) {
2336 log = chatbets.html();
2337 p = log.indexOf("<div");
2338 for (i = 0; i < chatbetmin; i++) {
2339 p = log.indexOf("<div", p + 1);
2340 if (p == -1) break
2341 }
2342 if (p >= 0) {
2343 chatbets.html(chatbets.html().substring(0, p));
2344 chatbetcount = chatbetmin
2345 }
2346 }
2347 } else {
2348 chatlog.append(txt);
2349 chatlogcount++;
2350 if (chatlogcount >= chatlogmax) {
2351 log = chatlog.html();
2352 p = log.lastIndexOf("<div");
2353 for (i = 1; i < chatlogmin; i++) {
2354 p = log.lastIndexOf("<div", p - 1);
2355 if (p == -1) break
2356 }
2357 if (p >= 0) {
2358 chatlog.html(chatlog.html().substring(p));
2359 chatlogcount = chatlogmin
2360 }
2361 }
2362 if (scroll_on_chat) scroll_to_bottom_of_chat()
2363 }
2364 }
2365
2366 function scroll_to_bottom_of_chat() {
2367 chatscroll.stop().animate({
2368 scrollTop: chatscroll[0].scrollHeight
2369 }, 333)
2370 }
2371
2372 function send_chat(chatinput) {
2373 var txt = chatinput.val(),
2374 matches;
2375 if (txt === "") scroll_to_bottom_of_chat();
2376 else if (txt.match(/^\/clear\b/i)) {
2377 chatlog.html("");
2378 chatinput.val("")
2379 } else {
2380 if (lastchat[1] != txt) {
2381 lastchat[0] = txt;
2382 lastchat.unshift("");
2383 lastchat.splice(lastchat_max + 1)
2384 }
2385 lastchat_index = 0;
2386 socket.emit("chat", csrf, txt);
2387 if (matches = txt.match(/^\s*([\/\\](?:(?:msg|pm)\s+\d+|dig|mods?|r|reply))\s+\S+/i)) chatinput.val(matches[1] + " ");
2388 else chatinput.val("")
2389 }
2390 return false
2391 }
2392
2393 function init_keybindings(chatinput) {
2394 var i, settings;
2395 chatinput.keypress(function(e) {
2396 if (e.which == 13) return send_chat(chatinput)
2397 });
2398 chatinput.keydown(function(e) {
2399 var code = e.keyCode;
2400 if (code == 38) {
2401 if (lastchat_index === 0) lastchat[0] = chatinput.val();
2402 if (++lastchat_index < lastchat.length) chatinput.val(lastchat[lastchat_index]);
2403 else lastchat_index = lastchat.length - 1;
2404 return false
2405 } else if (code == 40) {
2406 if (lastchat_index-- > 0) chatinput.val(lastchat[lastchat_index]);
2407 else lastchat_index = 0;
2408 return false
2409 }
2410 });
2411 var where = $("input").not(".typing").add(document);
2412 var nothing = "abcdefghijklmnopqrstuvwxyz,<[]=-;\\'`/";
2413 var len = nothing.length;
2414 var just_return = function() {
2415 return false
2416 };
2417 for (i = 0; i < len; i++) where.bind("keypress", nothing.substring(i, i + 1), just_return);
2418
2419 function bind_key(key, binding) {
2420 where.bind("keypress", key, function() {
2421 if (!global_bindings_enabled()) return;
2422 binding();
2423 return false
2424 })
2425 }
2426 var keybindings = {
2427 a: clicked_chance_min,
2428 s: clicked_chance_minus,
2429 d: clicked_chance_plus,
2430 f: clicked_chance_max,
2431 z: clicked_bet_min,
2432 x: clicked_bet_half,
2433 c: clicked_bet_double,
2434 b: clicked_bet_max,
2435 e: clicked_action_bet_random_chance,
2436 r: clicked_action_bet_random_hi_lo,
2437 t: clicked_action_bet_toggle,
2438 y: clicked_action_bet_same,
2439 h: clicked_action_bet_hi,
2440 l: clicked_action_bet_lo,
2441 i: clicked_action_deposit,
2442 o: clicked_action_withdraw,
2443 p: clicked_action_random
2444 };
2445 for (var key in keybindings) bind_key(key, keybindings[key]);
2446 settings = ["min_risk", "min_change", "chat_min_risk", "chat_min_change", "roll_delay", "max_double", "min_randchance", "max_randchance"];
2447 for (i in settings) bind_keys_for_float_input(settings[i]);
2448 settings = ["btcaddr"];
2449 for (i in settings) bind_keys_for_addr_input(settings[i]);
2450 settings = ["watch_player", "chat_watch_player", "emailaddr", "alert_words", "clamours"];
2451 for (i in settings) bind_keys_for_text_input(settings[i]);
2452 settings = ["autoinvest", "allbetsme", "mutechat", "randchancekey", "randomkey", "togglekey", "samekey", "shortcuts", "chatstake", "alarm", "alert", "hilite", "pmding", "styleme"];
2453 for (i in settings) bind_keys_for_bool_input(settings[i])
2454 }
2455 var setting_timeouts = {};
2456
2457 function bind_keys_for_float_input(setting) {
2458 var obj = $("#" + setting);
2459 obj.on("keyup paste", function(e) {
2460 setTimeout(function() {
2461 var value = obj.val();
2462 value = value.replace(/[^0-9.]/g, "");
2463 clearTimeout(setting_timeouts[setting]);
2464 setting_timeouts[setting] = setTimeout(function() {
2465 socket.emit("setting", csrf, "float", setting, value)
2466 }, 3 * 1e3);
2467 settings[setting] = parseFloat(value)
2468 }, 10)
2469 })
2470 }
2471
2472 function bind_keys_for_int_input(setting) {
2473 var obj = $("#" + setting);
2474 obj.on("keyup paste", function(e) {
2475 setTimeout(function() {
2476 var value = obj.val();
2477 value = value.replace(/[^0-9]/g, "");
2478 clearTimeout(setting_timeouts[setting]);
2479 setting_timeouts[setting] = setTimeout(function() {
2480 socket.emit("setting", csrf, "int", setting, value)
2481 }, 1 * 1e3);
2482 settings[setting] = parseInt(value)
2483 }, 10)
2484 })
2485 }
2486
2487 function bind_keys_for_addr_input(setting) {
2488 var obj = $("#" + setting);
2489 obj.on("keyup paste", function(e) {
2490 setTimeout(function() {
2491 var value = obj.val();
2492 value = value.replace(/[^1-9A-HJ-NP-Za-km-z]/g, "");
2493 clearTimeout(setting_timeouts[setting]);
2494 setting_timeouts[setting] = setTimeout(function() {
2495 socket.emit("setting", csrf, "addr", setting, value)
2496 }, 1 * 1e3);
2497 settings[setting] = value
2498 }, 10)
2499 })
2500 }
2501
2502 function bind_keys_for_text_input(setting) {
2503 var obj = $("#" + setting);
2504 obj.on("keyup paste", function(e) {
2505 setTimeout(function() {
2506 var value = obj.val();
2507 clearTimeout(setting_timeouts[setting]);
2508 setting_timeouts[setting] = setTimeout(function() {
2509 socket.emit("setting", csrf, "text", setting, value);
2510 if (setting == "alert_words") {
2511 default_alert_words = false;
2512 build_user_regexp(value)
2513 }
2514 }, 1 * 1e3);
2515 settings[setting] = value
2516 }, 10)
2517 })
2518 }
2519
2520 function bind_keys_for_bool_input(setting) {
2521 var obj = $("#" + setting);
2522 obj.on("click", function(e) {
2523 var value = obj.prop("checked");
2524 settings[setting] = value;
2525 socket.emit("setting", csrf, "bool", setting, value ? "1" : "0")
2526 })
2527 }
2528
2529 function format_percentage(p) {
2530 p = p.toFixed(0);
2531 p = "00000" + p;
2532 p = p.substring(p.length - 6);
2533 var p1 = p.substring(0, 2);
2534 var p2 = p.substring(2, 4);
2535 var p3 = p.substring(4, 6);
2536 return '<span class="s1">' + p1 + '.</span><span class="s2">' + p2 + '</span><span class="s3">' + p3 + "</span>"
2537 }
2538
2539 function invisible(txt) {
2540 return '<div class="skinny"> ' + txt + ": </div>"
2541 }
2542
2543 function add_result(r, me, all) {
2544 var result = "";
2545 var profit = r.this_profit;
2546 if (r.win && profit.substring(0, 1) != "+") profit = "+" + profit;
2547 else if (!r.win && profit.substring(0, 1) != "-") profit = "-" + profit;
2548 var other = r.high ? r.lucky < r.chance * 1e4 : r.lucky >= (100 - r.chance) * 1e4;
2549 var win = r.win ? other ? "win gold" : "win" : other ? "lose" : "lose imp";
2550 var mine = me ? "me " : "";
2551 var tmp = "tmp" + r.betid;
2552 var compare = r.high ? ">" : "<";
2553 var target = r.high ? (100 - r.chance) * 1e4 - 1 : r.chance * 1e4;
2554 result += '<div class="result ' + win + " " + mine + '">';
2555 result += invisible("user");
2556 result += '<div class="who">';
2557 result += quote_html(r.name);
2558 result += "</div>";
2559 result += invisible("date");
2560 result += '<div class="when">';
2561 result += moment(r.date.toString(), "X").format("YYYY-MM-DD HH:mm:ss");
2562 result += "</div>";
2563 result += invisible("betid");
2564 result += '<div class="betid">';
2565 result += '<a class="' + tmp + '" href="/roll/' + r.betid + '">' + r.betid + "</a>";
2566 result += "</div>";
2567 result += invisible("lucky");
2568 result += '<div class="lucky">';
2569 result += format_percentage(r.lucky);
2570 result += "</div>";
2571 result += invisible("target");
2572 result += '<div class="chance">';
2573 result += compare + format_percentage(target);
2574 result += "</div>";
2575 result += invisible("bet");
2576 result += '<div class="bet">';
2577 result += add_zeroes(r.bet);
2578 result += "</div>";
2579 result += invisible("payout");
2580 result += '<div class="payout">';
2581 result += r.payout + "x";
2582 result += "</div>";
2583 result += invisible("profit");
2584 result += '<div class="profit"><span class="s1">';
2585 result += add_zeroes(profit);
2586 result += "</span></div></div>";
2587 if (me) add_result_row(".results#me", result, r.betid, tmp);
2588 if (all !== false && (!me || settings.allbetsme)) add_result_row(".results#all", result, r.betid, tmp);
2589 $("." + tmp).removeClass(tmp)
2590 }
2591
2592 function add_result_to_chat(r) {
2593 var matches = r.name.match(/^(.*) \(([0-9]+)\)$/);
2594 var nick = matches[1];
2595 var uid = matches[2];
2596 var txt = "*** (" + uid + ") <" + nick + "> [#" + r.betid + "] bet " + r.bet + " " + currency + " at " + r.chance + "% and " + (r.win ? "won " + r.this_profit.substring(1) + " " + currency : "lost") + " ***";
2597 add_chat(Date(parseInt(r.date) * 1e3), txt, r.win ? "chatwin" : "chatlose", true)
2598 }
2599
2600 function add_zeroes(num) {
2601 if (typeof num == "number") num = num.toString();
2602 var num2 = "";
2603 var matches = num.match(/([+-]?[0-9]*)[.]([0-9]*)/);
2604 if (matches) num = matches[1] + "." + matches[2];
2605 else {
2606 num2 = ".";
2607 matches = ["", num, ""]
2608 }
2609 if (matches[2].length != 8) num2 += "00000000".substring(matches[2].length);
2610 return num + (num2 ? '<span class="zero">' + num2 + "</span>" : "")
2611 }
2612
2613 function add_result_row(selector, result, betid, tmp) {
2614 $(selector).prepend(result);
2615 $("." + tmp).off("click").click(function(e) {
2616 socket.emit("roll", csrf, betid);
2617 return false
2618 });
2619 if ($(selector + " div.result").length > results_to_keep) $(selector + " div.result:last-child").remove()
2620 }
2621
2622 function get_float_string(prefix, name, obj) {
2623 var val = obj.val();
2624 var fixed = 8;
2625 if (name == "chance") fixed = 4;
2626 var val2 = chop_extra_decimals(obj.val(), fixed);
2627 if (val != val2) {
2628 val = val2;
2629 obj.val(val)
2630 }
2631 if (!re.test(val) || name != "bet" && name != "balance" && name != "profit" && name != "payout" && name != "chance" && re3.test(val)) {
2632 if (re2.test(val) && name != "bet") set_invalid(obj, false);
2633 else set_invalid(obj, true);
2634 return false
2635 }
2636 if (re4.test(val)) {
2637 msg("extra 0 at start of '" + name + "' - did you make a mistake?");
2638 set_invalid(obj, true);
2639 return false
2640 }
2641 var ok = true;
2642 switch (name) {
2643 case "chance":
2644 if (val < 1e-4) {
2645 var min_chance = 1e-4;
2646 msg('minimum chance is <button id="doit">' + min_chance + "%</button> (one in a million chance)");
2647 $("#doit").click(function(e) {
2648 set_chance(min_chance);
2649 clear_msg();
2650 changed_chance(prefix)
2651 });
2652 ok = false
2653 } else {
2654 if (val > max_chance) {
2655 if (val > max_chance + 1e-6) {
2656 msg('maximum chance is <button id="doit">' + max_chance + "%</button>");
2657 $("#doit").click(function(e) {
2658 set_chance(max_chance);
2659 clear_msg();
2660 changed_chance(prefix)
2661 });
2662 ok = false
2663 } else {
2664 set_chance(max_chance);
2665 clear_msg()
2666 }
2667 }
2668 }
2669 break;
2670 case "payout":
2671 if (val < 1.00010052 || val > 99e4) ok = false;
2672 break;
2673 case "bet":
2674 var bal = parseFloat(find_object(prefix, "balance").val());
2675 if (val > bal) {
2676 $("#doit").click(function(e) {
2677 obj.val(bal);
2678 clear_msg();
2679 changed_bet(prefix)
2680 });
2681 ok = false
2682 }
2683 break;
2684 case "profit":
2685 if (val < 1e-8 && parseFloat($("#pct_bet").val()) !== 0) {
2686 msg('why bet if you can\'t win? set profit to at least <button id="doit">0.00000001 ' + currency + "</button>");
2687 $("#doit").click(function(e) {
2688 obj.val("0.00000001");
2689 clear_msg();
2690 changed_profit(prefix)
2691 });
2692 ok = false
2693 } else if (!check_profit(val)) ok = false;
2694 break
2695 }
2696 if (!ok) {
2697 set_invalid(obj, true);
2698 return val
2699 }
2700 set_invalid(obj, false);
2701 return val
2702 }
2703
2704 function fixed(val, fix) {
2705 if (typeof val == "number") {
2706 if (fix === undefined) fix = 8;
2707 val = val.toFixed(fix)
2708 }
2709 if (val == "-0.00000000") val = "0.00000000";
2710 return commaify(val)
2711 }
2712
2713 function tidy(val) {
2714 var fixed = 8;
2715 if (typeof val == "number") val = val.toFixed(fixed);
2716 val = val.replace(/([.].*?)0+$/, "$1");
2717 val = val.replace(/[.]$/, "");
2718 return val
2719 }
2720
2721 function chop_extra_decimals(val, fixed) {
2722 switch (fixed) {
2723 case 4:
2724 val = val.replace(/([.][0-9]{4}).*$/, "$1");
2725 break;
2726 case 8:
2727 val = val.replace(/([.][0-9]{8}).*$/, "$1");
2728 break
2729 }
2730 return val
2731 }
2732
2733 function changed_bet(prefix) {
2734 var bet_o = find_object(prefix, "bet");
2735 var bet = get_float_string(prefix, "bet", bet_o);
2736 if (!bet) {
2737 find_object(prefix, "profit").val("");
2738 return
2739 }
2740 var bet2 = chop_extra_decimals(bet, 8);
2741 if (bet != bet2) {
2742 bet_o.val(bet2);
2743 bet = bet2
2744 }
2745 bet = parseFloat(bet);
2746 var payout = get_float_string(prefix, "payout", find_object(prefix, "payout"));
2747 if (!payout) {
2748 find_object(prefix, "profit").val("");
2749 return
2750 }
2751 var ret = round_down(bet * payout);
2752 var profit = ret - bet;
2753 var profit_o = find_object(prefix, "profit");
2754 profit_o.val(tidy(profit));
2755 check_profit(profit)
2756 }
2757
2758 function check_profit(profit) {
2759 var profit_o = find_object("pct", "profit");
2760 if (profit > max_profit + 1e-9) {
2761 set_invalid(profit_o, true);
2762 if (max_profit === 0) msg('The site\'s bankroll is empty. <a href="http://just-dice.blogspot.ca/2014/06/betting-and-depositing-disabled-on-jd.html" target="_blank">Read more</a>.');
2763 else {
2764 msg('The max profit per bet is currently <button id="doit">' + max_profit.toFixed(2) + " " + currency + "</button> (this depends on the size of the site's bankroll)");
2765 $("#doit").click(function(e) {
2766 profit_o.val(max_profit);
2767 clear_msg();
2768 changed_profit("pct")
2769 })
2770 }
2771 return false
2772 }
2773 set_invalid(profit_o, false);
2774 return true
2775 }
2776
2777 function changed_profit(prefix) {
2778 var profit_o = find_object(prefix, "profit");
2779 var profit = get_float_string(prefix, "profit", profit_o);
2780 if (!profit) {
2781 return
2782 }
2783 var profit2 = chop_extra_decimals(profit, 8);
2784 if (profit != profit2) {
2785 profit_o.val(profit2);
2786 profit = profit2
2787 }
2788 profit = parseFloat(profit);
2789 var payout = get_float_string(prefix, "payout", find_object(prefix, "payout"));
2790 if (!payout) return;
2791 var bet = Math.floor(profit / (payout - 1) * 1e8 + 1e-6) / 1e8;
2792 if (round_down(bet * (payout - 1)) === 0) bet += 1e-8;
2793 bet = tidy(bet);
2794 var bet_o = find_object(prefix, "bet");
2795 if (bet_o.val() != bet && tidy(round_down(bet_o.val() * payout) - bet_o.val()) != profit_o.val()) bet_o.val(bet)
2796 }
2797
2798 function typed_amount(prefix, this_name, change_name) {
2799 var this_obj = find_object(prefix, this_name);
2800 var change_obj = find_object(prefix, change_name);
2801 var this_text = get_float_string(prefix, this_name, this_obj);
2802 if (!this_text) {
2803 changed_bet(prefix);
2804 return
2805 }
2806 var this_amount = parseFloat(this_text);
2807 if (this_amount < 0 || !isFinite(this_amount) || isNaN(this_amount)) {
2808 get_float_string(prefix, change_name, change_obj);
2809 changed_bet(prefix);
2810 return
2811 }
2812 if (this_amount === 0) {
2813 change_obj.val("0");
2814 get_float_string(prefix, change_name, change_obj);
2815 changed_bet(prefix);
2816 return
2817 }
2818 var val, fixed;
2819 if (this_name == "payout") {
2820 val = (100 - edge) / this_amount;
2821 if (val < 1e-4) val = 0;
2822 fixed = 4
2823 } else {
2824 val = (100 - edge) / this_amount;
2825 fixed = 8
2826 }
2827 val = val.toFixed(fixed);
2828 val = val.replace(/([.].*?)0+$/, "$1");
2829 val = val.replace(/[.]$/, "");
2830 if (change_obj.val() != val) change_obj.val(val);
2831 get_float_string(prefix, change_name, change_obj);
2832 if (this_name == "payout") set_warning(this_obj, ((100 - edge) / val).toFixed(8).replace(/([.].*?)0+$/, "$1").replace(/[.]$/, "") != this_amount.toFixed(8).replace(/([.].*?)0+$/, "$1").replace(/[.]$/, ""));
2833 else set_warning(change_obj, false);
2834 changed_bet(prefix)
2835 }
2836
2837 function changed_chance(prefix) {
2838 typed_amount(prefix, "chance", "payout");
2839 return false
2840 }
2841
2842 function changed_payout(prefix) {
2843 typed_amount(prefix, "payout", "chance")
2844 }
2845
2846 function handle_events_for_input(prefix, field, fun, fun2) {
2847 var input = find_object(prefix, field);
2848 input.on("blur", function(e) {
2849 if (fun2) fun2(prefix)
2850 });
2851 input.on("cut paste", function(e) {
2852 setTimeout(function() {
2853 fun(prefix)
2854 }, 10)
2855 });
2856 input.keyup(function(e) {
2857 fun(prefix)
2858 })
2859 }
2860
2861 function handle_events(prefix) {
2862 handle_events_for_input(prefix, "chance", function(p) {
2863 clear_msg();
2864 changed_chance(p);
2865 maybe_update_targets();
2866 fixup()
2867 });
2868 handle_events_for_input(prefix, "payout", function(p) {
2869 clear_msg();
2870 changed_payout(p);
2871 maybe_update_targets();
2872 fixup()
2873 }, function(p) {
2874 changed_chance(p)
2875 });
2876 handle_events_for_input(prefix, "bet", function(p) {
2877 clear_msg();
2878 changed_bet(p);
2879 fixup()
2880 });
2881 handle_events_for_input(prefix, "profit", function(p) {
2882 clear_msg();
2883 changed_profit(p);
2884 fixup()
2885 });
2886 handle_events_for_input(chatinput, false, function() {
2887 var val = chatinput.val();
2888 if (chatinput_class === 0 && !val.match(/^\s*[\/\\]/)) return;
2889 if (val.match(/^\s*[\/\\]me\b/i)) {
2890 if (chatinput_class != 4) {
2891 chatinput_class = 4;
2892 chatinput.addClass("chatemote").removeClass("chatpm chatmod chatinfo")
2893 }
2894 } else if (val.match(/^\s*[\/\\](?:pm|msg|r|reply)\b/i)) {
2895 if (chatinput_class != 3) {
2896 chatinput_class = 3;
2897 chatinput.addClass("chatpm").removeClass("chatemote chatmod chatinfo")
2898 }
2899 } else if (val.match(/^\s*[\/\\]mods?\b/i)) {
2900 if (chatinput_class != 2) {
2901 chatinput_class = 2;
2902 chatinput.addClass("chatmod").removeClass("chatemote chatpm chatinfo")
2903 }
2904 } else if (val.match(/^\s*[\/\\]tip\b/i)) {
2905 if (chatinput_class != 1) {
2906 chatinput_class = 1;
2907 chatinput.addClass("chatinfo").removeClass("chatemote chatpm chatmod")
2908 }
2909 } else {
2910 if (chatinput_class !== 0) {
2911 chatinput_class = 0;
2912 chatinput.removeClass("chatemote chatpm chatmod chatinfo")
2913 }
2914 }
2915 })
2916 }
2917 var nargs = /\{[0-9a-zA-Z_]+\}/g;
2918
2919 function template_compile(string) {
2920 var replacements = string.match(nargs),
2921 interleave = string.split(nargs),
2922 replace = [],
2923 prev = [""];
2924 for (var i in interleave) {
2925 var current = interleave[i],
2926 replacement = replacements[i];
2927 if (replacement) replacement = replacement.substring(1, replacement.length - 1);
2928 if (current.charAt(current.length - 1) === "{" && (interleave[i + 1] || "").charAt(0) === "}") replace.push(current + replacement);
2929 else {
2930 replace.push(current);
2931 if (replacement) replace.push({
2932 name: replacement
2933 })
2934 }
2935 }
2936 for (i in replace) {
2937 var curr = replace[i];
2938 if (String(curr) === curr) {
2939 var top = prev[prev.length - 1];
2940 if (String(top) === top) prev[prev.length - 1] = top + curr;
2941 else prev.push(curr)
2942 } else prev.push(curr)
2943 }
2944 return new Function(template_run('var args=arguments.length===1&&typeof arguments[0]==="object"?arguments[0]:arguments;' + "if(!args)args={};return{0}", prev.map(function(e) {
2945 return typeof e === "string" ? template_run('"{0}"', template_escape(e)) : template_run('args["{0}"]', template_escape(e.name))
2946 }).join("+")))
2947 }
2948
2949 function template_run(string) {
2950 var args = arguments.length === 2 && typeof arguments[1] === "object" ? arguments[1] : Array.prototype.slice.call(arguments, 1);
2951 if (!args || !args.hasOwnProperty) args = {};
2952 return string.replace(/\{([0-9a-zA-Z_]+)\}/g, function replaceArg(match, i, index) {
2953 var result = args.hasOwnProperty(i) ? args[i] : null;
2954 return result === null || result === undefined ? "" : result
2955 })
2956 }
2957
2958 function template_escape(string) {
2959 return string.replace(/["'\\\n\r]/g, function(character) {
2960 switch (character) {
2961 case '"':
2962 case "'":
2963 case "\\":
2964 return "\\" + character;
2965 case "\n":
2966 return "\\n";
2967 case "\r":
2968 return "\\r";
2969 default:
2970 return ""
2971 }
2972 })
2973 }
2974 }, {
2975 "./colors": 1,
2976 "./jqColorPicker": 3,
2977 "./jquery.animate-colors": 4,
2978 "./jquery.fancybox": 5,
2979 "./jquery.hotkeys": 6,
2980 "./moment": 7,
2981 "./sha256": 8
2982 }],
2983 3: [function(require, module, exports) {
2984 module.exports = function($, Colors, undefined) {
2985 "use strict";
2986 var $document = $(document),
2987 _instance, _colorPicker, _color, _options, _selector = "",
2988 _$trigger, _$UI, _$xy_slider, _$xy_cursor, _$z_cursor, _$alpha, _$alpha_cursor, _pointermove = "touchmove.a mousemove.a pointermove.a",
2989 _pointerdown = "touchstart.a mousedown.a pointerdown.a",
2990 _pointerup = "touchend.a mouseup.a pointerup.a",
2991 _GPU = false,
2992 _animate = window.requestAnimationFrame || window.webkitRequestAnimationFrame || function(cb) {
2993 cb()
2994 },
2995 _html = '<div class="cp-color-picker"><div class="cp-z-slider"><div c' + 'lass="cp-z-cursor"></div></div><div class="cp-xy-slider"><div cl' + 'ass="cp-white"></div><div class="cp-xy-cursor"></div></div><div ' + 'class="cp-alpha"><div class="cp-alpha-cursor"></div></div></div>',
2996 _css = ".cp-color-picker{position:absolute;overflow:hidden;padding:6p" + "x 6px 0;background-color:#444;color:#bbb;font-family:Arial,Helve" + "tica,sans-serif;font-size:12px;font-weight:400;cursor:default;bo" + "rder-radius:5px}.cp-color-picker>div{position:relative;overflow:" + "hidden}.cp-xy-slider{float:left;height:128px;width:128px;margin-" + "bottom:6px;background:linear-gradient(to right,#FFF,rgba(255,255" + ",255,0))}.cp-white{height:100%;width:100%;background:linear-grad" + "ient(rgba(0,0,0,0),#000)}.cp-xy-cursor{position:absolute;top:0;w" + "idth:10px;height:10px;margin:-5px;border:1px solid #fff;border-r" + "adius:100%;box-sizing:border-box}.cp-z-slider{float:right;margin" + "-left:6px;height:128px;width:20px;background:linear-gradient(red" + " 0,#f0f 17%,#00f 33%,#0ff 50%,#0f0 67%,#ff0 83%,red 100%)}.cp-z-" + "cursor{position:absolute;margin-top:-4px;width:100%;border:4px s" + "olid #fff;border-color:transparent #fff;box-sizing:border-box}.c" + "p-alpha{clear:both;width:100%;height:16px;margin:6px 0;backgroun" + "d:linear-gradient(to right,#444,rgba(0,0,0,0))}.cp-alpha-cursor{" + "position:absolute;margin-left:-4px;height:100%;border:4px solid " + "#fff;border-color:#fff transparent;box-sizing:border-box}",
2997 ColorPicker = function(options) {
2998 _color = this.color = new Colors(options);
2999 _options = _color.options
3000 };
3001 ColorPicker.prototype = {
3002 render: preRender,
3003 toggle: toggle
3004 };
3005
3006 function extractValue(elm) {
3007 return elm.value || elm.getAttribute("value") || $(elm).css("background-color") || "#fff"
3008 }
3009
3010 function resolveEventType(event) {
3011 event = event.originalEvent && event.originalEvent.touches ? event.originalEvent.touches[0] : event;
3012 return event.originalEvent ? event.originalEvent : event
3013 }
3014
3015 function findElement($elm) {
3016 return $($elm.find(_options.doRender)[0] || $elm[0])
3017 }
3018
3019 function toggle(event) {
3020 var $this = $(this),
3021 position = $this.offset(),
3022 $window = $(window),
3023 gap = _options.gap;
3024 if (event) {
3025 _$trigger = findElement($this);
3026 _colorPicker.$trigger = $this;
3027 (_$UI || build()).css({
3028 left: (_$UI[0]._left = position.left) - ((_$UI[0]._left = _$UI[0]._left + _$UI[0]._width - ($window.scrollLeft() + $window.width())) + gap > 0 ? _$UI[0]._left + gap : 0),
3029 top: (_$UI[0]._top = position.top + $this.outerHeight()) - ((_$UI[0]._top = _$UI[0]._top + _$UI[0]._height - ($window.scrollTop() + $window.height())) + gap > 0 ? _$UI[0]._top + gap : 0)
3030 }).show(_options.animationSpeed, function() {
3031 if (event === true) {
3032 return
3033 }
3034 _$alpha._width = _$alpha.width();
3035 _$xy_slider._width = _$xy_slider.width();
3036 _$xy_slider._height = _$xy_slider.height();
3037 _color.setColor(extractValue(_$trigger[0]));
3038 preRender(true)
3039 })
3040 } else {
3041 $(_$UI).hide(_options.animationSpeed, function() {
3042 _$trigger.blur();
3043 _colorPicker.$trigger = null;
3044 preRender(false)
3045 })
3046 }
3047 }
3048
3049 function build() {
3050 $("head").append('<style type="text/css">' + (_options.css || _css) + (_options.cssAddon || "") + "</style>");
3051 return _colorPicker.$UI = _$UI = $(_html).css({
3052 margin: _options.margin
3053 }).appendTo("body").show(0, function() {
3054 var $this = $(this);
3055 _GPU = _options.GPU && $this.css("perspective") !== undefined;
3056 _$xy_slider = $(".cp-xy-slider", this);
3057 _$xy_cursor = $(".cp-xy-cursor", this);
3058 _$z_cursor = $(".cp-z-cursor", this);
3059 _$alpha = $(".cp-alpha", this).toggle(!!_options.opacity);
3060 _$alpha_cursor = $(".cp-alpha-cursor", this);
3061 _options.buildCallback.call(_colorPicker, $this);
3062 $this.prepend("<div>").children().eq(0).css("width", $this.children().eq(0).width());
3063 this._width = this.offsetWidth;
3064 this._height = this.offsetHeight
3065 }).hide().on(_pointerdown, ".cp-xy-slider,.cp-z-slider,.cp-alpha", pointerdown)
3066 }
3067
3068 function pointerdown(e) {
3069 var action = this.className.replace(/cp-(.*?)(?:\s*|$)/, "$1").replace("-", "_");
3070 e.preventDefault && e.preventDefault();
3071 e.returnValue = false;
3072 _$trigger._offset = $(this).offset();
3073 (action = action === "xy_slider" ? xy_slider : action === "z_slider" ? z_slider : alpha)(e);
3074 $document.on(_pointerup, pointerup).on(_pointermove, action)
3075 }
3076
3077 function pointerup(e) {
3078 $document.off(".a")
3079 }
3080
3081 function xy_slider(event) {
3082 var e = resolveEventType(event),
3083 x = e.pageX - _$trigger._offset.left,
3084 y = e.pageY - _$trigger._offset.top;
3085 _color.setColor({
3086 s: x / _$xy_slider._width * 100,
3087 v: 100 - y / _$xy_slider._height * 100
3088 }, "hsv");
3089 preRender()
3090 }
3091
3092 function z_slider(event) {
3093 var z = resolveEventType(event).pageY - _$trigger._offset.top,
3094 hsv = _color.colors.hsv;
3095 _color.setColor({
3096 h: 360 - z / _$xy_slider._height * 360
3097 }, "hsv");
3098 preRender()
3099 }
3100
3101 function alpha(event) {
3102 var x = resolveEventType(event).pageX - _$trigger._offset.left,
3103 alpha = x / _$alpha._width;
3104 _color.setColor({}, "rgb", alpha > 1 ? 1 : alpha < 0 ? 0 : alpha);
3105 preRender()
3106 }
3107
3108 function preRender(toggled) {
3109 var colors = _color.colors,
3110 hueRGB = colors.hueRGB,
3111 RGB = colors.RND.rgb,
3112 HSL = colors.RND.hsl,
3113 dark = "#222",
3114 light = "#ddd",
3115 colorMode = _$trigger.data("colorMode"),
3116 isAlpha = colors.alpha !== 1,
3117 alpha = Math.round(colors.alpha * 100) / 100,
3118 RGBInnerText = RGB.r + ", " + RGB.g + ", " + RGB.b,
3119 text = colorMode === "HEX" && !isAlpha ? "#" + colors.HEX : colorMode === "rgb" || colorMode === "HEX" && isAlpha ? !isAlpha ? "rgb(" + RGBInnerText + ")" : "rgba(" + RGBInnerText + ", " + alpha + ")" : "hsl" + (isAlpha ? "a(" : "(") + HSL.h + ", " + HSL.s + "%, " + HSL.l + "%" + (isAlpha ? ", " + alpha : "") + ")",
3120 HUEContrast = colors.HUELuminance > .22 ? dark : light,
3121 alphaContrast = colors.rgbaMixBlack.luminance > .22 ? dark : light,
3122 h = (1 - colors.hsv.h) * _$xy_slider._height,
3123 s = colors.hsv.s * _$xy_slider._width,
3124 v = (1 - colors.hsv.v) * _$xy_slider._height,
3125 a = alpha * _$alpha._width,
3126 translate3d = _GPU ? "translate3d" : "",
3127 triggerValue = _$trigger.val(),
3128 hasNoValue = _$trigger[0].hasAttribute("value") && triggerValue === "" && toggled !== undefined;
3129 _$xy_slider._css = {
3130 backgroundColor: "rgb(" + hueRGB.r + "," + hueRGB.g + "," + hueRGB.b + ")"
3131 };
3132 _$xy_cursor._css = {
3133 transform: translate3d + "(" + s + "px, " + v + "px, 0)",
3134 left: !_GPU ? s : "",
3135 top: !_GPU ? v : "",
3136 borderColor: colors.RGBLuminance > .22 ? dark : light
3137 };
3138 _$z_cursor._css = {
3139 transform: translate3d + "(0, " + h + "px, 0)",
3140 top: !_GPU ? h : "",
3141 borderColor: "transparent " + HUEContrast
3142 };
3143 _$alpha._css = {
3144 backgroundColor: "rgb(" + RGBInnerText + ")"
3145 };
3146 _$alpha_cursor._css = {
3147 transform: translate3d + "(" + a + "px, 0, 0)",
3148 left: !_GPU ? a : "",
3149 borderColor: alphaContrast + " transparent"
3150 };
3151 _$trigger._css = {
3152 backgroundColor: hasNoValue ? "" : text,
3153 color: hasNoValue ? "" : colors.rgbaMixBGMixCustom.luminance > .22 ? dark : light
3154 };
3155 _$trigger.text = hasNoValue ? "" : triggerValue !== text ? text : "";
3156 toggled !== undefined ? render(toggled) : _animate(render)
3157 }
3158
3159 function render(toggled) {
3160 _$xy_slider.css(_$xy_slider._css);
3161 _$xy_cursor.css(_$xy_cursor._css);
3162 _$z_cursor.css(_$z_cursor._css);
3163 _$alpha.css(_$alpha._css);
3164 _$alpha_cursor.css(_$alpha_cursor._css);
3165 _options.doRender && _$trigger.css(_$trigger._css);
3166 _$trigger.text && _$trigger.val(_$trigger.text);
3167 _options.renderCallback.call(_colorPicker, _$trigger, typeof toggled === "boolean" ? toggled : undefined)
3168 }
3169 $.fn.colorPicker = function(options) {
3170 var noop = function() {};
3171 options = $.extend({
3172 animationSpeed: 150,
3173 GPU: true,
3174 doRender: true,
3175 customBG: "#FFF",
3176 opacity: true,
3177 renderCallback: noop,
3178 buildCallback: noop,
3179 body: document.body,
3180 scrollResize: true,
3181 gap: 4
3182 }, options);
3183 !_colorPicker && options.scrollResize && $(window).on("resize.a scroll.a", function() {
3184 if (_colorPicker.$trigger) {
3185 _colorPicker.toggle.call(_colorPicker.$trigger[0], true)
3186 }
3187 });
3188 _instance = _instance ? _instance.add(this) : this;
3189 _instance.colorPicker = _colorPicker || (_colorPicker = new ColorPicker(options));
3190 _selector += (_selector ? ", " : "") + this.selector;
3191 $(options.body).off(".a").on(_pointerdown, function(e) {
3192 var $target = $(e.target);
3193 if ($.inArray($target.closest(_selector)[0], _instance) === -1 && !$target.closest(_$UI).length) {
3194 toggle()
3195 }
3196 }).on("focus.a click.a", _selector, toggle).on("change.a", _selector, function() {
3197 _color.setColor(this.value || "#FFF");
3198 _instance.colorPicker.render(true)
3199 });
3200 return this.each(function() {
3201 var value = extractValue(this),
3202 mode = value.split("("),
3203 $elm = findElement($(this));
3204 $elm.data("colorMode", mode[1] ? mode[0].substr(0, 3) : "HEX").attr("readonly", _options.preventFocus);
3205 options.doRender && $elm.css({
3206 "background-color": value,
3207 color: function() {
3208 return _color.setColor(value).rgbaMixBGMixCustom.luminance > .22 ? "#222" : "#ddd"
3209 }
3210 })
3211 })
3212 };
3213 $.fn.colorPicker.destroy = function() {
3214 $(_colorPicker.color.options.body).off(".a");
3215 _colorPicker.toggle(false);
3216 _instance = null;
3217 _selector = ""
3218 }
3219 }
3220 }, {}],
3221 4: [function(require, module, exports) {
3222 module.exports = function($) {
3223 function isRGBACapable() {
3224 var $script = $("script:first"),
3225 color = $script.css("color"),
3226 result = false;
3227 if (/^rgba/.test(color)) {
3228 result = true
3229 } else {
3230 try {
3231 result = color != $script.css("color", "rgba(0, 0, 0, 0.5)").css("color");
3232 $script.css("color", color)
3233 } catch (e) {}
3234 }
3235 return result
3236 }
3237 $.extend(true, $, {
3238 support: {
3239 rgba: isRGBACapable()
3240 }
3241 });
3242 var properties = ["color", "backgroundColor", "borderBottomColor", "borderLeftColor", "borderRightColor", "borderTopColor", "outlineColor"];
3243 $.each(properties, function(i, property) {
3244 $.Tween.propHooks[property] = {
3245 get: function(tween) {
3246 return $(tween.elem).css(property)
3247 },
3248 set: function(tween) {
3249 var style = tween.elem.style;
3250 var p_begin = parseColor($(tween.elem).css(property));
3251 var p_end = parseColor(tween.end);
3252 tween.run = function(progress) {
3253 style[property] = calculateColor(p_begin, p_end, progress)
3254 }
3255 }
3256 }
3257 });
3258 $.Tween.propHooks.borderColor = {
3259 set: function(tween) {
3260 var style = tween.elem.style;
3261 var p_begin = [];
3262 var borders = properties.slice(2, 6);
3263 $.each(borders, function(i, property) {
3264 p_begin[property] = parseColor($(tween.elem).css(property))
3265 });
3266 var p_end = parseColor(tween.end);
3267 tween.run = function(progress) {
3268 $.each(borders, function(i, property) {
3269 style[property] = calculateColor(p_begin[property], p_end, progress)
3270 })
3271 }
3272 }
3273 };
3274
3275 function calculateColor(begin, end, pos) {
3276 var color = "rgb" + ($.support["rgba"] ? "a" : "") + "(" + parseInt(begin[0] + pos * (end[0] - begin[0]), 10) + "," + parseInt(begin[1] + pos * (end[1] - begin[1]), 10) + "," + parseInt(begin[2] + pos * (end[2] - begin[2]), 10);
3277 if ($.support["rgba"]) {
3278 color += "," + (begin && end ? parseFloat(begin[3] + pos * (end[3] - begin[3])) : 1)
3279 }
3280 color += ")";
3281 return color
3282 }
3283
3284 function parseColor(color) {
3285 var match, triplet;
3286 if (match = /#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})/.exec(color)) {
3287 triplet = [parseInt(match[1], 16), parseInt(match[2], 16), parseInt(match[3], 16), 1]
3288 } else if (match = /#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/.exec(color)) {
3289 triplet = [parseInt(match[1], 16) * 17, parseInt(match[2], 16) * 17, parseInt(match[3], 16) * 17, 1]
3290 } else if (match = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) {
3291 triplet = [parseInt(match[1]), parseInt(match[2]), parseInt(match[3]), 1]
3292 } else if (match = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9\.]*)\s*\)/.exec(color)) {
3293 triplet = [parseInt(match[1], 10), parseInt(match[2], 10), parseInt(match[3], 10), parseFloat(match[4])]
3294 }
3295 return triplet
3296 }
3297 }
3298 }, {}],
3299 5: [function(require, module, exports) {
3300 module.exports = function(window, document, $, undefined) {
3301 "use strict";
3302 var W = $(window),
3303 D = $(document),
3304 F = $.fancybox = function() {
3305 F.open.apply(this, arguments)
3306 },
3307 IE = navigator.userAgent.match(/msie/),
3308 didUpdate = null,
3309 isTouch = document.createTouch !== undefined,
3310 isQuery = function(obj) {
3311 return obj && obj.hasOwnProperty && obj instanceof $
3312 },
3313 isString = function(str) {
3314 return str && $.type(str) === "string"
3315 },
3316 isPercentage = function(str) {
3317 return isString(str) && str.indexOf("%") > 0
3318 },
3319 isScrollable = function(el) {
3320 return el && !(el.style.overflow && el.style.overflow === "hidden") && (el.clientWidth && el.scrollWidth > el.clientWidth || el.clientHeight && el.scrollHeight > el.clientHeight)
3321 },
3322 getScalar = function(orig, dim) {
3323 var value = parseInt(orig, 10) || 0;
3324 if (dim && isPercentage(orig)) {
3325 value = F.getViewport()[dim] / 100 * value
3326 }
3327 return Math.ceil(value)
3328 },
3329 getValue = function(value, dim) {
3330 return getScalar(value, dim) + "px"
3331 };
3332 $.extend(F, {
3333 version: "2.1.4",
3334 defaults: {
3335 padding: 15,
3336 margin: 20,
3337 width: 800,
3338 height: 600,
3339 minWidth: 100,
3340 minHeight: 100,
3341 maxWidth: 9999,
3342 maxHeight: 9999,
3343 autoSize: true,
3344 autoHeight: false,
3345 autoWidth: false,
3346 autoResize: true,
3347 autoCenter: !isTouch,
3348 fitToView: true,
3349 aspectRatio: false,
3350 topRatio: .5,
3351 leftRatio: .5,
3352 scrolling: "auto",
3353 wrapCSS: "",
3354 arrows: true,
3355 closeBtn: true,
3356 closeClick: false,
3357 nextClick: false,
3358 mouseWheel: true,
3359 autoPlay: false,
3360 playSpeed: 3e3,
3361 preload: 3,
3362 modal: false,
3363 loop: true,
3364 ajax: {
3365 dataType: "html",
3366 headers: {
3367 "X-fancyBox": true
3368 }
3369 },
3370 iframe: {
3371 scrolling: "auto",
3372 preload: true
3373 },
3374 swf: {
3375 wmode: "transparent",
3376 allowfullscreen: "true",
3377 allowscriptaccess: "always"
3378 },
3379 keys: {
3380 next: {
3381 13: "left",
3382 34: "up",
3383 39: "left",
3384 40: "up"
3385 },
3386 prev: {
3387 8: "right",
3388 33: "down",
3389 37: "right",
3390 38: "down"
3391 },
3392 close: [27],
3393 play: [32],
3394 toggle: [70]
3395 },
3396 direction: {
3397 next: "left",
3398 prev: "right"
3399 },
3400 scrollOutside: true,
3401 index: 0,
3402 type: null,
3403 href: null,
3404 content: null,
3405 title: null,
3406 tpl: {
3407 wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
3408 image: '<img class="fancybox-image" src="{href}" alt="" />',
3409 iframe: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : "") + "></iframe>",
3410 error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
3411 closeBtn: '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
3412 next: '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
3413 prev: '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
3414 },
3415 openEffect: "fade",
3416 openSpeed: 250,
3417 openEasing: "swing",
3418 openOpacity: true,
3419 openMethod: "zoomIn",
3420 closeEffect: "fade",
3421 closeSpeed: 250,
3422 closeEasing: "swing",
3423 closeOpacity: true,
3424 closeMethod: "zoomOut",
3425 nextEffect: "elastic",
3426 nextSpeed: 250,
3427 nextEasing: "swing",
3428 nextMethod: "changeIn",
3429 prevEffect: "elastic",
3430 prevSpeed: 250,
3431 prevEasing: "swing",
3432 prevMethod: "changeOut",
3433 helpers: {
3434 overlay: true,
3435 title: true
3436 },
3437 onCancel: $.noop,
3438 beforeLoad: $.noop,
3439 afterLoad: $.noop,
3440 beforeShow: $.noop,
3441 afterShow: $.noop,
3442 beforeChange: $.noop,
3443 beforeClose: $.noop,
3444 afterClose: $.noop
3445 },
3446 group: {},
3447 opts: {},
3448 previous: null,
3449 coming: null,
3450 current: null,
3451 isActive: false,
3452 isOpen: false,
3453 isOpened: false,
3454 wrap: null,
3455 skin: null,
3456 outer: null,
3457 inner: null,
3458 player: {
3459 timer: null,
3460 isActive: false
3461 },
3462 ajaxLoad: null,
3463 imgPreload: null,
3464 transitions: {},
3465 helpers: {},
3466 open: function(group, opts) {
3467 if (!group) {
3468 return
3469 }
3470 if (!$.isPlainObject(opts)) {
3471 opts = {}
3472 }
3473 if (false === F.close(true)) {
3474 return
3475 }
3476 if (!$.isArray(group)) {
3477 group = isQuery(group) ? $(group).get() : [group]
3478 }
3479 $.each(group, function(i, element) {
3480 var obj = {},
3481 href, title, content, type, rez, hrefParts, selector;
3482 if ($.type(element) === "object") {
3483 if (element.nodeType) {
3484 element = $(element)
3485 }
3486 if (isQuery(element)) {
3487 obj = {
3488 href: element.data("fancybox-href") || element.attr("href"),
3489 title: element.data("fancybox-title") || element.attr("title"),
3490 isDom: true,
3491 element: element
3492 };
3493 if ($.metadata) {
3494 $.extend(true, obj, element.metadata())
3495 }
3496 } else {
3497 obj = element
3498 }
3499 }
3500 href = opts.href || obj.href || (isString(element) ? element : null);
3501 title = opts.title !== undefined ? opts.title : obj.title || "";
3502 content = opts.content || obj.content;
3503 type = content ? "html" : opts.type || obj.type;
3504 if (!type && obj.isDom) {
3505 type = element.data("fancybox-type");
3506 if (!type) {
3507 rez = element.prop("class").match(/fancybox\.(\w+)/);
3508 type = rez ? rez[1] : null
3509 }
3510 }
3511 if (isString(href)) {
3512 if (!type) {
3513 if (F.isImage(href)) {
3514 type = "image"
3515 } else if (F.isSWF(href)) {
3516 type = "swf"
3517 } else if (href.charAt(0) === "#") {
3518 type = "inline"
3519 } else if (isString(element)) {
3520 type = "html";
3521 content = element
3522 }
3523 }
3524 if (type === "ajax") {
3525 hrefParts = href.split(/\s+/, 2);
3526 href = hrefParts.shift();
3527 selector = hrefParts.shift()
3528 }
3529 }
3530 if (!content) {
3531 if (type === "inline") {
3532 if (href) {
3533 content = $(isString(href) ? href.replace(/.*(?=#[^\s]+$)/, "") : href)
3534 } else if (obj.isDom) {
3535 content = element
3536 }
3537 } else if (type === "html") {
3538 content = href
3539 } else if (!type && !href && obj.isDom) {
3540 type = "inline";
3541 content = element
3542 }
3543 }
3544 $.extend(obj, {
3545 href: href,
3546 type: type,
3547 content: content,
3548 title: title,
3549 selector: selector
3550 });
3551 group[i] = obj
3552 });
3553 F.opts = $.extend(true, {}, F.defaults, opts);
3554 if (opts.keys !== undefined) {
3555 F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false
3556 }
3557 F.group = group;
3558 return F._start(F.opts.index)
3559 },
3560 cancel: function() {
3561 var coming = F.coming;
3562 if (!coming || false === F.trigger("onCancel")) {
3563 return
3564 }
3565 F.hideLoading();
3566 if (F.ajaxLoad) {
3567 F.ajaxLoad.abort()
3568 }
3569 F.ajaxLoad = null;
3570 if (F.imgPreload) {
3571 F.imgPreload.onload = F.imgPreload.onerror = null
3572 }
3573 if (coming.wrap) {
3574 coming.wrap.stop(true, true).trigger("onReset").remove()
3575 }
3576 F.coming = null;
3577 if (!F.current) {
3578 F._afterZoomOut(coming)
3579 }
3580 },
3581 close: function(event) {
3582 F.cancel();
3583 if (false === F.trigger("beforeClose")) {
3584 return
3585 }
3586 F.unbindEvents();
3587 if (!F.isActive) {
3588 return
3589 }
3590 if (!F.isOpen || event === true) {
3591 $(".fancybox-wrap").stop(true).trigger("onReset").remove();
3592 F._afterZoomOut()
3593 } else {
3594 F.isOpen = F.isOpened = false;
3595 F.isClosing = true;
3596 $(".fancybox-item, .fancybox-nav").remove();
3597 F.wrap.stop(true, true).removeClass("fancybox-opened");
3598 F.transitions[F.current.closeMethod]()
3599 }
3600 },
3601 play: function(action) {
3602 var clear = function() {
3603 clearTimeout(F.player.timer)
3604 },
3605 set = function() {
3606 clear();
3607 if (F.current && F.player.isActive) {
3608 F.player.timer = setTimeout(F.next, F.current.playSpeed)
3609 }
3610 },
3611 stop = function() {
3612 clear();
3613 $("body").unbind(".player");
3614 F.player.isActive = false;
3615 F.trigger("onPlayEnd")
3616 },
3617 start = function() {
3618 if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
3619 F.player.isActive = true;
3620 $("body").bind({
3621 "afterShow.player onUpdate.player": set,
3622 "onCancel.player beforeClose.player": stop,
3623 "beforeLoad.player": clear
3624 });
3625 set();
3626 F.trigger("onPlayStart")
3627 }
3628 };
3629 if (action === true || !F.player.isActive && action !== false) {
3630 start()
3631 } else {
3632 stop()
3633 }
3634 },
3635 next: function(direction) {
3636 var current = F.current;
3637 if (current) {
3638 if (!isString(direction)) {
3639 direction = current.direction.next
3640 }
3641 F.jumpto(current.index + 1, direction, "next")
3642 }
3643 },
3644 prev: function(direction) {
3645 var current = F.current;
3646 if (current) {
3647 if (!isString(direction)) {
3648 direction = current.direction.prev
3649 }
3650 F.jumpto(current.index - 1, direction, "prev")
3651 }
3652 },
3653 jumpto: function(index, direction, router) {
3654 var current = F.current;
3655 if (!current) {
3656 return
3657 }
3658 index = getScalar(index);
3659 F.direction = direction || current.direction[index >= current.index ? "next" : "prev"];
3660 F.router = router || "jumpto";
3661 if (current.loop) {
3662 if (index < 0) {
3663 index = current.group.length + index % current.group.length
3664 }
3665 index = index % current.group.length
3666 }
3667 if (current.group[index] !== undefined) {
3668 F.cancel();
3669 F._start(index)
3670 }
3671 },
3672 reposition: function(e, onlyAbsolute) {
3673 var current = F.current,
3674 wrap = current ? current.wrap : null,
3675 pos;
3676 if (wrap) {
3677 pos = F._getPosition(onlyAbsolute);
3678 if (e && e.type === "scroll") {
3679 delete pos.position;
3680 wrap.stop(true, true).animate(pos, 200)
3681 } else {
3682 wrap.css(pos);
3683 current.pos = $.extend({}, current.dim, pos)
3684 }
3685 }
3686 },
3687 update: function(e) {
3688 var type = e && e.type,
3689 anyway = !type || type === "orientationchange";
3690 if (anyway) {
3691 clearTimeout(didUpdate);
3692 didUpdate = null
3693 }
3694 if (!F.isOpen || didUpdate) {
3695 return
3696 }
3697 didUpdate = setTimeout(function() {
3698 var current = F.current;
3699 if (!current || F.isClosing) {
3700 return
3701 }
3702 F.wrap.removeClass("fancybox-tmp");
3703 if (anyway || type === "load" || type === "resize" && current.autoResize) {
3704 F._setDimension()
3705 }
3706 if (!(type === "scroll" && current.canShrink)) {
3707 F.reposition(e)
3708 }
3709 F.trigger("onUpdate");
3710 didUpdate = null
3711 }, anyway && !isTouch ? 0 : 300)
3712 },
3713 toggle: function(action) {
3714 if (F.isOpen) {
3715 F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView;
3716 if (isTouch) {
3717 F.wrap.removeAttr("style").addClass("fancybox-tmp");
3718 F.trigger("onUpdate")
3719 }
3720 F.update()
3721 }
3722 },
3723 hideLoading: function() {
3724 D.unbind(".loading");
3725 $("#fancybox-loading").remove()
3726 },
3727 showLoading: function() {
3728 var el, viewport;
3729 F.hideLoading();
3730 el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo("body");
3731 D.bind("keydown.loading", function(e) {
3732 if ((e.which || e.keyCode) === 27) {
3733 e.preventDefault();
3734 F.cancel()
3735 }
3736 });
3737 if (!F.defaults.fixed) {
3738 viewport = F.getViewport();
3739 el.css({
3740 position: "absolute",
3741 top: viewport.h * .5 + viewport.y,
3742 left: viewport.w * .5 + viewport.x
3743 })
3744 }
3745 },
3746 getViewport: function() {
3747 var locked = F.current && F.current.locked || false,
3748 rez = {
3749 x: W.scrollLeft(),
3750 y: W.scrollTop()
3751 };
3752 if (locked) {
3753 rez.w = locked[0].clientWidth;
3754 rez.h = locked[0].clientHeight
3755 } else {
3756 rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width();
3757 rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height()
3758 }
3759 return rez
3760 },
3761 unbindEvents: function() {
3762 if (F.wrap && isQuery(F.wrap)) {
3763 F.wrap.unbind(".fb")
3764 }
3765 D.unbind(".fb");
3766 W.unbind(".fb")
3767 },
3768 bindEvents: function() {
3769 var current = F.current,
3770 keys;
3771 if (!current) {
3772 return
3773 }
3774 W.bind("orientationchange.fb" + (isTouch ? "" : " resize.fb") + (current.autoCenter && !current.locked ? " scroll.fb" : ""), F.update);
3775 keys = current.keys;
3776 if (keys) {
3777 D.bind("keydown.fb", function(e) {
3778 var code = e.which || e.keyCode,
3779 target = e.target || e.srcElement;
3780 if (code === 27 && F.coming) {
3781 return false
3782 }
3783 if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is("[contenteditable]")))) {
3784 $.each(keys, function(i, val) {
3785 if (current.group.length > 1 && val[code] !== undefined) {
3786 F[i](val[code]);
3787 e.preventDefault();
3788 return false
3789 }
3790 if ($.inArray(code, val) > -1) {
3791 F[i]();
3792 e.preventDefault();
3793 return false
3794 }
3795 })
3796 }
3797 })
3798 }
3799 if ($.fn.mousewheel && current.mouseWheel) {
3800 F.wrap.bind("mousewheel.fb", function(e, delta, deltaX, deltaY) {
3801 var target = e.target || null,
3802 parent = $(target),
3803 canScroll = false;
3804 while (parent.length) {
3805 if (canScroll || parent.is(".fancybox-skin") || parent.is(".fancybox-wrap")) {
3806 break
3807 }
3808 canScroll = isScrollable(parent[0]);
3809 parent = $(parent).parent()
3810 }
3811 if (delta !== 0 && !canScroll) {
3812 if (F.group.length > 1 && !current.canShrink) {
3813 if (deltaY > 0 || deltaX > 0) {
3814 F.prev(deltaY > 0 ? "down" : "left")
3815 } else if (deltaY < 0 || deltaX < 0) {
3816 F.next(deltaY < 0 ? "up" : "right")
3817 }
3818 e.preventDefault()
3819 }
3820 }
3821 })
3822 }
3823 },
3824 trigger: function(event, o) {
3825 var ret, obj = o || F.coming || F.current;
3826 if (!obj) {
3827 return
3828 }
3829 if ($.isFunction(obj[event])) {
3830 ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1))
3831 }
3832 if (ret === false) {
3833 return false
3834 }
3835 if (obj.helpers) {
3836 $.each(obj.helpers, function(helper, opts) {
3837 if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) {
3838 opts = $.extend(true, {}, F.helpers[helper].defaults, opts);
3839 F.helpers[helper][event](opts, obj)
3840 }
3841 })
3842 }
3843 $.event.trigger(event + ".fb")
3844 },
3845 isImage: function(str) {
3846 return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp)((\?|#).*)?$)/i)
3847 },
3848 isSWF: function(str) {
3849 return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i)
3850 },
3851 _start: function(index) {
3852 var coming = {},
3853 obj, href, type, margin, padding;
3854 index = getScalar(index);
3855 obj = F.group[index] || null;
3856 if (!obj) {
3857 return false
3858 }
3859 coming = $.extend(true, {}, F.opts, obj);
3860 margin = coming.margin;
3861 padding = coming.padding;
3862 if ($.type(margin) === "number") {
3863 coming.margin = [margin, margin, margin, margin]
3864 }
3865 if ($.type(padding) === "number") {
3866 coming.padding = [padding, padding, padding, padding]
3867 }
3868 if (coming.modal) {
3869 $.extend(true, coming, {
3870 closeBtn: false,
3871 closeClick: false,
3872 nextClick: false,
3873 arrows: false,
3874 mouseWheel: false,
3875 keys: null,
3876 helpers: {
3877 overlay: {
3878 closeClick: false
3879 }
3880 }
3881 })
3882 }
3883 if (coming.autoSize) {
3884 coming.autoWidth = coming.autoHeight = true
3885 }
3886 if (coming.width === "auto") {
3887 coming.autoWidth = true
3888 }
3889 if (coming.height === "auto") {
3890 coming.autoHeight = true
3891 }
3892 coming.group = F.group;
3893 coming.index = index;
3894 F.coming = coming;
3895 if (false === F.trigger("beforeLoad")) {
3896 F.coming = null;
3897 return
3898 }
3899 type = coming.type;
3900 href = coming.href;
3901 if (!type) {
3902 F.coming = null;
3903 if (F.current && F.router && F.router !== "jumpto") {
3904 F.current.index = index;
3905 return F[F.router](F.direction)
3906 }
3907 return false
3908 }
3909 F.isActive = true;
3910 if (type === "image" || type === "swf") {
3911 coming.autoHeight = coming.autoWidth = false;
3912 coming.scrolling = "visible"
3913 }
3914 if (type === "image") {
3915 coming.aspectRatio = true
3916 }
3917 if (type === "iframe" && isTouch) {
3918 coming.scrolling = "scroll"
3919 }
3920 coming.wrap = $(coming.tpl.wrap).addClass("fancybox-" + (isTouch ? "mobile" : "desktop") + " fancybox-type-" + type + " fancybox-tmp " + coming.wrapCSS).appendTo(coming.parent || "body");
3921 $.extend(coming, {
3922 skin: $(".fancybox-skin", coming.wrap),
3923 outer: $(".fancybox-outer", coming.wrap),
3924 inner: $(".fancybox-inner", coming.wrap)
3925 });
3926 $.each(["Top", "Right", "Bottom", "Left"], function(i, v) {
3927 coming.skin.css("padding" + v, getValue(coming.padding[i]))
3928 });
3929 F.trigger("onReady");
3930 if (type === "inline" || type === "html") {
3931 if (!coming.content || !coming.content.length) {
3932 return F._error("content")
3933 }
3934 } else if (!href) {
3935 return F._error("href")
3936 }
3937 if (type === "image") {
3938 F._loadImage()
3939 } else if (type === "ajax") {
3940 F._loadAjax()
3941 } else if (type === "iframe") {
3942 F._loadIframe()
3943 } else {
3944 F._afterLoad()
3945 }
3946 },
3947 _error: function(type) {
3948 $.extend(F.coming, {
3949 type: "html",
3950 autoWidth: true,
3951 autoHeight: true,
3952 minWidth: 0,
3953 minHeight: 0,
3954 scrolling: "no",
3955 hasError: type,
3956 content: F.coming.tpl.error
3957 });
3958 F._afterLoad()
3959 },
3960 _loadImage: function() {
3961 var img = F.imgPreload = new Image;
3962 img.onload = function() {
3963 this.onload = this.onerror = null;
3964 F.coming.width = this.width;
3965 F.coming.height = this.height;
3966 F._afterLoad()
3967 };
3968 img.onerror = function() {
3969 this.onload = this.onerror = null;
3970 F._error("image")
3971 };
3972 img.src = F.coming.href;
3973 if (img.complete !== true) {
3974 F.showLoading()
3975 }
3976 },
3977 _loadAjax: function() {
3978 var coming = F.coming;
3979 F.showLoading();
3980 F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {
3981 url: coming.href,
3982 error: function(jqXHR, textStatus) {
3983 if (F.coming && textStatus !== "abort") {
3984 F._error("ajax", jqXHR)
3985 } else {
3986 F.hideLoading()
3987 }
3988 },
3989 success: function(data, textStatus) {
3990 if (textStatus === "success") {
3991 coming.content = data;
3992 F._afterLoad()
3993 }
3994 }
3995 }))
3996 },
3997 _loadIframe: function() {
3998 var coming = F.coming,
3999 iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, (new Date).getTime())).attr("scrolling", isTouch ? "auto" : coming.iframe.scrolling).attr("src", coming.href);
4000 $(coming.wrap).bind("onReset", function() {
4001 try {
4002 $(this).find("iframe").hide().attr("src", "//about:blank").end().empty()
4003 } catch (e) {}
4004 });
4005 if (coming.iframe.preload) {
4006 F.showLoading();
4007 iframe.one("load", function() {
4008 $(this).data("ready", 1);
4009 if (!isTouch) {
4010 $(this).bind("load.fb", F.update)
4011 }
4012 $(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show();
4013 F._afterLoad()
4014 })
4015 }
4016 coming.content = iframe.appendTo(coming.inner);
4017 if (!coming.iframe.preload) {
4018 F._afterLoad()
4019 }
4020 },
4021 _preloadImages: function() {
4022 var group = F.group,
4023 current = F.current,
4024 len = group.length,
4025 cnt = current.preload ? Math.min(current.preload, len - 1) : 0,
4026 item, i;
4027 for (i = 1; i <= cnt; i += 1) {
4028 item = group[(current.index + i) % len];
4029 if (item.type === "image" && item.href) {
4030 (new Image).src = item.href
4031 }
4032 }
4033 },
4034 _afterLoad: function() {
4035 var coming = F.coming,
4036 previous = F.current,
4037 placeholder = "fancybox-placeholder",
4038 current, content, type, scrolling, href, embed;
4039 F.hideLoading();
4040 if (!coming || F.isActive === false) {
4041 return
4042 }
4043 if (false === F.trigger("afterLoad", coming, previous)) {
4044 coming.wrap.stop(true).trigger("onReset").remove();
4045 F.coming = null;
4046 return
4047 }
4048 if (previous) {
4049 F.trigger("beforeChange", previous);
4050 previous.wrap.stop(true).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove()
4051 }
4052 F.unbindEvents();
4053 current = coming;
4054 content = coming.content;
4055 type = coming.type;
4056 scrolling = coming.scrolling;
4057 $.extend(F, {
4058 wrap: current.wrap,
4059 skin: current.skin,
4060 outer: current.outer,
4061 inner: current.inner,
4062 current: current,
4063 previous: previous
4064 });
4065 href = current.href;
4066 switch (type) {
4067 case "inline":
4068 case "ajax":
4069 case "html":
4070 if (current.selector) {
4071 content = $("<div>").html(content).find(current.selector)
4072 } else if (isQuery(content)) {
4073 if (!content.data(placeholder)) {
4074 content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter(content).hide())
4075 }
4076 content = content.show().detach();
4077 current.wrap.bind("onReset", function() {
4078 if ($(this).find(content).length) {
4079 content.hide().replaceAll(content.data(placeholder)).data(placeholder, false)
4080 }
4081 })
4082 }
4083 break;
4084 case "image":
4085 content = current.tpl.image.replace("{href}", href);
4086 break;
4087 case "swf":
4088 content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';
4089 embed = "";
4090 $.each(current.swf, function(name, val) {
4091 content += '<param name="' + name + '" value="' + val + '"></param>';
4092 embed += " " + name + '="' + val + '"'
4093 });
4094 content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + "></embed></object>";
4095 break
4096 }
4097 if (!(isQuery(content) && content.parent().is(current.inner))) {
4098 current.inner.append(content)
4099 }
4100 F.trigger("beforeShow");
4101 current.inner.css("overflow", scrolling === "yes" ? "scroll" : scrolling === "no" ? "hidden" : scrolling);
4102 F._setDimension();
4103 F.reposition();
4104 F.isOpen = false;
4105 F.coming = null;
4106 F.bindEvents();
4107 if (!F.isOpened) {
4108 $(".fancybox-wrap").not(current.wrap).stop(true).trigger("onReset").remove()
4109 } else if (previous.prevMethod) {
4110 F.transitions[previous.prevMethod]()
4111 }
4112 F.transitions[F.isOpened ? current.nextMethod : current.openMethod]();
4113 F._preloadImages()
4114 },
4115 _setDimension: function() {
4116 var viewport = F.getViewport(),
4117 steps = 0,
4118 canShrink = false,
4119 canExpand = false,
4120 wrap = F.wrap,
4121 skin = F.skin,
4122 inner = F.inner,
4123 current = F.current,
4124 width = current.width,
4125 height = current.height,
4126 minWidth = current.minWidth,
4127 minHeight = current.minHeight,
4128 maxWidth = current.maxWidth,
4129 maxHeight = current.maxHeight,
4130 scrolling = current.scrolling,
4131 scrollOut = current.scrollOutside ? current.scrollbarWidth : 0,
4132 margin = current.margin,
4133 wMargin = getScalar(margin[1] + margin[3]),
4134 hMargin = getScalar(margin[0] + margin[2]),
4135 wPadding, hPadding, wSpace, hSpace, origWidth, origHeight, origMaxWidth, origMaxHeight, ratio, width_, height_, maxWidth_, maxHeight_, iframe, body;
4136 wrap.add(skin).add(inner).width("auto").height("auto").removeClass("fancybox-tmp");
4137 wPadding = getScalar(skin.outerWidth(true) - skin.width());
4138 hPadding = getScalar(skin.outerHeight(true) - skin.height());
4139 wSpace = wMargin + wPadding;
4140 hSpace = hMargin + hPadding;
4141 origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width;
4142 origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;
4143 if (current.type === "iframe") {
4144 iframe = current.content;
4145 if (current.autoHeight && iframe.data("ready") === 1) {
4146 try {
4147 if (iframe[0].contentWindow.document.location) {
4148 inner.width(origWidth).height(9999);
4149 body = iframe.contents().find("body");
4150 if (scrollOut) {
4151 body.css("overflow-x", "hidden")
4152 }
4153 origHeight = body.height()
4154 }
4155 } catch (e) {}
4156 }
4157 } else if (current.autoWidth || current.autoHeight) {
4158 inner.addClass("fancybox-tmp");
4159 if (!current.autoWidth) {
4160 inner.width(origWidth)
4161 }
4162 if (!current.autoHeight) {
4163 inner.height(origHeight)
4164 }
4165 if (current.autoWidth) {
4166 origWidth = inner.width()
4167 }
4168 if (current.autoHeight) {
4169 origHeight = inner.height()
4170 }
4171 inner.removeClass("fancybox-tmp")
4172 }
4173 width = getScalar(origWidth);
4174 height = getScalar(origHeight);
4175 ratio = origWidth / origHeight;
4176 minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, "w") - wSpace : minWidth);
4177 maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, "w") - wSpace : maxWidth);
4178 minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, "h") - hSpace : minHeight);
4179 maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, "h") - hSpace : maxHeight);
4180 origMaxWidth = maxWidth;
4181 origMaxHeight = maxHeight;
4182 if (current.fitToView) {
4183 maxWidth = Math.min(viewport.w - wSpace, maxWidth);
4184 maxHeight = Math.min(viewport.h - hSpace, maxHeight)
4185 }
4186 maxWidth_ = viewport.w - wMargin;
4187 maxHeight_ = viewport.h - hMargin;
4188 if (current.aspectRatio) {
4189 if (width > maxWidth) {
4190 width = maxWidth;
4191 height = getScalar(width / ratio)
4192 }
4193 if (height > maxHeight) {
4194 height = maxHeight;
4195 width = getScalar(height * ratio)
4196 }
4197 if (width < minWidth) {
4198 width = minWidth;
4199 height = getScalar(width / ratio)
4200 }
4201 if (height < minHeight) {
4202 height = minHeight;
4203 width = getScalar(height * ratio)
4204 }
4205 } else {
4206 width = Math.max(minWidth, Math.min(width, maxWidth));
4207 if (current.autoHeight && current.type !== "iframe") {
4208 inner.width(width);
4209 height = inner.height()
4210 }
4211 height = Math.max(minHeight, Math.min(height, maxHeight))
4212 }
4213 if (current.fitToView) {
4214 inner.width(width).height(height);
4215 wrap.width(width + wPadding);
4216 width_ = wrap.width();
4217 height_ = wrap.height();
4218 if (current.aspectRatio) {
4219 while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
4220 if (steps++ > 19) {
4221 break
4222 }
4223 height = Math.max(minHeight, Math.min(maxHeight, height - 10));
4224 width = getScalar(height * ratio);
4225 if (width < minWidth) {
4226 width = minWidth;
4227 height = getScalar(width / ratio)
4228 }
4229 if (width > maxWidth) {
4230 width = maxWidth;
4231 height = getScalar(width / ratio)
4232 }
4233 inner.width(width).height(height);
4234 wrap.width(width + wPadding);
4235 width_ = wrap.width();
4236 height_ = wrap.height()
4237 }
4238 } else {
4239 width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_)));
4240 height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)))
4241 }
4242 }
4243 if (scrollOut && scrolling === "auto" && height < origHeight && width + wPadding + scrollOut < maxWidth_) {
4244 width += scrollOut
4245 }
4246 inner.width(width).height(height);
4247 wrap.width(width + wPadding);
4248 width_ = wrap.width();
4249 height_ = wrap.height();
4250 canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
4251 canExpand = current.aspectRatio ? width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight : (width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight);
4252 $.extend(current, {
4253 dim: {
4254 width: getValue(width_),
4255 height: getValue(height_)
4256 },
4257 origWidth: origWidth,
4258 origHeight: origHeight,
4259 canShrink: canShrink,
4260 canExpand: canExpand,
4261 wPadding: wPadding,
4262 hPadding: hPadding,
4263 wrapSpace: height_ - skin.outerHeight(true),
4264 skinSpace: skin.height() - height
4265 });
4266 if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
4267 inner.height("auto")
4268 }
4269 },
4270 _getPosition: function(onlyAbsolute) {
4271 var current = F.current,
4272 viewport = F.getViewport(),
4273 margin = current.margin,
4274 width = F.wrap.width() + margin[1] + margin[3],
4275 height = F.wrap.height() + margin[0] + margin[2],
4276 rez = {
4277 position: "absolute",
4278 top: margin[0],
4279 left: margin[3]
4280 };
4281 if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
4282 rez.position = "fixed"
4283 } else if (!current.locked) {
4284 rez.top += viewport.y;
4285 rez.left += viewport.x
4286 }
4287 rez.top = getValue(Math.max(rez.top, rez.top + (viewport.h - height) * current.topRatio));
4288 rez.left = getValue(Math.max(rez.left, rez.left + (viewport.w - width) * current.leftRatio));
4289 return rez
4290 },
4291 _afterZoomIn: function() {
4292 var current = F.current;
4293 if (!current) {
4294 return
4295 }
4296 F.isOpen = F.isOpened = true;
4297 F.wrap.css("overflow", "visible").addClass("fancybox-opened");
4298 F.update();
4299 if (current.closeClick || current.nextClick && F.group.length > 1) {
4300 F.inner.css("cursor", "pointer").bind("click.fb", function(e) {
4301 if (!$(e.target).is("a") && !$(e.target).parent().is("a")) {
4302 e.preventDefault();
4303 F[current.closeClick ? "close" : "next"]()
4304 }
4305 })
4306 }
4307 if (current.closeBtn) {
4308 $(current.tpl.closeBtn).appendTo(F.skin).bind("click.fb", function(e) {
4309 e.preventDefault();
4310 F.close()
4311 })
4312 }
4313 if (current.arrows && F.group.length > 1) {
4314 if (current.loop || current.index > 0) {
4315 $(current.tpl.prev).appendTo(F.outer).bind("click.fb", F.prev)
4316 }
4317 if (current.loop || current.index < F.group.length - 1) {
4318 $(current.tpl.next).appendTo(F.outer).bind("click.fb", F.next)
4319 }
4320 }
4321 F.trigger("afterShow");
4322 if (!current.loop && current.index === current.group.length - 1) {
4323 F.play(false)
4324 } else if (F.opts.autoPlay && !F.player.isActive) {
4325 F.opts.autoPlay = false;
4326 F.play()
4327 }
4328 },
4329 _afterZoomOut: function(obj) {
4330 obj = obj || F.current;
4331 $(".fancybox-wrap").trigger("onReset").remove();
4332 $.extend(F, {
4333 group: {},
4334 opts: {},
4335 router: false,
4336 current: null,
4337 isActive: false,
4338 isOpened: false,
4339 isOpen: false,
4340 isClosing: false,
4341 wrap: null,
4342 skin: null,
4343 outer: null,
4344 inner: null
4345 });
4346 F.trigger("afterClose", obj)
4347 }
4348 });
4349 F.transitions = {
4350 getOrigPosition: function() {
4351 var current = F.current,
4352 element = current.element,
4353 orig = current.orig,
4354 pos = {},
4355 width = 50,
4356 height = 50,
4357 hPadding = current.hPadding,
4358 wPadding = current.wPadding,
4359 viewport = F.getViewport();
4360 if (!orig && current.isDom && element.is(":visible")) {
4361 orig = element.find("img:first");
4362 if (!orig.length) {
4363 orig = element
4364 }
4365 }
4366 if (isQuery(orig)) {
4367 pos = orig.offset();
4368 if (orig.is("img")) {
4369 width = orig.outerWidth();
4370 height = orig.outerHeight()
4371 }
4372 } else {
4373 pos.top = viewport.y + (viewport.h - height) * current.topRatio;
4374 pos.left = viewport.x + (viewport.w - width) * current.leftRatio
4375 }
4376 if (F.wrap.css("position") === "fixed" || current.locked) {
4377 pos.top -= viewport.y;
4378 pos.left -= viewport.x
4379 }
4380 pos = {
4381 top: getValue(pos.top - hPadding * current.topRatio),
4382 left: getValue(pos.left - wPadding * current.leftRatio),
4383 width: getValue(width + wPadding),
4384 height: getValue(height + hPadding)
4385 };
4386 return pos
4387 },
4388 step: function(now, fx) {
4389 var ratio, padding, value, prop = fx.prop,
4390 current = F.current,
4391 wrapSpace = current.wrapSpace,
4392 skinSpace = current.skinSpace;
4393 if (prop === "width" || prop === "height") {
4394 ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);
4395 if (F.isClosing) {
4396 ratio = 1 - ratio
4397 }
4398 padding = prop === "width" ? current.wPadding : current.hPadding;
4399 value = now - padding;
4400 F.skin[prop](getScalar(prop === "width" ? value : value - wrapSpace * ratio));
4401 F.inner[prop](getScalar(prop === "width" ? value : value - wrapSpace * ratio - skinSpace * ratio))
4402 }
4403 },
4404 zoomIn: function() {
4405 var current = F.current,
4406 startPos = current.pos,
4407 effect = current.openEffect,
4408 elastic = effect === "elastic",
4409 endPos = $.extend({
4410 opacity: 1
4411 }, startPos);
4412 delete endPos.position;
4413 if (elastic) {
4414 startPos = this.getOrigPosition();
4415 if (current.openOpacity) {
4416 startPos.opacity = .1
4417 }
4418 } else if (effect === "fade") {
4419 startPos.opacity = .1
4420 }
4421 F.wrap.css(startPos).animate(endPos, {
4422 duration: effect === "none" ? 0 : current.openSpeed,
4423 easing: current.openEasing,
4424 step: elastic ? this.step : null,
4425 complete: F._afterZoomIn
4426 })
4427 },
4428 zoomOut: function() {
4429 var current = F.current,
4430 effect = current.closeEffect,
4431 elastic = effect === "elastic",
4432 endPos = {
4433 opacity: .1
4434 };
4435 if (elastic) {
4436 endPos = this.getOrigPosition();
4437 if (current.closeOpacity) {
4438 endPos.opacity = .1
4439 }
4440 }
4441 F.wrap.animate(endPos, {
4442 duration: effect === "none" ? 0 : current.closeSpeed,
4443 easing: current.closeEasing,
4444 step: elastic ? this.step : null,
4445 complete: F._afterZoomOut
4446 })
4447 },
4448 changeIn: function() {
4449 var current = F.current,
4450 effect = current.nextEffect,
4451 startPos = current.pos,
4452 endPos = {
4453 opacity: 1
4454 },
4455 direction = F.direction,
4456 distance = 200,
4457 field;
4458 startPos.opacity = .1;
4459 if (effect === "elastic") {
4460 field = direction === "down" || direction === "up" ? "top" : "left";
4461 if (direction === "down" || direction === "right") {
4462 startPos[field] = getValue(getScalar(startPos[field]) - distance);
4463 endPos[field] = "+=" + distance + "px"
4464 } else {
4465 startPos[field] = getValue(getScalar(startPos[field]) + distance);
4466 endPos[field] = "-=" + distance + "px"
4467 }
4468 }
4469 if (effect === "none") {
4470 F._afterZoomIn()
4471 } else {
4472 F.wrap.css(startPos).animate(endPos, {
4473 duration: current.nextSpeed,
4474 easing: current.nextEasing,
4475 complete: F._afterZoomIn
4476 })
4477 }
4478 },
4479 changeOut: function() {
4480 var previous = F.previous,
4481 effect = previous.prevEffect,
4482 endPos = {
4483 opacity: .1
4484 },
4485 direction = F.direction,
4486 distance = 200;
4487 if (effect === "elastic") {
4488 endPos[direction === "down" || direction === "up" ? "top" : "left"] = (direction === "up" || direction === "left" ? "-" : "+") + "=" + distance + "px"
4489 }
4490 previous.wrap.animate(endPos, {
4491 duration: effect === "none" ? 0 : previous.prevSpeed,
4492 easing: previous.prevEasing,
4493 complete: function() {
4494 $(this).trigger("onReset").remove()
4495 }
4496 })
4497 }
4498 };
4499 F.helpers.overlay = {
4500 defaults: {
4501 closeClick: true,
4502 speedOut: 200,
4503 showEarly: true,
4504 css: {},
4505 locked: !isTouch,
4506 fixed: true
4507 },
4508 overlay: null,
4509 fixed: false,
4510 create: function(opts) {
4511 opts = $.extend({}, this.defaults, opts);
4512 if (this.overlay) {
4513 this.close()
4514 }
4515 this.overlay = $('<div class="fancybox-overlay"></div>').appendTo("body");
4516 this.fixed = false;
4517 if (opts.fixed && F.defaults.fixed) {
4518 this.overlay.addClass("fancybox-overlay-fixed");
4519 this.fixed = true
4520 }
4521 },
4522 open: function(opts) {
4523 var that = this;
4524 opts = $.extend({}, this.defaults, opts);
4525 if (this.overlay) {
4526 this.overlay.unbind(".overlay").width("auto").height("auto")
4527 } else {
4528 this.create(opts)
4529 }
4530 if (!this.fixed) {
4531 W.bind("resize.overlay", $.proxy(this.update, this));
4532 this.update()
4533 }
4534 if (opts.closeClick) {
4535 this.overlay.bind("click.overlay", function(e) {
4536 if ($(e.target).hasClass("fancybox-overlay")) {
4537 if (F.isActive) {
4538 F.close()
4539 } else {
4540 that.close()
4541 }
4542 }
4543 })
4544 }
4545 this.overlay.css(opts.css).show()
4546 },
4547 close: function() {
4548 $(".fancybox-overlay").remove();
4549 W.unbind("resize.overlay");
4550 this.overlay = null;
4551 if (this.margin !== false) {
4552 $("body").css("margin-right", this.margin);
4553 this.margin = false
4554 }
4555 if (this.el) {
4556 this.el.removeClass("fancybox-lock")
4557 }
4558 },
4559 update: function() {
4560 var width = "100%",
4561 offsetWidth;
4562 this.overlay.width(width).height("100%");
4563 if (IE) {
4564 offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
4565 if (D.width() > offsetWidth) {
4566 width = D.width()
4567 }
4568 } else if (D.width() > W.width()) {
4569 width = D.width()
4570 }
4571 this.overlay.width(width).height(D.height())
4572 },
4573 onReady: function(opts, obj) {
4574 $(".fancybox-overlay").stop(true, true);
4575 if (!this.overlay) {
4576 this.margin = D.height() > W.height() || $("body").css("overflow-y") === "scroll" ? $("body").css("margin-right") : false;
4577 this.el = document.all && !document.querySelector ? $("html") : $("body");
4578 this.create(opts)
4579 }
4580 if (opts.locked && this.fixed) {
4581 obj.locked = this.overlay.append(obj.wrap);
4582 obj.fixed = false
4583 }
4584 if (opts.showEarly === true) {
4585 this.beforeShow.apply(this, arguments)
4586 }
4587 },
4588 beforeShow: function(opts, obj) {
4589 if (obj.locked) {
4590 this.el.addClass("fancybox-lock");
4591 if (this.margin !== false) {
4592 $("body").css("margin-right", getScalar(this.margin) + obj.scrollbarWidth)
4593 }
4594 }
4595 this.open(opts)
4596 },
4597 onUpdate: function() {
4598 if (!this.fixed) {
4599 this.update()
4600 }
4601 },
4602 afterClose: function(opts) {
4603 if (this.overlay && !F.isActive) {
4604 this.overlay.fadeOut(opts.speedOut, $.proxy(this.close, this))
4605 }
4606 }
4607 };
4608 F.helpers.title = {
4609 defaults: {
4610 type: "float",
4611 position: "bottom"
4612 },
4613 beforeShow: function(opts) {
4614 var current = F.current,
4615 text = current.title,
4616 type = opts.type,
4617 title, target;
4618 if ($.isFunction(text)) {
4619 text = text.call(current.element, current)
4620 }
4621 if (!isString(text) || $.trim(text) === "") {
4622 return
4623 }
4624 title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">' + text + "</div>");
4625 switch (type) {
4626 case "inside":
4627 target = F.skin;
4628 break;
4629 case "outside":
4630 target = F.wrap;
4631 break;
4632 case "over":
4633 target = F.inner;
4634 break;
4635 default:
4636 target = F.skin;
4637 title.appendTo("body");
4638 if (IE) {
4639 title.width(title.width())
4640 }
4641 title.wrapInner('<span class="child"></span>');
4642 F.current.margin[2] += Math.abs(getScalar(title.css("margin-bottom")));
4643 break
4644 }
4645 title[opts.position === "top" ? "prependTo" : "appendTo"](target)
4646 }
4647 };
4648 $.fn.fancybox = function(options) {
4649 var index, that = $(this),
4650 selector = this.selector || "",
4651 run = function(e) {
4652 var what = $(this).blur(),
4653 idx = index,
4654 relType, relVal;
4655 if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is(".fancybox-wrap")) {
4656 relType = options.groupAttr || "data-fancybox-group";
4657 relVal = what.attr(relType);
4658 if (!relVal) {
4659 relType = "rel";
4660 relVal = what.get(0)[relType]
4661 }
4662 if (relVal && relVal !== "" && relVal !== "nofollow") {
4663 what = selector.length ? $(selector) : that;
4664 what = what.filter("[" + relType + '="' + relVal + '"]');
4665 idx = what.index(this)
4666 }
4667 options.index = idx;
4668 if (F.open(what, options) !== false) {
4669 e.preventDefault()
4670 }
4671 }
4672 };
4673 options = options || {};
4674 index = options.index || 0;
4675 if (!selector || options.live === false) {
4676 that.unbind("click.fb-start").bind("click.fb-start", run)
4677 } else {
4678 D.undelegate(selector, "click.fb-start").delegate(selector + ":not('.fancybox-item, .fancybox-nav')", "click.fb-start", run)
4679 }
4680 this.filter("[data-fancybox-start=1]").trigger("click");
4681 return this
4682 };
4683 D.ready(function() {
4684 if ($.scrollbarWidth === undefined) {
4685 $.scrollbarWidth = function() {
4686 var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo("body"),
4687 child = parent.children(),
4688 width = child.innerWidth() - child.height(99).innerWidth();
4689 parent.remove();
4690 return width
4691 }
4692 }
4693 if ($.support.fixedPosition === undefined) {
4694 $.support.fixedPosition = function() {
4695 var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo("body"),
4696 fixed = elem[0].offsetTop === 20 || elem[0].offsetTop === 15;
4697 elem.remove();
4698 return fixed
4699 }()
4700 }
4701 $.extend(F.defaults, {
4702 scrollbarWidth: $.scrollbarWidth(),
4703 fixed: $.support.fixedPosition,
4704 parent: $("body")
4705 })
4706 })
4707 }
4708 }, {}],
4709 6: [function(require, module, exports) {
4710 module.exports = function(jQuery) {
4711 jQuery.hotkeys = {
4712 version: "0.8",
4713 specialKeys: {
4714 8: "backspace",
4715 9: "tab",
4716 13: "return",
4717 16: "shift",
4718 17: "ctrl",
4719 18: "alt",
4720 19: "pause",
4721 20: "capslock",
4722 27: "esc",
4723 32: "space",
4724 33: "pageup",
4725 34: "pagedown",
4726 35: "end",
4727 36: "home",
4728 37: "left",
4729 38: "up",
4730 39: "right",
4731 40: "down",
4732 45: "insert",
4733 46: "del",
4734 96: "0",
4735 97: "1",
4736 98: "2",
4737 99: "3",
4738 100: "4",
4739 101: "5",
4740 102: "6",
4741 103: "7",
4742 104: "8",
4743 105: "9",
4744 106: "*",
4745 107: "+",
4746 109: "-",
4747 110: ".",
4748 111: "/",
4749 112: "f1",
4750 113: "f2",
4751 114: "f3",
4752 115: "f4",
4753 116: "f5",
4754 117: "f6",
4755 118: "f7",
4756 119: "f8",
4757 120: "f9",
4758 121: "f10",
4759 122: "f11",
4760 123: "f12",
4761 144: "numlock",
4762 145: "scroll",
4763 191: "/",
4764 224: "meta"
4765 },
4766 shiftNums: {
4767 "`": "~",
4768 1: "!",
4769 2: "@",
4770 3: "#",
4771 4: "$",
4772 5: "%",
4773 6: "^",
4774 7: "&",
4775 8: "*",
4776 9: "(",
4777 0: ")",
4778 "-": "_",
4779 "=": "+",
4780 ";": ": ",
4781 "'": '"',
4782 ",": "<",
4783 ".": ">",
4784 "/": "?",
4785 "\\": "|"
4786 }
4787 };
4788
4789 function keyHandler(handleObj) {
4790 if (typeof handleObj.data !== "string") {
4791 return
4792 }
4793 var origHandler = handleObj.handler,
4794 keys = handleObj.data.toLowerCase().split(" ");
4795 handleObj.handler = function(event) {
4796 if (this !== event.target && (/textarea|select/i.test(event.target.nodeName) || event.target.type === "text" || event.target.type === "password")) {
4797 return
4798 }
4799 var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[event.which],
4800 character = String.fromCharCode(event.which).toLowerCase(),
4801 key, modif = "",
4802 possible = {};
4803 if (event.altKey && special !== "alt") {
4804 modif += "alt+"
4805 }
4806 if (event.ctrlKey && special !== "ctrl") {
4807 modif += "ctrl+"
4808 }
4809 if (event.metaKey && !event.ctrlKey && special !== "meta") {
4810 modif += "meta+"
4811 }
4812 if (event.shiftKey && special !== "shift") {
4813 modif += "shift+"
4814 }
4815 if (special) {
4816 possible[modif + special] = true
4817 } else {
4818 possible[modif + character] = true;
4819 possible[modif + jQuery.hotkeys.shiftNums[character]] = true;
4820 if (modif === "shift+") {
4821 possible[jQuery.hotkeys.shiftNums[character]] = true
4822 }
4823 }
4824 for (var i = 0, l = keys.length; i < l; i++) {
4825 if (possible[keys[i]]) {
4826 return origHandler.apply(this, arguments)
4827 }
4828 }
4829 }
4830 }
4831 jQuery.each(["keydown", "keyup", "keypress"], function() {
4832 jQuery.event.special[this] = {
4833 add: keyHandler
4834 }
4835 })
4836 }
4837 }, {}],
4838 7: [function(require, module, exports) {
4839 (function(undefined) {
4840 var moment, VERSION = "2.0.0",
4841 round = Math.round,
4842 i, languages = {},
4843 hasModule = typeof module !== "undefined" && module.exports,
4844 aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
4845 formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
4846 localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
4847 parseMultipleFormatChunker = /([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,
4848 parseTokenOneOrTwoDigits = /\d\d?/,
4849 parseTokenOneToThreeDigits = /\d{1,3}/,
4850 parseTokenThreeDigits = /\d{3}/,
4851 parseTokenFourDigits = /\d{1,4}/,
4852 parseTokenSixDigits = /[+\-]?\d{1,6}/,
4853 parseTokenWord = /[0-9]*[a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF]+\s*?[\u0600-\u06FF]+/i,
4854 parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i,
4855 parseTokenT = /T/i,
4856 parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/,
4857 isoRegex = /^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,
4858 isoFormat = "YYYY-MM-DDTHH:mm:ssZ",
4859 isoTimes = [
4860 ["HH:mm:ss.S", /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
4861 ["HH:mm:ss", /(T| )\d\d:\d\d:\d\d/],
4862 ["HH:mm", /(T| )\d\d:\d\d/],
4863 ["HH", /(T| )\d\d/]
4864 ],
4865 parseTimezoneChunker = /([\+\-]|\d\d)/gi,
4866 proxyGettersAndSetters = "Month|Date|Hours|Minutes|Seconds|Milliseconds".split("|"),
4867 unitMillisecondFactors = {
4868 Milliseconds: 1,
4869 Seconds: 1e3,
4870 Minutes: 6e4,
4871 Hours: 36e5,
4872 Days: 864e5,
4873 Months: 2592e6,
4874 Years: 31536e6
4875 },
4876 formatFunctions = {},
4877 ordinalizeTokens = "DDD w W M D d".split(" "),
4878 paddedTokens = "M D H h m s w W".split(" "),
4879 formatTokenFunctions = {
4880 M: function() {
4881 return this.month() + 1
4882 },
4883 MMM: function(format) {
4884 return this.lang().monthsShort(this, format)
4885 },
4886 MMMM: function(format) {
4887 return this.lang().months(this, format)
4888 },
4889 D: function() {
4890 return this.date()
4891 },
4892 DDD: function() {
4893 return this.dayOfYear()
4894 },
4895 d: function() {
4896 return this.day()
4897 },
4898 dd: function(format) {
4899 return this.lang().weekdaysMin(this, format)
4900 },
4901 ddd: function(format) {
4902 return this.lang().weekdaysShort(this, format)
4903 },
4904 dddd: function(format) {
4905 return this.lang().weekdays(this, format)
4906 },
4907 w: function() {
4908 return this.week()
4909 },
4910 W: function() {
4911 return this.isoWeek()
4912 },
4913 YY: function() {
4914 return leftZeroFill(this.year() % 100, 2)
4915 },
4916 YYYY: function() {
4917 return leftZeroFill(this.year(), 4)
4918 },
4919 YYYYY: function() {
4920 return leftZeroFill(this.year(), 5)
4921 },
4922 a: function() {
4923 return this.lang().meridiem(this.hours(), this.minutes(), true)
4924 },
4925 A: function() {
4926 return this.lang().meridiem(this.hours(), this.minutes(), false)
4927 },
4928 H: function() {
4929 return this.hours()
4930 },
4931 h: function() {
4932 return this.hours() % 12 || 12
4933 },
4934 m: function() {
4935 return this.minutes()
4936 },
4937 s: function() {
4938 return this.seconds()
4939 },
4940 S: function() {
4941 return ~~(this.milliseconds() / 100)
4942 },
4943 SS: function() {
4944 return leftZeroFill(~~(this.milliseconds() / 10), 2)
4945 },
4946 SSS: function() {
4947 return leftZeroFill(this.milliseconds(), 3)
4948 },
4949 Z: function() {
4950 var a = -this.zone(),
4951 b = "+";
4952 if (a < 0) {
4953 a = -a;
4954 b = "-"
4955 }
4956 return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2)
4957 },
4958 ZZ: function() {
4959 var a = -this.zone(),
4960 b = "+";
4961 if (a < 0) {
4962 a = -a;
4963 b = "-"
4964 }
4965 return b + leftZeroFill(~~(10 * a / 6), 4)
4966 },
4967 X: function() {
4968 return this.unix()
4969 }
4970 };
4971
4972 function padToken(func, count) {
4973 return function(a) {
4974 return leftZeroFill(func.call(this, a), count)
4975 }
4976 }
4977
4978 function ordinalizeToken(func) {
4979 return function(a) {
4980 return this.lang().ordinal(func.call(this, a))
4981 }
4982 }
4983 while (ordinalizeTokens.length) {
4984 i = ordinalizeTokens.pop();
4985 formatTokenFunctions[i + "o"] = ordinalizeToken(formatTokenFunctions[i])
4986 }
4987 while (paddedTokens.length) {
4988 i = paddedTokens.pop();
4989 formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2)
4990 }
4991 formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
4992
4993 function Language() {}
4994
4995 function Moment(config) {
4996 extend(this, config)
4997 }
4998
4999 function Duration(duration) {
5000 var data = this._data = {},
5001 years = duration.years || duration.year || duration.y || 0,
5002 months = duration.months || duration.month || duration.M || 0,
5003 weeks = duration.weeks || duration.week || duration.w || 0,
5004 days = duration.days || duration.day || duration.d || 0,
5005 hours = duration.hours || duration.hour || duration.h || 0,
5006 minutes = duration.minutes || duration.minute || duration.m || 0,
5007 seconds = duration.seconds || duration.second || duration.s || 0,
5008 milliseconds = duration.milliseconds || duration.millisecond || duration.ms || 0;
5009 this._milliseconds = milliseconds + seconds * 1e3 + minutes * 6e4 + hours * 36e5;
5010 this._days = days + weeks * 7;
5011 this._months = months + years * 12;
5012 data.milliseconds = milliseconds % 1e3;
5013 seconds += absRound(milliseconds / 1e3);
5014 data.seconds = seconds % 60;
5015 minutes += absRound(seconds / 60);
5016 data.minutes = minutes % 60;
5017 hours += absRound(minutes / 60);
5018 data.hours = hours % 24;
5019 days += absRound(hours / 24);
5020 days += weeks * 7;
5021 data.days = days % 30;
5022 months += absRound(days / 30);
5023 data.months = months % 12;
5024 years += absRound(months / 12);
5025 data.years = years
5026 }
5027
5028 function extend(a, b) {
5029 for (var i in b) {
5030 if (b.hasOwnProperty(i)) {
5031 a[i] = b[i]
5032 }
5033 }
5034 return a
5035 }
5036
5037 function absRound(number) {
5038 if (number < 0) {
5039 return Math.ceil(number)
5040 } else {
5041 return Math.floor(number)
5042 }
5043 }
5044
5045 function leftZeroFill(number, targetLength) {
5046 var output = number + "";
5047 while (output.length < targetLength) {
5048 output = "0" + output
5049 }
5050 return output
5051 }
5052
5053 function addOrSubtractDurationFromMoment(mom, duration, isAdding) {
5054 var ms = duration._milliseconds,
5055 d = duration._days,
5056 M = duration._months,
5057 currentDate;
5058 if (ms) {
5059 mom._d.setTime(+mom + ms * isAdding)
5060 }
5061 if (d) {
5062 mom.date(mom.date() + d * isAdding)
5063 }
5064 if (M) {
5065 currentDate = mom.date();
5066 mom.date(1).month(mom.month() + M * isAdding).date(Math.min(currentDate, mom.daysInMonth()))
5067 }
5068 }
5069
5070 function isArray(input) {
5071 return Object.prototype.toString.call(input) === "[object Array]"
5072 }
5073
5074 function compareArrays(array1, array2) {
5075 var len = Math.min(array1.length, array2.length),
5076 lengthDiff = Math.abs(array1.length - array2.length),
5077 diffs = 0,
5078 i;
5079 for (i = 0; i < len; i++) {
5080 if (~~array1[i] !== ~~array2[i]) {
5081 diffs++
5082 }
5083 }
5084 return diffs + lengthDiff
5085 }
5086 Language.prototype = {
5087 set: function(config) {
5088 var prop, i;
5089 for (i in config) {
5090 prop = config[i];
5091 if (typeof prop === "function") {
5092 this[i] = prop
5093 } else {
5094 this["_" + i] = prop
5095 }
5096 }
5097 },
5098 _months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
5099 months: function(m) {
5100 return this._months[m.month()]
5101 },
5102 _monthsShort: "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
5103 monthsShort: function(m) {
5104 return this._monthsShort[m.month()]
5105 },
5106 monthsParse: function(monthName) {
5107 var i, mom, regex, output;
5108 if (!this._monthsParse) {
5109 this._monthsParse = []
5110 }
5111 for (i = 0; i < 12; i++) {
5112 if (!this._monthsParse[i]) {
5113 mom = moment([2e3, i]);
5114 regex = "^" + this.months(mom, "") + "|^" + this.monthsShort(mom, "");
5115 this._monthsParse[i] = new RegExp(regex.replace(".", ""), "i")
5116 }
5117 if (this._monthsParse[i].test(monthName)) {
5118 return i
5119 }
5120 }
5121 },
5122 _weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
5123 weekdays: function(m) {
5124 return this._weekdays[m.day()]
5125 },
5126 _weekdaysShort: "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
5127 weekdaysShort: function(m) {
5128 return this._weekdaysShort[m.day()]
5129 },
5130 _weekdaysMin: "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
5131 weekdaysMin: function(m) {
5132 return this._weekdaysMin[m.day()]
5133 },
5134 _longDateFormat: {
5135 LT: "h:mm A",
5136 L: "MM/DD/YYYY",
5137 LL: "MMMM D YYYY",
5138 LLL: "MMMM D YYYY LT",
5139 LLLL: "dddd, MMMM D YYYY LT"
5140 },
5141 longDateFormat: function(key) {
5142 var output = this._longDateFormat[key];
5143 if (!output && this._longDateFormat[key.toUpperCase()]) {
5144 output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function(val) {
5145 return val.slice(1)
5146 });
5147 this._longDateFormat[key] = output
5148 }
5149 return output
5150 },
5151 meridiem: function(hours, minutes, isLower) {
5152 if (hours > 11) {
5153 return isLower ? "pm" : "PM"
5154 } else {
5155 return isLower ? "am" : "AM"
5156 }
5157 },
5158 _calendar: {
5159 sameDay: "[Today at] LT",
5160 nextDay: "[Tomorrow at] LT",
5161 nextWeek: "dddd [at] LT",
5162 lastDay: "[Yesterday at] LT",
5163 lastWeek: "[last] dddd [at] LT",
5164 sameElse: "L"
5165 },
5166 calendar: function(key, mom) {
5167 var output = this._calendar[key];
5168 return typeof output === "function" ? output.apply(mom) : output
5169 },
5170 _relativeTime: {
5171 future: "in %s",
5172 past: "%s ago",
5173 s: "a few seconds",
5174 m: "a minute",
5175 mm: "%d minutes",
5176 h: "an hour",
5177 hh: "%d hours",
5178 d: "a day",
5179 dd: "%d days",
5180 M: "a month",
5181 MM: "%d months",
5182 y: "a year",
5183 yy: "%d years"
5184 },
5185 relativeTime: function(number, withoutSuffix, string, isFuture) {
5186 var output = this._relativeTime[string];
5187 return typeof output === "function" ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number)
5188 },
5189 pastFuture: function(diff, output) {
5190 var format = this._relativeTime[diff > 0 ? "future" : "past"];
5191 return typeof format === "function" ? format(output) : format.replace(/%s/i, output)
5192 },
5193 ordinal: function(number) {
5194 return this._ordinal.replace("%d", number)
5195 },
5196 _ordinal: "%d",
5197 preparse: function(string) {
5198 return string
5199 },
5200 postformat: function(string) {
5201 return string
5202 },
5203 week: function(mom) {
5204 return weekOfYear(mom, this._week.dow, this._week.doy)
5205 },
5206 _week: {
5207 dow: 0,
5208 doy: 6
5209 }
5210 };
5211
5212 function loadLang(key, values) {
5213 values.abbr = key;
5214 if (!languages[key]) {
5215 languages[key] = new Language
5216 }
5217 languages[key].set(values);
5218 return languages[key]
5219 }
5220
5221 function getLangDefinition(key) {
5222 if (!key) {
5223 return moment.fn._lang
5224 }
5225 if (!languages[key] && hasModule) {
5226 require("./lang/" + key)
5227 }
5228 return languages[key]
5229 }
5230
5231 function removeFormattingTokens(input) {
5232 if (input.match(/\[.*\]/)) {
5233 return input.replace(/^\[|\]$/g, "")
5234 }
5235 return input.replace(/\\/g, "")
5236 }
5237
5238 function makeFormatFunction(format) {
5239 var array = format.match(formattingTokens),
5240 i, length;
5241 for (i = 0, length = array.length; i < length; i++) {
5242 if (formatTokenFunctions[array[i]]) {
5243 array[i] = formatTokenFunctions[array[i]]
5244 } else {
5245 array[i] = removeFormattingTokens(array[i])
5246 }
5247 }
5248 return function(mom) {
5249 var output = "";
5250 for (i = 0; i < length; i++) {
5251 output += typeof array[i].call === "function" ? array[i].call(mom, format) : array[i]
5252 }
5253 return output
5254 }
5255 }
5256
5257 function formatMoment(m, format) {
5258 var i = 5;
5259
5260 function replaceLongDateFormatTokens(input) {
5261 return m.lang().longDateFormat(input) || input
5262 }
5263 while (i-- && localFormattingTokens.test(format)) {
5264 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens)
5265 }
5266 if (!formatFunctions[format]) {
5267 formatFunctions[format] = makeFormatFunction(format)
5268 }
5269 return formatFunctions[format](m)
5270 }
5271
5272 function getParseRegexForToken(token) {
5273 switch (token) {
5274 case "DDDD":
5275 return parseTokenThreeDigits;
5276 case "YYYY":
5277 return parseTokenFourDigits;
5278 case "YYYYY":
5279 return parseTokenSixDigits;
5280 case "S":
5281 case "SS":
5282 case "SSS":
5283 case "DDD":
5284 return parseTokenOneToThreeDigits;
5285 case "MMM":
5286 case "MMMM":
5287 case "dd":
5288 case "ddd":
5289 case "dddd":
5290 case "a":
5291 case "A":
5292 return parseTokenWord;
5293 case "X":
5294 return parseTokenTimestampMs;
5295 case "Z":
5296 case "ZZ":
5297 return parseTokenTimezone;
5298 case "T":
5299 return parseTokenT;
5300 case "MM":
5301 case "DD":
5302 case "YY":
5303 case "HH":
5304 case "hh":
5305 case "mm":
5306 case "ss":
5307 case "M":
5308 case "D":
5309 case "d":
5310 case "H":
5311 case "h":
5312 case "m":
5313 case "s":
5314 return parseTokenOneOrTwoDigits;
5315 default:
5316 return new RegExp(token.replace("\\", ""))
5317 }
5318 }
5319
5320 function addTimeToArrayFromToken(token, input, config) {
5321 var a, b, datePartArray = config._a;
5322 switch (token) {
5323 case "M":
5324 case "MM":
5325 datePartArray[1] = input == null ? 0 : ~~input - 1;
5326 break;
5327 case "MMM":
5328 case "MMMM":
5329 a = getLangDefinition(config._l).monthsParse(input);
5330 if (a != null) {
5331 datePartArray[1] = a
5332 } else {
5333 config._isValid = false
5334 }
5335 break;
5336 case "D":
5337 case "DD":
5338 case "DDD":
5339 case "DDDD":
5340 if (input != null) {
5341 datePartArray[2] = ~~input
5342 }
5343 break;
5344 case "YY":
5345 datePartArray[0] = ~~input + (~~input > 68 ? 1900 : 2e3);
5346 break;
5347 case "YYYY":
5348 case "YYYYY":
5349 datePartArray[0] = ~~input;
5350 break;
5351 case "a":
5352 case "A":
5353 config._isPm = (input + "").toLowerCase() === "pm";
5354 break;
5355 case "H":
5356 case "HH":
5357 case "h":
5358 case "hh":
5359 datePartArray[3] = ~~input;
5360 break;
5361 case "m":
5362 case "mm":
5363 datePartArray[4] = ~~input;
5364 break;
5365 case "s":
5366 case "ss":
5367 datePartArray[5] = ~~input;
5368 break;
5369 case "S":
5370 case "SS":
5371 case "SSS":
5372 datePartArray[6] = ~~(("0." + input) * 1e3);
5373 break;
5374 case "X":
5375 config._d = new Date(parseFloat(input) * 1e3);
5376 break;
5377 case "Z":
5378 case "ZZ":
5379 config._useUTC = true;
5380 a = (input + "").match(parseTimezoneChunker);
5381 if (a && a[1]) {
5382 config._tzh = ~~a[1]
5383 }
5384 if (a && a[2]) {
5385 config._tzm = ~~a[2]
5386 }
5387 if (a && a[0] === "+") {
5388 config._tzh = -config._tzh;
5389 config._tzm = -config._tzm
5390 }
5391 break
5392 }
5393 if (input == null) {
5394 config._isValid = false
5395 }
5396 }
5397
5398 function dateFromArray(config) {
5399 var i, date, input = [];
5400 if (config._d) {
5401 return
5402 }
5403 for (i = 0; i < 7; i++) {
5404 config._a[i] = input[i] = config._a[i] == null ? i === 2 ? 1 : 0 : config._a[i]
5405 }
5406 input[3] += config._tzh || 0;
5407 input[4] += config._tzm || 0;
5408 date = new Date(0);
5409 if (config._useUTC) {
5410 date.setUTCFullYear(input[0], input[1], input[2]);
5411 date.setUTCHours(input[3], input[4], input[5], input[6])
5412 } else {
5413 date.setFullYear(input[0], input[1], input[2]);
5414 date.setHours(input[3], input[4], input[5], input[6])
5415 }
5416 config._d = date
5417 }
5418
5419 function makeDateFromStringAndFormat(config) {
5420 var tokens = config._f.match(formattingTokens),
5421 string = config._i,
5422 i, parsedInput;
5423 config._a = [];
5424 for (i = 0; i < tokens.length; i++) {
5425 parsedInput = (getParseRegexForToken(tokens[i]).exec(string) || [])[0];
5426 if (parsedInput) {
5427 string = string.slice(string.indexOf(parsedInput) + parsedInput.length)
5428 }
5429 if (formatTokenFunctions[tokens[i]]) {
5430 addTimeToArrayFromToken(tokens[i], parsedInput, config)
5431 }
5432 }
5433 if (config._isPm && config._a[3] < 12) {
5434 config._a[3] += 12
5435 }
5436 if (config._isPm === false && config._a[3] === 12) {
5437 config._a[3] = 0
5438 }
5439 dateFromArray(config)
5440 }
5441
5442 function makeDateFromStringAndArray(config) {
5443 var tempConfig, tempMoment, bestMoment, scoreToBeat = 99,
5444 i, currentDate, currentScore;
5445 while (config._f.length) {
5446 tempConfig = extend({}, config);
5447 tempConfig._f = config._f.pop();
5448 makeDateFromStringAndFormat(tempConfig);
5449 tempMoment = new Moment(tempConfig);
5450 if (tempMoment.isValid()) {
5451 bestMoment = tempMoment;
5452 break
5453 }
5454 currentScore = compareArrays(tempConfig._a, tempMoment.toArray());
5455 if (currentScore < scoreToBeat) {
5456 scoreToBeat = currentScore;
5457 bestMoment = tempMoment
5458 }
5459 }
5460 extend(config, bestMoment)
5461 }
5462
5463 function makeDateFromString(config) {
5464 var i, string = config._i;
5465 if (isoRegex.exec(string)) {
5466 config._f = "YYYY-MM-DDT";
5467 for (i = 0; i < 4; i++) {
5468 if (isoTimes[i][1].exec(string)) {
5469 config._f += isoTimes[i][0];
5470 break
5471 }
5472 }
5473 if (parseTokenTimezone.exec(string)) {
5474 config._f += " Z"
5475 }
5476 makeDateFromStringAndFormat(config)
5477 } else {
5478 config._d = new Date(string)
5479 }
5480 }
5481
5482 function makeDateFromInput(config) {
5483 var input = config._i,
5484 matched = aspNetJsonRegex.exec(input);
5485 if (input === undefined) {
5486 config._d = new Date
5487 } else if (matched) {
5488 config._d = new Date(+matched[1])
5489 } else if (typeof input === "string") {
5490 makeDateFromString(config)
5491 } else if (isArray(input)) {
5492 config._a = input.slice(0);
5493 dateFromArray(config)
5494 } else {
5495 config._d = input instanceof Date ? new Date(+input) : new Date(input)
5496 }
5497 }
5498
5499 function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
5500 return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture)
5501 }
5502
5503 function relativeTime(milliseconds, withoutSuffix, lang) {
5504 var seconds = round(Math.abs(milliseconds) / 1e3),
5505 minutes = round(seconds / 60),
5506 hours = round(minutes / 60),
5507 days = round(hours / 24),
5508 years = round(days / 365),
5509 args = seconds < 45 && ["s", seconds] || minutes === 1 && ["m"] || minutes < 45 && ["mm", minutes] || hours === 1 && ["h"] || hours < 22 && ["hh", hours] || days === 1 && ["d"] || days <= 25 && ["dd", days] || days <= 45 && ["M"] || days < 345 && ["MM", round(days / 30)] || years === 1 && ["y"] || ["yy", years];
5510 args[2] = withoutSuffix;
5511 args[3] = milliseconds > 0;
5512 args[4] = lang;
5513 return substituteTimeAgo.apply({}, args)
5514 }
5515
5516 function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
5517 var end = firstDayOfWeekOfYear - firstDayOfWeek,
5518 daysToDayOfWeek = firstDayOfWeekOfYear - mom.day();
5519 if (daysToDayOfWeek > end) {
5520 daysToDayOfWeek -= 7
5521 }
5522 if (daysToDayOfWeek < end - 7) {
5523 daysToDayOfWeek += 7
5524 }
5525 return Math.ceil(moment(mom).add("d", daysToDayOfWeek).dayOfYear() / 7)
5526 }
5527
5528 function makeMoment(config) {
5529 var input = config._i,
5530 format = config._f;
5531 if (input === null || input === "") {
5532 return null
5533 }
5534 if (typeof input === "string") {
5535 config._i = input = getLangDefinition().preparse(input)
5536 }
5537 if (moment.isMoment(input)) {
5538 config = extend({}, input);
5539 config._d = new Date(+input._d)
5540 } else if (format) {
5541 if (isArray(format)) {
5542 makeDateFromStringAndArray(config)
5543 } else {
5544 makeDateFromStringAndFormat(config)
5545 }
5546 } else {
5547 makeDateFromInput(config)
5548 }
5549 return new Moment(config)
5550 }
5551 moment = function(input, format, lang) {
5552 return makeMoment({
5553 _i: input,
5554 _f: format,
5555 _l: lang,
5556 _isUTC: false
5557 })
5558 };
5559 moment.utc = function(input, format, lang) {
5560 return makeMoment({
5561 _useUTC: true,
5562 _isUTC: true,
5563 _l: lang,
5564 _i: input,
5565 _f: format
5566 })
5567 };
5568 moment.unix = function(input) {
5569 return moment(input * 1e3)
5570 };
5571 moment.duration = function(input, key) {
5572 var isDuration = moment.isDuration(input),
5573 isNumber = typeof input === "number",
5574 duration = isDuration ? input._data : isNumber ? {} : input,
5575 ret;
5576 if (isNumber) {
5577 if (key) {
5578 duration[key] = input
5579 } else {
5580 duration.milliseconds = input
5581 }
5582 }
5583 ret = new Duration(duration);
5584 if (isDuration && input.hasOwnProperty("_lang")) {
5585 ret._lang = input._lang
5586 }
5587 return ret
5588 };
5589 moment.version = VERSION;
5590 moment.defaultFormat = isoFormat;
5591 moment.lang = function(key, values) {
5592 var i;
5593 if (!key) {
5594 return moment.fn._lang._abbr
5595 }
5596 if (values) {
5597 loadLang(key, values)
5598 } else if (!languages[key]) {
5599 getLangDefinition(key)
5600 }
5601 moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key)
5602 };
5603 moment.langData = function(key) {
5604 if (key && key._lang && key._lang._abbr) {
5605 key = key._lang._abbr
5606 }
5607 return getLangDefinition(key)
5608 };
5609 moment.isMoment = function(obj) {
5610 return obj instanceof Moment
5611 };
5612 moment.isDuration = function(obj) {
5613 return obj instanceof Duration
5614 };
5615 moment.fn = Moment.prototype = {
5616 clone: function() {
5617 return moment(this)
5618 },
5619 valueOf: function() {
5620 return +this._d
5621 },
5622 unix: function() {
5623 return Math.floor(+this._d / 1e3)
5624 },
5625 toString: function() {
5626 return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")
5627 },
5628 toDate: function() {
5629 return this._d
5630 },
5631 toJSON: function() {
5632 return moment.utc(this).format("YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")
5633 },
5634 toArray: function() {
5635 var m = this;
5636 return [m.year(), m.month(), m.date(), m.hours(), m.minutes(), m.seconds(), m.milliseconds()]
5637 },
5638 isValid: function() {
5639 if (this._isValid == null) {
5640 if (this._a) {
5641 this._isValid = !compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray())
5642 } else {
5643 this._isValid = !isNaN(this._d.getTime())
5644 }
5645 }
5646 return !!this._isValid
5647 },
5648 utc: function() {
5649 this._isUTC = true;
5650 return this
5651 },
5652 local: function() {
5653 this._isUTC = false;
5654 return this
5655 },
5656 format: function(inputString) {
5657 var output = formatMoment(this, inputString || moment.defaultFormat);
5658 return this.lang().postformat(output)
5659 },
5660 add: function(input, val) {
5661 var dur;
5662 if (typeof input === "string") {
5663 dur = moment.duration(+val, input)
5664 } else {
5665 dur = moment.duration(input, val)
5666 }
5667 addOrSubtractDurationFromMoment(this, dur, 1);
5668 return this
5669 },
5670 subtract: function(input, val) {
5671 var dur;
5672 if (typeof input === "string") {
5673 dur = moment.duration(+val, input)
5674 } else {
5675 dur = moment.duration(input, val)
5676 }
5677 addOrSubtractDurationFromMoment(this, dur, -1);
5678 return this
5679 },
5680 diff: function(input, units, asFloat) {
5681 var that = this._isUTC ? moment(input).utc() : moment(input).local(),
5682 zoneDiff = (this.zone() - that.zone()) * 6e4,
5683 diff, output;
5684 if (units) {
5685 units = units.replace(/s$/, "")
5686 }
5687 if (units === "year" || units === "month") {
5688 diff = (this.daysInMonth() + that.daysInMonth()) * 432e5;
5689 output = (this.year() - that.year()) * 12 + (this.month() - that.month());
5690 output += (this - moment(this).startOf("month") - (that - moment(that).startOf("month"))) / diff;
5691 if (units === "year") {
5692 output = output / 12
5693 }
5694 } else {
5695 diff = this - that - zoneDiff;
5696 output = units === "second" ? diff / 1e3 : units === "minute" ? diff / 6e4 : units === "hour" ? diff / 36e5 : units === "day" ? diff / 864e5 : units === "week" ? diff / 6048e5 : diff
5697 }
5698 return asFloat ? output : absRound(output)
5699 },
5700 from: function(time, withoutSuffix) {
5701 return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix)
5702 },
5703 fromNow: function(withoutSuffix) {
5704 return this.from(moment(), withoutSuffix)
5705 },
5706 calendar: function() {
5707 var diff = this.diff(moment().startOf("day"), "days", true),
5708 format = diff < -6 ? "sameElse" : diff < -1 ? "lastWeek" : diff < 0 ? "lastDay" : diff < 1 ? "sameDay" : diff < 2 ? "nextDay" : diff < 7 ? "nextWeek" : "sameElse";
5709 return this.format(this.lang().calendar(format, this))
5710 },
5711 isLeapYear: function() {
5712 var year = this.year();
5713 return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0
5714 },
5715 isDST: function() {
5716 return this.zone() < moment([this.year()]).zone() || this.zone() < moment([this.year(), 5]).zone()
5717 },
5718 day: function(input) {
5719 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
5720 return input == null ? day : this.add({
5721 d: input - day
5722 })
5723 },
5724 startOf: function(units) {
5725 units = units.replace(/s$/, "");
5726 switch (units) {
5727 case "year":
5728 this.month(0);
5729 case "month":
5730 this.date(1);
5731 case "week":
5732 case "day":
5733 this.hours(0);
5734 case "hour":
5735 this.minutes(0);
5736 case "minute":
5737 this.seconds(0);
5738 case "second":
5739 this.milliseconds(0)
5740 }
5741 if (units === "week") {
5742 this.day(0)
5743 }
5744 return this
5745 },
5746 endOf: function(units) {
5747 return this.startOf(units).add(units.replace(/s?$/, "s"), 1).subtract("ms", 1)
5748 },
5749 isAfter: function(input, units) {
5750 units = typeof units !== "undefined" ? units : "millisecond";
5751 return +this.clone().startOf(units) > +moment(input).startOf(units)
5752 },
5753 isBefore: function(input, units) {
5754 units = typeof units !== "undefined" ? units : "millisecond";
5755 return +this.clone().startOf(units) < +moment(input).startOf(units)
5756 },
5757 isSame: function(input, units) {
5758 units = typeof units !== "undefined" ? units : "millisecond";
5759 return +this.clone().startOf(units) === +moment(input).startOf(units)
5760 },
5761 zone: function() {
5762 return this._isUTC ? 0 : this._d.getTimezoneOffset()
5763 },
5764 daysInMonth: function() {
5765 return moment.utc([this.year(), this.month() + 1, 0]).date()
5766 },
5767 dayOfYear: function(input) {
5768 var dayOfYear = round((moment(this).startOf("day") - moment(this).startOf("year")) / 864e5) + 1;
5769 return input == null ? dayOfYear : this.add("d", input - dayOfYear)
5770 },
5771 isoWeek: function(input) {
5772 var week = weekOfYear(this, 1, 4);
5773 return input == null ? week : this.add("d", (input - week) * 7)
5774 },
5775 week: function(input) {
5776 var week = this.lang().week(this);
5777 return input == null ? week : this.add("d", (input - week) * 7)
5778 },
5779 lang: function(key) {
5780 if (key === undefined) {
5781 return this._lang
5782 } else {
5783 this._lang = getLangDefinition(key);
5784 return this
5785 }
5786 }
5787 };
5788
5789 function makeGetterAndSetter(name, key) {
5790 moment.fn[name] = moment.fn[name + "s"] = function(input) {
5791 var utc = this._isUTC ? "UTC" : "";
5792 if (input != null) {
5793 this._d["set" + utc + key](input);
5794 return this
5795 } else {
5796 return this._d["get" + utc + key]()
5797 }
5798 }
5799 }
5800 for (i = 0; i < proxyGettersAndSetters.length; i++) {
5801 makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ""), proxyGettersAndSetters[i])
5802 }
5803 makeGetterAndSetter("year", "FullYear");
5804 moment.fn.days = moment.fn.day;
5805 moment.fn.weeks = moment.fn.week;
5806 moment.fn.isoWeeks = moment.fn.isoWeek;
5807 moment.duration.fn = Duration.prototype = {
5808 weeks: function() {
5809 return absRound(this.days() / 7)
5810 },
5811 valueOf: function() {
5812 return this._milliseconds + this._days * 864e5 + this._months * 2592e6
5813 },
5814 humanize: function(withSuffix) {
5815 var difference = +this,
5816 output = relativeTime(difference, !withSuffix, this.lang());
5817 if (withSuffix) {
5818 output = this.lang().pastFuture(difference, output)
5819 }
5820 return this.lang().postformat(output)
5821 },
5822 lang: moment.fn.lang
5823 };
5824
5825 function makeDurationGetter(name) {
5826 moment.duration.fn[name] = function() {
5827 return this._data[name]
5828 }
5829 }
5830
5831 function makeDurationAsGetter(name, factor) {
5832 moment.duration.fn["as" + name] = function() {
5833 return +this / factor
5834 }
5835 }
5836 for (i in unitMillisecondFactors) {
5837 if (unitMillisecondFactors.hasOwnProperty(i)) {
5838 makeDurationAsGetter(i, unitMillisecondFactors[i]);
5839 makeDurationGetter(i.toLowerCase())
5840 }
5841 }
5842 makeDurationAsGetter("Weeks", 6048e5);
5843 moment.lang("en", {
5844 ordinal: function(number) {
5845 var b = number % 10,
5846 output = ~~(number % 100 / 10) === 1 ? "th" : b === 1 ? "st" : b === 2 ? "nd" : b === 3 ? "rd" : "th";
5847 return number + output
5848 }
5849 });
5850 if (hasModule) {
5851 module.exports = moment
5852 }
5853 if (typeof ender === "undefined") {
5854 this["moment"] = moment
5855 }
5856 if (typeof define === "function" && define.amd) {
5857 define("moment", [], function() {
5858 return moment
5859 })
5860 }
5861 }).call(this)
5862 }, {}],
5863 8: [function(require, module, exports) {
5864 var CryptoJS = function(h, s) {
5865 var f = {},
5866 t = f.lib = {},
5867 g = function() {},
5868 j = t.Base = {
5869 extend: function(a) {
5870 g.prototype = this;
5871 var c = new g;
5872 a && c.mixIn(a);
5873 c.hasOwnProperty("init") || (c.init = function() {
5874 c.$super.init.apply(this, arguments)
5875 });
5876 c.init.prototype = c;
5877 c.$super = this;
5878 return c
5879 },
5880 create: function() {
5881 var a = this.extend();
5882 a.init.apply(a, arguments);
5883 return a
5884 },
5885 init: function() {},
5886 mixIn: function(a) {
5887 for (var c in a) a.hasOwnProperty(c) && (this[c] = a[c]);
5888 a.hasOwnProperty("toString") && (this.toString = a.toString)
5889 },
5890 clone: function() {
5891 return this.init.prototype.extend(this)
5892 }
5893 },
5894 q = t.WordArray = j.extend({
5895 init: function(a, c) {
5896 a = this.words = a || [];
5897 this.sigBytes = c != s ? c : 4 * a.length
5898 },
5899 toString: function(a) {
5900 return (a || u).stringify(this)
5901 },
5902 concat: function(a) {
5903 var c = this.words,
5904 d = a.words,
5905 b = this.sigBytes;
5906 a = a.sigBytes;
5907 this.clamp();
5908 if (b % 4)
5909 for (var e = 0; e < a; e++) c[b + e >>> 2] |= (d[e >>> 2] >>> 24 - 8 * (e % 4) & 255) << 24 - 8 * ((b + e) % 4);
5910 else if (65535 < d.length)
5911 for (e = 0; e < a; e += 4) c[b + e >>> 2] = d[e >>> 2];
5912 else c.push.apply(c, d);
5913 this.sigBytes += a;
5914 return this
5915 },
5916 clamp: function() {
5917 var a = this.words,
5918 c = this.sigBytes;
5919 a[c >>> 2] &= 4294967295 << 32 - 8 * (c % 4);
5920 a.length = h.ceil(c / 4)
5921 },
5922 clone: function() {
5923 var a = j.clone.call(this);
5924 a.words = this.words.slice(0);
5925 return a
5926 },
5927 random: function(a) {
5928 for (var c = [], d = 0; d < a; d += 4) c.push(4294967296 * h.random() | 0);
5929 return new q.init(c, a)
5930 }
5931 }),
5932 v = f.enc = {},
5933 u = v.Hex = {
5934 stringify: function(a) {
5935 var c = a.words;
5936 a = a.sigBytes;
5937 for (var d = [], b = 0; b < a; b++) {
5938 var e = c[b >>> 2] >>> 24 - 8 * (b % 4) & 255;
5939 d.push((e >>> 4).toString(16));
5940 d.push((e & 15).toString(16))
5941 }
5942 return d.join("")
5943 },
5944 parse: function(a) {
5945 for (var c = a.length, d = [], b = 0; b < c; b += 2) d[b >>> 3] |= parseInt(a.substr(b, 2), 16) << 24 - 4 * (b % 8);
5946 return new q.init(d, c / 2)
5947 }
5948 },
5949 k = v.Latin1 = {
5950 stringify: function(a) {
5951 var c = a.words;
5952 a = a.sigBytes;
5953 for (var d = [], b = 0; b < a; b++) d.push(String.fromCharCode(c[b >>> 2] >>> 24 - 8 * (b % 4) & 255));
5954 return d.join("")
5955 },
5956 parse: function(a) {
5957 for (var c = a.length, d = [], b = 0; b < c; b++) d[b >>> 2] |= (a.charCodeAt(b) & 255) << 24 - 8 * (b % 4);
5958 return new q.init(d, c)
5959 }
5960 },
5961 l = v.Utf8 = {
5962 stringify: function(a) {
5963 try {
5964 return decodeURIComponent(escape(k.stringify(a)))
5965 } catch (c) {
5966 throw Error("Malformed UTF-8 data")
5967 }
5968 },
5969 parse: function(a) {
5970 return k.parse(unescape(encodeURIComponent(a)))
5971 }
5972 },
5973 x = t.BufferedBlockAlgorithm = j.extend({
5974 reset: function() {
5975 this._data = new q.init;
5976 this._nDataBytes = 0
5977 },
5978 _append: function(a) {
5979 "string" == typeof a && (a = l.parse(a));
5980 this._data.concat(a);
5981 this._nDataBytes += a.sigBytes
5982 },
5983 _process: function(a) {
5984 var c = this._data,
5985 d = c.words,
5986 b = c.sigBytes,
5987 e = this.blockSize,
5988 f = b / (4 * e),
5989 f = a ? h.ceil(f) : h.max((f | 0) - this._minBufferSize, 0);
5990 a = f * e;
5991 b = h.min(4 * a, b);
5992 if (a) {
5993 for (var m = 0; m < a; m += e) this._doProcessBlock(d, m);
5994 m = d.splice(0, a);
5995 c.sigBytes -= b
5996 }
5997 return new q.init(m, b)
5998 },
5999 clone: function() {
6000 var a = j.clone.call(this);
6001 a._data = this._data.clone();
6002 return a
6003 },
6004 _minBufferSize: 0
6005 });
6006 t.Hasher = x.extend({
6007 cfg: j.extend(),
6008 init: function(a) {
6009 this.cfg = this.cfg.extend(a);
6010 this.reset()
6011 },
6012 reset: function() {
6013 x.reset.call(this);
6014 this._doReset()
6015 },
6016 update: function(a) {
6017 this._append(a);
6018 this._process();
6019 return this
6020 },
6021 finalize: function(a) {
6022 a && this._append(a);
6023 return this._doFinalize()
6024 },
6025 blockSize: 16,
6026 _createHelper: function(a) {
6027 return function(c, d) {
6028 return new a.init(d).finalize(c)
6029 }
6030 },
6031 _createHmacHelper: function(a) {
6032 return function(c, d) {
6033 return new w.HMAC.init(a, d).finalize(c)
6034 }
6035 }
6036 });
6037 var w = f.algo = {};
6038 return f
6039 }(Math);
6040 (function(h) {
6041 for (var s = CryptoJS, f = s.lib, t = f.WordArray, g = f.Hasher, f = s.algo, j = [], q = [], v = function(a) {
6042 return 4294967296 * (a - (a | 0)) | 0
6043 }, u = 2, k = 0; 64 > k;) {
6044 var l;
6045 a: {
6046 l = u;
6047 for (var x = h.sqrt(l), w = 2; w <= x; w++)
6048 if (!(l % w)) {
6049 l = !1;
6050 break a
6051 } l = !0
6052 }
6053 l && (8 > k && (j[k] = v(h.pow(u, .5))), q[k] = v(h.pow(u, 1 / 3)), k++);
6054 u++
6055 }
6056 var a = [],
6057 f = f.SHA256 = g.extend({
6058 _doReset: function() {
6059 this._hash = new t.init(j.slice(0))
6060 },
6061 _doProcessBlock: function(c, d) {
6062 for (var b = this._hash.words, e = b[0], f = b[1], m = b[2], h = b[3], p = b[4], j = b[5], k = b[6], l = b[7], n = 0; 64 > n; n++) {
6063 if (16 > n) a[n] = c[d + n] | 0;
6064 else {
6065 var r = a[n - 15],
6066 g = a[n - 2];
6067 a[n] = ((r << 25 | r >>> 7) ^ (r << 14 | r >>> 18) ^ r >>> 3) + a[n - 7] + ((g << 15 | g >>> 17) ^ (g << 13 | g >>> 19) ^ g >>> 10) + a[n - 16]
6068 }
6069 r = l + ((p << 26 | p >>> 6) ^ (p << 21 | p >>> 11) ^ (p << 7 | p >>> 25)) + (p & j ^ ~p & k) + q[n] + a[n];
6070 g = ((e << 30 | e >>> 2) ^ (e << 19 | e >>> 13) ^ (e << 10 | e >>> 22)) + (e & f ^ e & m ^ f & m);
6071 l = k;
6072 k = j;
6073 j = p;
6074 p = h + r | 0;
6075 h = m;
6076 m = f;
6077 f = e;
6078 e = r + g | 0
6079 }
6080 b[0] = b[0] + e | 0;
6081 b[1] = b[1] + f | 0;
6082 b[2] = b[2] + m | 0;
6083 b[3] = b[3] + h | 0;
6084 b[4] = b[4] + p | 0;
6085 b[5] = b[5] + j | 0;
6086 b[6] = b[6] + k | 0;
6087 b[7] = b[7] + l | 0
6088 },
6089 _doFinalize: function() {
6090 var a = this._data,
6091 d = a.words,
6092 b = 8 * this._nDataBytes,
6093 e = 8 * a.sigBytes;
6094 d[e >>> 5] |= 128 << 24 - e % 32;
6095 d[(e + 64 >>> 9 << 4) + 14] = h.floor(b / 4294967296);
6096 d[(e + 64 >>> 9 << 4) + 15] = b;
6097 a.sigBytes = 4 * d.length;
6098 this._process();
6099 return this._hash
6100 },
6101 clone: function() {
6102 var a = g.clone.call(this);
6103 a._hash = this._hash.clone();
6104 return a
6105 }
6106 });
6107 s.SHA256 = g._createHelper(f);
6108 s.HmacSHA256 = g._createHmacHelper(f)
6109 })(Math);
6110 module.exports = CryptoJS
6111 }, {}]
6112}, {}, [2]);