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