PageSourceSearch

https://www.radicalmedia.com/js/egg.js?ts=

js radicalmedia.com collected 2026-10-02 02:45:05 UTC 41,970 bytes, 1,823 lines download raw bytes

1;(function(scope,document,$){
2
3	var keys = {
4		A : 65, B : 66, C : 67, D : 68,
5		E : 69, F : 70, G : 71, H : 72,
6		I : 73, J : 74, K : 75, L : 76,
7		M : 77, N : 78, O : 79, P : 80,
8		Q : 81, R : 82, S : 83, T : 84,
9		U : 85, V : 86, W : 87, X : 88,
10		Y : 89, Z : 90,
11
12		// ooooops we need that huh
13		'`' : 192
14	},
15	// store many eggs
16	hatchery = [],
17	// expose various methods to window so our egg friends can acccess them
18	egg = {},
19
20	/**
21	 * these are for local references to these commonly used libs
22	 * stored in this scope after the egg.init event occurs
23	 */
24	jqr, def, req;
25
26	function s(test) {
27		var a = [];
28		for(var i = 0; i < test.length; i++) {
29			a.push( keys[ test.charAt(i).toUpperCase() ]);
30		}
31		return a.join('');
32	}
33
34	function getDefaultOptions(options) {
35		var opt = {
36			visible : true
37			// etc
38		};
39		for(var i in opt) {
40			if (options && typeof options === "object" && options.hasOwnProperty(i)) {
41				opt[i] = options[i];
42			}
43		}
44		return opt;
45	}
46
47	/**
48	 * check if an egg is present
49	 *
50	 * @return bool
51	 */
52	egg.exists = function(string) {
53		for(var i = 0; i < hatchery.length; i++) {
54			test = hatchery[i];
55			if (test.name === string) {
56				return true;
57			}
58		}
59		return false;
60	};
61
62	/**
63	 * get list of egg names ('commands')
64	 *
65	 * @return array
66	 */
67	egg.list = function() {
68		var commands = [];
69		for(var i = 0; i < hatchery.length; i++){
70			if (hatchery[i].visible) {
71				commands.push(hatchery[i].name);
72			}
73		}
74		return commands;
75	};
76
77	/**
78	 * multi eggs are run the first time the trigger occurs
79	 */
80	egg.single = function(str, funct, options) {
81		options = getDefaultOptions(options);
82		hatchery.push({
83			trigger : s(str),
84			name : str,
85			triggered : false,
86			multiple : false,
87			now : false,
88			run : funct,
89			visible : options.visible
90		});
91	};
92
93	/**
94	 * multi eggs are run each time the trigger occurs
95	 *
96	 * @void
97	 */
98	egg.multi = function(str, funct, options) {
99		options = getDefaultOptions(options);
100		hatchery.push({
101			trigger : s(str),
102			name : str,
103			triggered : false,
104			multiple : true,
105			now : false,
106			run : funct,
107			visible : options.visible
108		});
109	};
110
111	/**
112	 * now eggs are run once the initial unlock happens, meaning they can define
113	 * their own conditions etc
114	 *
115	 * @void
116	 */
117	egg.now = function(funct) {
118		hatchery.push({
119			trigger : false,
120			name : false,
121			triggered : false,
122			multiple : false,
123			now : true,
124			run : funct
125		});
126	};
127
128	/*
129	egg.add = function() {
130		hatchery.push({
131			trigger : false,
132			name : false,
133			triggered : false,
134			multiple : false,
135			now : true,
136			run : funct
137		});
138	}
139	*/
140
141	/**
142	 * run an egg by name
143	 */
144	egg.run = function(name) {
145		for(var i = 0; i < hatchery.length; i++) {
146			currentEgg = hatchery[i];
147			if (currentEgg.now !== true && (currentEgg.triggered === false || currentEgg.multiple === true) && currentEgg.name === name) {
148				currentEgg.run(jqr, req, def);
149				currentEgg.triggered = true;
150			}
151		}
152	};
153
154	// this event will be fired after the egg source is loaded and ready
155	$(document).on('egg.init', function(eve, jQuery, require, define) {
156
157		jqr = jQuery;
158		req = require;
159		def = define;
160
161		for(var i = 0; i < hatchery.length; i++) {
162			currentEgg = hatchery[i];
163			if (currentEgg.now === true && currentEgg.triggered === false) {
164				currentEgg.run(jqr, req, def);
165				currentEgg.triggered = true;
166			}
167		}
168
169		// add a module in case we need to mess with egg within an egg 0_o
170		// i know i know, just trust me on this one, it will happen
171		define('egg',[],function(){
172			return egg;
173		});
174
175	});
176
177	// this event is fired on each typing timeout
178	$(document).on('egg.run', function(eve, egg, jQuery, require, define) {
179
180		for(var i = 0; i < hatchery.length; i++) {
181			currentEgg = hatchery[i];
182			// matched, and not run or can run again
183			if (currentEgg.trigger == egg && (!currentEgg.triggered || currentEgg.multiple)) {
184				currentEgg.run(jqr, req, def);
185				currentEgg.triggered = true;
186			}
187		}
188
189	});
190
191	// expose these to our outer scope (window)
192	scope.egg = egg;
193
194})(this,document,jQuery);
195
196/**
197 * Bouncy Ball
198 */
199egg.single('bouncy',function($, require, define){
200
201	require(['radical/component/console'],function(logger){
202
203		var msRate = 1000 / 60;
204		var objs = [];
205		var bounds = {
206			top : 0,
207			right : $(window).width(),
208			bottom : $(window).height(),
209			left : 0
210		};
211		var terminalVelocity = 100;
212
213		function randomColor() {
214			// return randomColorRBGA();
215			return randomColorHEX();
216		}
217
218		function randomColorRBGA() {
219			return 'rgba(' + [
220				Math.floor(Math.random() * 255),
221				Math.floor(Math.random() * 255),
222				Math.floor(Math.random() * 255),
223				Math.random()
224			].join(',') + ')';
225		}
226
227		function randomColorHEX() {
228			var c = "0123456789abcdef";
229			var s = "";
230			while (s.length < 6)
231				s += c.charAt(Math.floor(Math.random() * c.length));
232			return "#" + s;
233		}
234
235		function getObject(xPos,yPos,object,options) {
236			options = options || {};
237			var obj = {
238				$object : $(object),
239				w : options.width,
240				h : options.height,
241				x : xPos,
242				y : yPos,
243				xLast : xPos,
244				yLast : yPos,
245				xVel : options.hasOwnProperty('xVel') ? options.xVel : (Math.random() * 200 - 100),
246				yVel : options.hasOwnProperty('yVel') ? options.yVel : 0,
247				isMoving : true,
248				rotation : 0,
249				rotationSpeed : options.hasOwnProperty('rotationSpeed') ? options.hasOwnProperty('rotationSpeed') : 0,
250				friction : 0.99, // 0-1
251				gravity : 0.8, // ? small #
252				recalculateScale : function() {
253					this.w = this.$object.width();
254					this.h = this.$object.height();
255				},
256				bounds : function() {
257					return {
258						top : this.y - (this.h / 2),
259						right : this.x + (this.w / 2),
260						bottom : this.y + (this.h / 2),
261						left : this.x - (this.w / 2)
262					};
263				},
264				update : function() {
265
266					// no calculations on stationary balls
267					if (!this.isMoving) {
268						return;
269					}
270
271					if (this.friction) {
272						this.xVel *= this.friction;
273						this.yVel *= this.friction;
274					}
275
276					if (this.gravity) {
277						this.yVel += this.gravity;
278					}
279
280					if (Math.abs(this.xVel) < 0.5) {
281						this.xVel = 0;
282					}
283
284					if (Math.abs(this.yVel) < 0.5) {
285						this.yVel = 0;
286					}
287
288					// process movement
289					this.x += this.xVel;
290					this.y += this.yVel;
291
292					// this has to happen after the x/y move ^
293					var meBounds = this.bounds();
294
295					// handle bounds
296					if (meBounds.right > bounds.right) {
297						this.x = bounds.right - (this.w / 2);
298						this.xVel *= -1;
299					}
300					else if (meBounds.left < bounds.left) {
301						this.x = bounds.left + (this.w / 2);
302						this.xVel *= -1;
303					}
304					// check bottom bounds
305					if (meBounds.bottom >
305 bounds.bottom) {
306						this.y = bounds.bottom - (this.h / 2);
307						this.yVel *= -1;
308					}
309
310					// handle "terminalVelocity" type thing
311					if (this.xVel > terminalVelocity) {
312						this.xVel = terminalVelocity;
313					}
314					else if (this.xVel < -terminalVelocity) {
315						this.xVel = -terminalVelocity;
316					}
317
318					if (this.yVel > terminalVelocity) {
319						this.yVel = terminalVelocity;
320					}
321					else if (this.yVel < -terminalVelocity) {
322						this.yVel = -terminalVelocity;
323					}
324
325					if (this.rotationSpeed) {
326						this.rotation += this.rotationSpeed;
327					}
328
329					if (this.x != this.xLast || this.y != this.yLast) {
330
331						var posX = Math.floor(this.x - (this.w / 2));
332						var posY = Math.floor(this.y - (this.h / 2));
333
334						this.$object.css({
335							left      : posX + 'px',
336							top       : posY + 'px',
337							transform : 'rotate(' + this.rotation + 'deg)'
338						});
339						this.lastMoved = new Date().getTime();
340
341						this.xLast = this.x;
342						this.yLast = this.y;
343
344					}
345
346					/// are we moving at all (and on the bottom edge) ?
347					if (this.xVel === 0 && this.yVel === 0 && meBounds.bottom >= bounds.bottom) {
348						this.isMoving = false;
349					}
350
351					return this;
352				}
353			};
354
355			obj.update();
356
357			return obj;
358		}
359
360		function getBall(xPos, yPos, diameter, options) {
361			options = options || {};
362			options.width = diameter;
363			options.height = diameter;
364			return getObject(
365				xPos,
366				yPos,
367				$("<div>").css({
368					display : 'block',
369					position: 'absolute',
370					top : '-10000px',
371					left : '-10000px',
372					'border-radius' : '100%',
373					'background-color' : randomColor(), // 'red',
374					'z-index' : 1000000,
375					width : diameter + 'px',
376					height : diameter + 'px'
377				}).appendTo('body'),
378				options
379			);
380		}
381
382		function getAndConvertRandomElement() {
383
384			var $things = $("h1,h2,h3,h4,h5,h6,p,a,input,button").not('.already-duped, .dupe');
385
386			if ($things.length === 0) {
387				return false;
388			}
389
390			var $me = $things.first();
391			var $dupe = $me.clone().addClass('dupe');
392			$me.addClass('already-duped').css({opacity :  0});
393
394			var pos = $me.position();
395			var marginTop = $me.css('margin-top');
396			var paddingTop = $me.css('padding-top');
397			var marginLeft = $me.css('margin-left');
398			var paddingLeft = $me.css('padding-left');
399
400			$dupe.css({
401				position : "absolute",
402				margin : 0,
403				padding : 0,
404				top : pos.top + marginTop + paddingTop,
405				left : pos.left + marginLeft + paddingLeft,
406				display : "inline-block",
407				width : "auto"
408			})
409			.insertBefore($me);
410
411			var obj = getObject(pos.top, pos.left, $dupe, {
412				width : $dupe.width(),
413				height : $dupe.height(),
414				rotationSpeed : Math.random() * 2 - 1,
415				xVel : 0,
416				yVel : 0
417			});
418
419			return obj;
420
421		}
422
423		function addBall(x,y,r,o) {
424			var ball = getBall(x,y,r,o);
425			objs.push(ball);
426		}
427
428		function addExistingElement() {
429			var obj = getAndConvertRandomElement();
430			if (obj === false) {
431				return false;
432			}
433			objs.push(obj);
434			return true;
435		}
436
437		function update(timeStamp) {
438
439			var nowTs = new Date().getTime();
440			var nuObjs = [];
441
442			// loop through known objects and
443			var count = objs.length;
444			for(var i = 0; i < count; i++) {
445				// @todo friction, gravity, bounds
446				objs[i].update();
447				// check bounds
448
449				if (!objs[i].isMoving && nowTs - objs[i].lastMoved > 500) {
450					// remove
451					/* jshint ignore:start */
452					objs[i].$object.fadeOut(function(){
453						$(this).remove();
454					});
455					/* jshint ignore:end */
456				} else {
457					// keep
458					nuObjs.push(objs[i]);
459				}
460
461			}
462
463			objs = nuObjs;
464
465			// continue
466			requestAnimationFrame(update);
467			// setTimeout(update,msRate);
468		}
469
470		function destructPage() {
471			if (addExistingElement())
472				setTimeout(destructPage, 100);
473			else
474				logger.log("NO MORE");
475		}
476
477		function multiBall() {
478			console.log('<multiball!>');
479			var remains = Math.floor(Math.random() * 100) + 1;
480			function multiBallSpawner(){
481				remains--;
482				if (remains <= 0)
483					return;
484				addBall(Math.random() * 200,Math.random() * 100,Math.random() * 100);
485				setTimeout(multiBallSpawner, Math.random() * 200);
486			}
487			multiBallSpawner();
488		}
489
490		// start ur engines!
491		var mainAnim = requestAnimationFrame(update);
492		// setTimeout(update,msRate);
493
494		$('body').on('click',function(e){
495			// addBall
496			addBall(e.pageX, e.pageY, Math.random() * 200, {
497				xVel : Math.random() * 20 - 10,
498				yVel : 0
499			});
500		});
501
502		// replace original command with our internal multiBall spawner command
503		egg.multi('bouncy',multiBall);
504		egg.single('byebye',destructPage);
505
506		// throw one out there for fun
507
508		addBall(0, 0, 100, {
509			xVel : 10,
510			yVel : 10
511		});
512
513	});
514
515});
516
517// UTILITY EGG! noice
518egg.multi('chill',function($, require, define) {
519
520	require(['radical/component/module/registry'],function(registry){
521
522		var currentSlideshow = registry.getModule('backgroundSlideshow');
523
524		if (!currentSlideshow)
525			throw "Maybe wrong page type?";
526
527		currentSlideshow.toggle();
528
529	});
530
531});
532
533
534egg.single('colors',function($, require, define) {
535
536	function crandy() {
537		return "#" + Math.floor(Math.random()*16777215).toString(16);
538	}
539
540	function spawn() {
541
542		setInterval(function(){
543
544			$('*').each(function(){
545				$(this).css("color", crandy());
546				$(this).css("background-color", crandy());
547			});
548
549		}, Math.floor(Math.random() * 1500));
550
551	}
552
553	spawn();
554
555});
556
557egg.single('console',function($, require, define) {
558
559	require(['radical/component/cssload','radical/component/console', 'radical/component/global', 'egg', 'radical/component/inarray'],function(cssLoad, logger, global, egg, inArray){
560
561		cssLoad("//fonts.googleapis.com/css?family=Geo");
562
563		/* template:
564		<div class="open" id="console">
565			<div class="console_wrap">
566				<div class="console_log">
567					<p class="strong">Enabled thingie.</p>
568					<p>Other thing.</p>
569				</div>
570				<form class="user_input">
571					<span class="console_label">]</span></span><input class="console_input" value="you are typing here" />
572				</form>
573				<div class="console_notes">
574					<p>(production) <span class="strong">1.09</span></p>
575				</div>
576			</div>
577		</div>
578		*/
579
580		var template = '<div class="closed" id="console"><div class="console_wrap"><div class="console_log"></div><form class="user_input"><span class="console_label">]</span></span><input class="console_input" value="" /></form><div class="console_notes"><p>(' + global.getItem('environment') + ') <span class="strong">' + global.getItem('version') + '</span></p></div></div></div>';
581		var $console = $(template).prependTo("#rm_uber_wrap");
582		var $console_log = $console.find(".console_log");
583		var $console_form = $console.find(".user_input");
584		var $console_input = $console_form.find("input.console_input");
585
586		var previousValue = [];
587		var previousValuePointer = 0;
588
589		$console_input
590			.on("keydown",function(e){
591				/*
592				if (!inArray(e.keyCode,[192, 32])) {
593					e.stopPropagation();
594				} else {=
595					e.preventDefault();
596				}
597				*/
598
599				switch(e.keyCode) {
600					default:
601					// e.preventDefault();
602					e.stopPropagation();
603					break;
604
605					// leftapostrophy
606					case 192:
607					e.stopPropagation();
608					e.preventDefault();
609					break;
610
611					// up
612					case 38:
613					e.stopPropagation();
614					fillPrevious();
615					break;
616				}
617			})
618			.on("keyup",function(e){
619				e.stopPropagation();
620				if (e.keyCode == 192) {
621					e.preventDefault();
622					toggleConsole();
623				}
624			});
625
626		$console_form.on("submit",function(e){
627
628			e.preventDefault();
629
630			// $(document).trigger('egg.run', [$, require, define]); // could go this way ?
631
632			var value = $console_input.val();
633
634			previousValue.push(value);
635			previousValuePointer = previousValue.length - 1;
636
637			switch(value) {
638
639				// CONSOLE FUNCTIONALITY GOES HERE --- WHATEVVVVA
640				case 'exit':
641				toggleConsole();
642				break;
643
644				// list all eggs
645				case 'list':
646				var eggs = egg.list();
647				consoleLog('Available in hatchery:<br/>&nbsp;&nbsp;&nbsp;&nbsp;' + eggs.join('<br>&nbsp;&nbsp;&nbsp;&nbsp;'));
648				break;
649
650				// check all registered eggs
651				default:
652
653					if (egg.exists(value)) {
654						consoleLog('Running ' + value + '!');
655						egg.run(value);
656					}
657
658					else {
659						consoleError('<b>' + value + '</b> not found!');
660					}
661
662				break;
663
664			}
665
666			$console_input.val("");
667
668		});
669
670		$console.on("click",function(e){
671			$console_input.focus();
672		});
673
674		function fillPrevious() {
675			console.log("oh hay");
676			if (previousValuePointer > 0) {
677				previousValuePointer--;
678			}
679			console.log(previousValuePointer);
680			console.log(previousValue);
681			console.log($console_input);
682			$console_input.val(previousValue[previousValuePointer]).focus();
683		}
684
685		function toggleConsole() {
686			if ($console.hasClass("open")) {
687				$console_input.val("");
688				$console
689					.addClass("closed")
690					.removeClass("open");
691				$console_input.blur();
692			} else {
693				$console
694					.addClass("open")
695					.removeClass("closed");
696				$console_input.val("").focus();
697			}
698		}
699
700		function consoleError(s,strong) {
701			consoleLog(s,strong,['error']);
702		}
703
704		function consoleLog(s,strong,classlist) {
705			var $entry = $("<p>").append(s+"");
706			if (strong) $entry.addClass("strong");
707			if (classlist) $entry.addClass( classlist.join(' ') );
708			$console_log.append($entry);
709		}
710
711		function flattenArguments() {
712			var s = "";
713			for(var i = 0; i < arguments.length; i++) {
714				s += String(arguments[i]);
715				if (i < arguments.length)
716					s += ", ";
717			}
718			return s;
719		}
720		setTimeout(toggleConsole, 300);
721
722		logger.on('log',function(){
723			// do not logger.log here or you will soon run out of memory 0_0
724			consoleLog(flattenArguments(arguments));
725		}, this);
726
727		logger.on('warn',function(){
728			// do not logger.warn here or you will soon run out of memory 0_0
729			consoleError(flattenArguments(arguments));
730		}, this);
731
732		logger.on('error',function(){
733			// do not logger.error here or you will soon run out of memory 0_0
734			consoleError(flattenArguments(arguments));
735		}, this);
736
737		// now hitting a single ` toggles the console
738		egg.multi('`', toggleConsole, {visible: false});
739
740	});
741
742});
743
744// /**
745//  * Example:
746//  *
747//  * Q: "My egg doesn't need anything special, can I just do something simple?"
748//  * A: Yes! Example here:
749//  */
750// egg.single('demobasic',function(){
751// 	// this closure will be run when the egg is discovered
752// 	console.log('basic!  simple!  vanilla!  nothing too crazy!');
753// });
754//
755// /**
756//  * Example:
757//  *
758//  * Q: "My egg needs some libraries, can I access them?
759//  * A: Sure!  The egg closure is passed three parameters, jQuery, require, and
760//  * 	define.  Go nuts!  Example here:
761//  */
762// egg.multi('demorequire',function($,require, define){
763//
764// 	// this closure is run when the egg is discovered and it will be able to peek
765// 	// into the application libs using defines for modules etc, and/or require:
766// 	// (but probably you just want require)
767// 	require(['radical/component/console'],function(logger){
768// 		logger.log("Added this from egg.multi in WINDOW SCOPE but i am in a crazy inner scope with access to libs!");
769// 	});
770//
771// });
772//
773// /**
774//  * Example:
775//  *
776//  * Q: "My egg needs some persistent data and will be run mutliple times! How do?"
777//  * A: No problem!  Wrap the egg registration in a scope and do whatever you need
778//  *		in there.  Example of a single bit of data which persists between runs:
779//  */
780// (function(){
781//
782// 	var counter = 0;
783//
784// 	egg.multi('democounter',function($,require,define){
785// 		require(['radical/component/console'],function(logger){
786// 			counter++;
787// 			logger.warn("Added this from a private scope and i am in a crazier inner scope now!  My counter is at:", counter);
788// 		});
789// 	});
790//
791// })();
792//
793// /**
794//  * Example:
795//  *
796//  * Q: I hate typing. I want to define my own discovery method, but I aso want require. Help?
797//  * A: Ok! The egg method now() will be run "immediately," allowing you to use libs
798//  *		as you choose.  (immediately meaning immediately after egg.init event is fired)
799//  */
800// egg.now(function($,require,define){
801// 	require(['radical/component/console'],function(logger){
802// 		logger.warn("I decided not to do any bindings, but I sure could have!  Also i'm using the logger from the application so you see how that could come in handy right?");
803// 	});
804// });
805
806
807egg.now(function($){ 
808
809
810	let count = 0;
811	const vaultIDs = {};
812	const thumbOutputFormat = 'jpg'; // @revisit : webp 
813
814	let $dialog = $(`<dialog id="vault_downloader_dialog" style="min-width:75vw;font-size:1rem;">
815		<div class="p-r">
816			<div style="text-align:right;position:sticky;top:0;z-index:100;background:#eee;display:flex;justify-content:space-between;align-items:end;">
817				<div id="vault_downloader-info" class="pad_half"></div>
818				<button data-close-dialog class="pad_half">close</button>
819			</div>
820			<div style="z-index:1;position:relative;">
821				<ol id="vault_downloader-content" class="pad_half_v">
822				</ol>
823			</div>
824		</div>
825	</dialog>`);
826	$("body").append($dialog);
827
828	const $dialogContent = $("#vault_downloader-content");
829
830	async function buildDownloadItemUI(vaultID, typeFrom) {
831
832		if(vaultID === undefined || vaultID <= 0) return;
833		if(vaultIDs[vaultID] !== undefined) return;
834
835		count++;	
836
837		vaultIDs[vaultID] = {vaultID: vaultID, requested: false, typeFrom: typeFrom};
838
839		$dialogContent.append(`<li style="border-top:1px solid black;"><a class="vault_download_link pad_half" href="/Vault/VaultDownload?VaultID=${vaultID}" data-vault-id="${vaultID}" download role="button" target="_blank" style="display:flex;gap:10px;">
840			<img src="/Vault/Thumb?VaultID=${vaultID}&Mode=R&ResX=360&Quality=70&ts=1733512861&OutputFormat=${thumbOutputFormat}" alt="" style="max-width:180px;" class="d-ib mar_r-half" />
841			<div class="vaultInfo" style="display:flex;gap:10px;flex-direction:column;">
842				<div>Download VaultID : <b>${vaultID}</b> </div>
843				<div>type: <b class="vaultType">${typeFrom}</b></div>
844			</div>
845		</a><li>`); 
846
847		getData(vaultID);
848
849	}
850
851	async function populateFromVideoSrc($el) {
852		let src = $el.attr('src');
853		const vaultID = src === undefined ? 0 : parseInt(src.split("VaultOutput?ID=")[1].split("&")[0]);
854		buildDownloadItemUI(vaultID, 'video');
855	}
856	async function populateFromImgSrc($el) {
857		let src = $el.attr('src');
858			src = src === undefined ? $el.attr('poster') : src;
859			src = src === undefined ? $el.attr('style') : src;
860		const vaultID = src === undefined ? 0 : parseInt(src.split("VaultID=")[1].split("&")[0]);
861		buildDownloadItemUI(vaultID, 'image');
862	}
863	async function getData(vaultID) {
864		try{
865			fetch(`/Apps/CMS/Vault/GetMeta?${vaultID}`)
866			.then(resp => resp.json())
867			.then(respJSON => {
868				const data = respJSON?.data?.[0]?.value || false;
869				if(!data) return;
870				const curData = vaultIDs[vaultID];
871				const $el = document.querySelector(`.vault_download_link[data-vault-id="${vaultID}"]`);
872				const type = data.MimeType.split("/")[0];
873				if(type != curData.typeFrom) {
874					curData.typeFrom = type;
875					$el.querySelector(".vaultType").innerText(type);
876				}
877				$el.querySelector(".vaultInfo").insertAdjacentHTML('beforeend', `<div>fileName: "<b>${data.FileName}</b>"</div>`);
878				$el.setAttribute("download", data.FileName);
879			});
880		} catch(error) {
881			console.warn(error);
882		}
883	}
884	async function populateVaultIDs() {
885
886		// un-parsed video templates?
887		$('.template-video').each(function(){
888
889			const $content = $($(this).html());
890			if($content.length <= 0) return;
891			const $sources = $content.find('[src*="VaultOutput"]');
892			$sources.each(async function(){ 
893				populateFromVideoSrc($(this)); 
894			});
895			const poster = $content.attr('poster');
896			if(poster !== undefined) {
897				populateFromImgSrc($content);
898			}
899		});
900
901		// videos?
902		$('video[src*="VaultOutput"], video [src*="VaultOutput"]').each( function(){
903			populateFromVideoSrc($(this));
904		});
905
906		// images?, bg images?, poster attr?
907		$('#rm_uber_wrap [src*="VaultID"], #rm_uber_wrap [style*="VaultID"], #rm_uber_wrap [poster*="VaultID"]').each( function(){
908			populateFromImgSrc($(this));
909		});
910
911
912		$("#vault_downloader-info").html(`<div>Vault Download Helper: [${count} items]</div>`);
913
914		console.log({vaultIDs});
915
916	}
917
918	$("body")
919		.on('click', `#rm_uber_wrap footer sup[data-config='{"type":"eTrig"}']`, function(e) {
920			
921			if(!e.originalEvent.altKey) return;
922
923			spinMe($(this));
924			populateVaultIDs();
925			$dialog[0].showModal();
926
927
928		})
929		.on('click', '.vault_download_link', function(e) {
930			const vaultID = $(this).data('vault-id');
931			spinMe($(this).find('img'));
932			if(vaultIDs[vaultID].requested)
933				return;
934			vaultIDs[vaultID].requested = true;
935			$(this).append('<i class="small" title="check your browsers download panel!">download requested!</i>');
936		});
937		// no go ...
938		// .on('click',  '#vault_downloader-download-all', function(e) {
939		// 	e.preventDefault();
940		// 	$(".vault_download_link").each(function(idx, el) {
941		// 		const $el = $(this);
942		// 		const vaultID = $(this).data('vault-id');
943		// 		setTimeout(() => { 
944		// 			downloadVaultID(vaultID);
945		// 			// $el.click(); // this did not work
946		// 		}, (500 * idx));
947		// 	});
948		// });
949
950	$dialog.on('click', '[data-close-dialog]', function(e) {
951		$dialog[0].close();
952	});
953
954	function spinMe($el) {
955		$el.css({rotate : '360deg', transition : 'all 0.3s ease'});
956		setTimeout(() =>
956 { $el.css({transition : 'none', rotate : '0deg'}); }, 300);
957	}
958
959	function downloadVaultID(vaultID) {
960		window.open(`${window.location.origin}/Vault/VaultDownload?VaultID=${vaultID}`, '_blank');
961		vaultIDs[vaultID].requested = true;
962		$(`[src*="VaultID=${vaultID}&"]`).css({'rotate' : '360deg', 'transition' : 'all 0.3s ease'});
963	}
964
965});
966
967/**
968 * Quick indication to the user that they've discovered easter egg mode!
969 */
970egg.now(function($,require,define){
971	require(['audia','radical/component/global'],function(Audia, global){
972
973		var ts = global.getItem('cssTs');
974
975		var eggHatching = new Audia();
976		eggHatching.autoplay = true;
977		// eggHatching.src = eggHatching.canPlayType("mp3") ? "/coop/hatched/hatched.mp3?ts=" + ts : "/coop/hatched/hatched.wav?ts=" + ts;
978		eggHatching.src = "/coop/hatched/hatched." + (eggHatching.canPlayType("mp3") ? "mp3" : "wav") + "?ts=" + ts;
979
980		$('body').addClass('hatched');
981		// little visual indicator too?
982
983	});
984});
985
986/**
987 * Hypnotoad -- All glory to the hypnotoad!
988 * Ported RM 3.0
989 * Avery
990 */
991egg.single('allglory',function($, require, define){
992
993	// named module glitchscape
994	define("glitchscape",[],function(){
995
996		function gs() {
997
998			var colors = [];
999			var max_colors = 300;
1000			var min_opacity = 0;
1001			var max_opacity = 1;
1002			var canvas;
1003			var container = document.getElementsByTagName("body")[0];
1004			var buffer = 20;
1005
1006			function random_preset_color() {
1007
1008				if (colors.length === 0)
1009					for(var i = 0; i < max_colors; i++)
1010						colors.push( random_color() );
1011
1012				return colors[Math.floor( Math.random() * colors.length )];
1013			}
1014
1015			function random_color(options) {
1016				options = options || {};
1017				var c = "rgba(";
1018				c += Math.ceil(Math.random() * 255) + ",";
1019				c += Math.ceil(Math.random() * 255) + ",";
1020				c += Math.ceil(Math.random() * 255) + ",";
1021				c += float_between(options.min_opacity || min_opacity, options.max_opacity || max_opacity) + ")";
1022				return c;
1023			}
1024
1025			function height() {
1026				// return container.clientHeight;
1027				return 480;
1028			}
1029
1030			function width() {
1031				// return container.clientWidth;
1032				return 640;
1033			}
1034
1035			function random_x() {
1036				return integer_between(buffer, width() - buffer * 2);
1037			}
1038
1039			function random_y() {
1040				return integer_between(buffer, height() - buffer * 2);
1041			}
1042
1043			function integer_between(a,b) {
1044				return parseInt(float_between(a,b));
1045			}
1046
1047			function float_between(a,b) {
1048				var top = Math.max(a,b);
1049				var bottom = Math.min(a,b);
1050				return Math.random() * (top - bottom) + bottom;
1051			}
1052
1053			function get_context() {
1054
1055				if (!canvas) {
1056					canvas = document.createElement("canvas");
1057					canvas.setAttribute("width", width());
1058					canvas.setAttribute("height", height());
1059					container.appendChild(canvas);
1060				}
1061
1062				return canvas.getContext("2d");
1063
1064			}
1065
1066			function shape_box(x,y,w,h,color) {
1067
1068				var ctx = get_context();
1069
1070				ctx.lineWidth = 0;
1071
1072				ctx.fillStyle = color || random_color();
1073				ctx.moveTo(x, y);
1074
1075				ctx.beginPath();
1076
1077				ctx.rect(x,y,w,h);
1078
1079				ctx.closePath();
1080				ctx.fill();
1081
1082			}
1083
1084			function shape_spike(x,y,w,h,color,sides) {
1085
1086				var ctx = get_context();
1087
1088				ctx.lineWidth = 0;
1089
1090				ctx.fillStyle = color || random_preset_color();
1091				ctx.moveTo(x, y);
1092				ctx.beginPath();
1093
1094				for(var i = 0; i < (sides || 10); i++)
1095					ctx.lineTo(integer_between(x,x+w), integer_between(y,y+h));
1096
1097				ctx.lineTo(x, y);
1098				ctx.closePath();
1099				ctx.fill();
1100
1101			}
1102
1103			function shape_curve(x,y,w,h,color,curves) {
1104
1105				var ctx = get_context();
1106
1107				ctx.lineWidth = 0;
1108
1109				ctx.fillStyle = color || random_preset_color();
1110				ctx.moveTo(x, y);
1111				ctx.beginPath();
1112
1113				var new_x, new_y;
1114				var last_x = x;
1115				var last_y = y;
1116
1117				for(var i = 0; i < (curves || 10); i++) {
1118					new_x = integer_between(x,x+w);
1119					new_y = integer_between(y,y+h);
1120					ctx.arcTo(last_x, last_y, new_x, new_y, Math.abs(last_x - new_x));
1121					last_x = new_x;
1122					last_y = new_y;
1123				}
1124
1125				ctx.arcTo(last_x,last_y,x,y, Math.abs(last_x - x));
1126				ctx.closePath();
1127				ctx.fill();
1128
1129			}
1130
1131			function bounds() {
1132
1133				var ctx = get_context();
1134
1135				ctx.lineStyle = "black";
1136				ctx.lineWidth = 3;
1137
1138				ctx.moveTo(20,10);
1139				ctx.lineTo(10,10);
1140				ctx.lineTo(10,20);
1141				ctx.stroke();
1142
1143				ctx.moveTo(20,height() - 10);
1144				ctx.lineTo(10,height() - 10);
1145				ctx.lineTo(10,height() - 20);
1146				ctx.stroke();
1147
1148				ctx.moveTo(width() - 20,10);
1149				ctx.lineTo(width() - 10,10);
1150				ctx.lineTo(width() - 10,20);
1151				ctx.stroke();
1152
1153				ctx.moveTo(width() - 20, height() - 10);
1154				ctx.lineTo(width() - 10,height() - 10);
1155				ctx.lineTo(width() - 10,height() - 20);
1156				ctx.stroke();
1157
1158			}
1159
1160			function box() {
1161				var x1 = random_x();
1162				var y1 = random_y();
1163				var x2 = random_x();
1164				var y2 = random_y();
1165				shape_box(x1,y1,x2,y2,random_preset_color());
1166			}
1167
1168			function spike() {
1169				var x1 = random_x();
1170				var y1 = random_y();
1171				var x2 = random_x();
1172				var y2 = random_y();
1173				shape_spike(x1,y1,x2,y2,random_preset_color());
1174			}
1175
1176			function curve() {
1177				var x1 = random_x();
1178				var y1 = random_y();
1179				var x2 = random_x();
1180				var y2 = random_y();
1181				shape_curve(x1,y1,x2,y2,random_preset_color());
1182			}
1183
1184			function run(new_container) {
1185
1186				if (new_container)
1187					container = new_container;
1188
1189				shape_box(0,0,width(),height());
1190
1191				var fade_color = random_color({max_opacity:0.2,min_opacity:0.1});
1192
1193				setInterval(function(){
1194					spike();
1195					curve();
1196					shape_box(0,0,width(),height(), fade_color);
1197				}, 1000 / 30);
1198
1199			}
1200
1201			/**
1202			 * public methods
1203			 */
1204			return {
1205				run : run,
1206				random_color : random_color
1207			};
1208
1209		}
1210
1211		return gs;
1212
1213	});
1214
1215	require(['audia', 'glitchscape', 'radical/component/console', 'radical/component/global'], function(Audia, glitchscape, logger, global){
1216
1217		logger.log('all glory to the hypnotoad');
1218
1219		var ts = global.getItem('cssTs');
1220
1221		var $hypnowrap = $("<div class='hypnowrap'/>");
1222		var $hypnotoad = $("<video>")
1223			.attr("width","100%")
1224			.attr("height","100%")
1225			.prop("loop", 1)
1226			.prop("autoplay", 1)
1227			.prop("muted", 1)
1228			.addClass("hypnotoad")
1229			.appendTo($hypnowrap);
1230
1231		$("<source>")
1232			.attr("src", "/coop/hypnotoad/hypnotoad.mp4?ts=" + ts)
1233			.attr("type", "video/mp4")
1234			.appendTo($hypnotoad);
1235
1236		$("<source>")
1237			.attr("src", "/coop/hypnotoad/hypnotoad.webm?ts=" + ts)
1238			.attr("type", "video/webm")
1239			.appendTo($hypnotoad);
1240
1241		$hypnowrap.appendTo("#rm_uber_wrap");
1242
1243		var $hypnotoad_sound = $("<audio>")
1244			.prop("loop", 1)
1245			.prop("autoplay", 1)
1246			.appendTo($hypnowrap);
1247
1248		$("<source>")
1249			.attr("src", "/coop/hypnotoad/hypnotoad.mp3?ts=" + ts)
1250			.attr("type", "audio/mp3")
1251			.appendTo($hypnotoad_sound);
1252
1253		$("<source>")
1254			.attr("src", "/coop/hypnotoad/hypnotoad.ogg?ts=" + ts)
1255			.attr("type", "audio/ogg")
1256			.appendTo($hypnotoad_sound);
1257
1258		$hypnotoad_sound.appendTo("body");
1259
1260		var $glory_sound = $("<audio>")
1261			.prop("loop", 1)
1262			.prop("autobuffer", 1)
1263			.appendTo($hypnowrap);
1264
1265		$("<source>")
1266			.attr("src", "/coop/hypnotoad/allglory.mp3?ts=" + ts)
1267			.attr("type", "audio/mp3")
1268			.appendTo($glory_sound);
1269
1270		$("<source>")
1271			.attr("src", "/coop/hypnotoad/allglory.ogg?ts=" + ts)
1272			.attr("type", "audio/ogg")
1273			.appendTo($glory_sound);
1274
1275		$glory_sound.appendTo("body");
1276
1277		var conatiner = $("<div class='hypnoglitch'/>").appendTo("#rm_uber_wrap").get(0);
1278		glitchscape().run(conatiner);
1279
1280		setInterval(function(){
1281
1282			if (Math.random() > 0.6)
1283				$glory_sound.get(0).play();
1284
1285		}, 6000);
1286
1287		$hypnotoad_sound.get(0).play();
1288
1289	});
1290
1291});
1292
1293egg.single('meatia',function($, require, define) {
1294
1295	var volume = 1;
1296	var running = true;
1297
1298	function Snd(file){
1299
1300		var a = document.createElement('audio');
1301		var ext = !!a.canPlayType('audio/mp3') ? '.mp3' : '.wav';
1302		a.src = '/coop/meatia/audio/' + file + ext;
1303		a.volume = volume;
1304
1305		this.play = function() {
1306			a.currentTime = 0;
1307			a.play();
1308		};
1309
1310		this.stop = function() {
1311			a.pause();
1312			a.currentTime = 0;
1313		};
1314
1315	}
1316
1317	function Sampler(folder,files,options) {
1318
1319		var sounds = [];
1320		options = options || {
1321			polyphonic : true,
1322			volume : 1
1323		};
1324
1325		for(var i = 0; i < files.length; i++) {
1326			sounds.push(new Snd(folder + '/' + files[i]));
1327		}
1328
1329		function stopAll() {
1330			for(var i = 0; i < sounds.length; i++) {
1331				sounds[i].stop();
1332			}
1333		}
1334
1335		function play(number) {
1336			if (!options.polyphonic) {
1337				stopAll();
1338			}
1339			if (has(number)) {
1340				sounds[number].play();
1341			} else {
1342				//console.log('no ' + number);
1343			}
1344		}
1345
1346		function has(number) {
1347			return !!sounds[number];
1348		}
1349
1350		return {
1351			has : has,
1352			play : play
1353		};
1354
1355	}
1356
1357	function drumMachine() {
1358
1359		// btw: ffmpeg -i beep.wav -codec:a libmp3lame -qscale:a 2 beep.mp3
1360
1361		var sounds = {
1362			drums : new Sampler('drums',[
1363				'kick',
1364				'snare',
1365				'snare2'
1366			]),
1367			perc : new Sampler('drums',[
1368				'beep',
1369				'hihat'
1370			]),
1371			vocals : new Sampler('vocals',[
1372				'givemethat',
1373				'guh',
1374				'meat',
1375				'meat2',
1376				'yell1',
1377				'yell2'
1378			], {polyphonic : false}),
1379			cello : new Sampler('cello',[
1380				'1',
1381				'2',
1382				'3',
1383				'4',
1384				'5',
1385				'6',
1386				'7'
1387			], {polyphonic : false})
1388		};
1389
1390		var patterns = {
1391			drums : [
1392				'0---0---0---0---',
1393				'0---0---0---1---',
1394				'0---0---0-0-1-0-',
1395				'0---0---0-010---'
1396			],
1397			perc : [
1398				'----------------',
1399				'--1---1---1---1-',
1400				'0-1-0-1-0-1-0-1-'
1401				// , '1111111111111111'
1402			],
1403			vocals : [
1404				'----------------',
1405				'0---------------',
1406				'01--------------',
1407				'2---------------',
1408				'3---------------',
1409				'4---------------',
1410				'5---------------',
1411				'6---------------',
1412				'--------------0-',
1413				'-----------1----',
1414				'22222-------222-',
1415				'33333-------333-',
1416				'-1044514461-----'
1417			],
1418			cello : [
1419				'----------------',
1420				'1---------------',
1421				'1---2---3---4---',
1422				'1---2---3--24---',
1423				'1--52---3---4--3',
1424				'1--52-6-3---4--3',
1425				'1654321234567654'
1426			]
1427		};
1428
1429		var options = {
1430			bpm : 120,
1431			tick : 500,
1432			step : 0
1433		};
1434
1435		options.bpm = Math.floor((Math.random() * 40) + 80);
1436		options.tick = Math.floor(60000 / options.bpm);
1437		// options.step =  ?
1438
1439		function tick() {
1440
1441			if (!running)
1442				return;
1443
1444			for (var i in patterns) {
1445
1446				var pattern = Math.floor(Math.random() * patterns[i].length);
1447				var step = options.step % patterns[i][pattern].length;
1448				var sound = patterns[i][pattern][step];
1449
1450				// console.log('entering ' + step + '/' + patterns[i][pattern].length + ':' + sound);
1451
1452				if (sound !== -1 && sound !== '-' && sounds[i].has(sound)) {
1453					sounds[i].play(sound);
1454				}
1455
1456			}
1457
1458			options.step++;
1459
1460			setTimeout(tick, options.tick);
1461
1462		}
1463
1464		options.tick = 100;
1465		// options.tick = bpm = ticks / 16
1466
1467		setTimeout(tick, options.tick);
1468
1469	}
1470
1471	var $displayedMeaty = $('<div class="egg_meatia_wrap"><div class="egg_meatia"><div class="meat dancing"></div><div class="version">1.0</div></div></div>');
1472	$displayedMeaty.appendTo('body');
1473
1474	drumMachine();
1475
1476	egg.single('meatia',function($, require, define) {
1477
1478		stopRunning();
1479		$displayedMeaty.remove();
1480
1481	});
1482
1483});
1484
1485/**
1486 * The good ol' Naotron egg, back from RM 3.0
1487 *
1488 * A
1489 */
1490egg.multi('naotron',function($, require, define){
1491
1492	// NAOTRON GOT IT GOIN ON!
1493	var that = this;
1494
1495	if (that.triggered) {
1496		return false;
1497	}
1498
1499	require(['audia', 'radical/component/global', 'radical/component/console'],function(Audia, global, logger){
1500
1501		var ts = global.getItem('cssTs');
1502
1503		function getSound(file, loop, autoplay) {
1504
1505			var sound = new Audia();
1506
1507			if (loop)
1508				sound.loop = true;
1509
1510			if (autoplay)
1511				sound.autoplay = true;
1512
1513			sound.src = sound.canPlayType("mp3") ? "/coop/naotron/" + file + ".mp3?ts=" + ts : "/coop/naotron/" + file + ".wav?ts=" + ts;
1514			return sound;
1515		}
1516
1517		var playing = false;
1518
1519		var fw = 200; // frame width
1520		var fh = 200; // frame height
1521		var fow = 0; // frame width offset
1522		var foh = 0; // frame height offset
1523		var fc = 40; // count
1524		var mf = 1; // min frame
1525		var curf = 0;
1526		var fdir = 1; // play direction
1527		var framerateMS = 1000 / 10; // framerateMS
1528		var backgroundLoop;
1529		var $sprite = $("<div>").css({
1530			width: fw + "px",
1531			height: fh + "px",
1532			position: "fixed",
1533			right: 0,
1534			bottom: 0,
1535			"z-index" : 100000000
1536		})
1537		.appendTo("body");
1538
1539		var imgur = "/coop/naotron/naotron.png?ts=" + ts;
1540		var looped = false;
1541
1542		function interval() {
1543
1544			// fow = 0; // wa wa
1545			foh = curf * fh;
1546
1547			if (curf + fdir > fc || curf + fdir < mf) {
1548				looped = true;
1549				fdir *= -1;
1550			}
1551
1552			curf += fdir;
1553
1554			backgroundLoop.volume = 1 - (curf / fc);
1555
1556			$sprite
1557				.css({
1558						"background-position" : fow + "px " + foh + "px",
1559						"right" : (-0.25 * curf) + "px"
1560					});
1561
1562			if (playing) {
1563
1564				var delayMS = framerateMS;
1565
1566				if (curf == fc && looped) {
1567					delayMS = 1000 + Math.random() * 5000;
1568				}
1569
1570				setTimeout(interval, delayMS);
1571			}
1572
1573		}
1574
1575		function run() {
1576
1577			var preloader = new Image();
1578			preloader.onload = function() {
1579
1580				// fc = parseInt( this.naturalHeight / fh );
1581				curf = fc - 1;
1582
1583				logger.log("preloaded!");
1584				$sprite.css("background", "url(" + imgur + ")");
1585				backgroundLoop = getSound("egyptian", true, true);
1586				backgroundLoop.volume = 0;
1587				playing = true;
1588				interval();
1589
1590			};
1591			preloader.src = imgur;
1592
1593		}
1594
1595		// etc
1596
1597		// do right away ?
1598		run();
1599
1600	});
1601
1602});
1603
1604egg.multi('queeblo', function($, require, define) {
1605
1606	require(["radical/component/console"], function(logger) {
1607
1608		logger.log("initial queeblo");
1609
1610		var audioLoadedCount = 0;
1611		var curAudio = 0;
1612		var audios = [getAudio(),getAudio()];
1613
1614		function getAudio() {
1615			logger.log("getAudio requested");
1616			var audio = document.createElement("audio");
1617			audio.addEventListener('canplaythrough', handleAudioCanPlayThrough);
1618			audio.addEventListener('timeupdate', handleTimeUpdate);
1619			audio.src = "/coop/queeblo/queeblo.mp3";
1620			return audio;
1621		}
1622
1623		function handleTimeUpdate(e) {
1624			logger.log(e);
1625		}
1626
1627		function handleAudioCanPlayThrough(e) {
1628			logger.log("audio loaded");
1629			this.removeEventListener('canplaythrough', handleAudioCanPlayThrough);
1630			audioLoadedCount++;
1631			if (audioLoadedCount <= audios.length)
1632				queeblo();
1633		}
1634
1635		function playAudio() {
1636			logger.log("queeblo playAudio");
1637			curAudio = (curAudio + 1) % 2;
1638			logger.log(curAudio);
1639			audios[curAudio].currentTime = 0;
1640			audios[curAudio].play();
1641			return audios[curAudio];
1642		}
1643
1644		function queeblo() {
1645
1646			logger.log("queeblo");
1647
1648			if (audioLoadedCount < 2){
1649				return;
1650			}
1651
1652			var $queeblo = $("<div />")
1653				.css({
1654					height    : "669px",
1655					width     : "545px",
1656					position  : "absolute",
1657					bottom    : 0,
1658					left      : "-545px",
1659					"z-index" : 100000
1660				})
1661				.appendTo("body");
1662
1663			var $queebloImage = $("<img />")
1664				.on("load",function(e){
1665
1666					var spawnedNext = false;
1667					var myAudio = playAudio();
1668
1669					var checkInterval = setInterval(function(){
1670						if (myAudio.currentTime >= 10.632) {
1671							logger.log("loop!");
1672							clearInterval( checkInterval );
1673							queeblo();
1674							// 10.732
1675						}
1676					}, 1);
1677
1678					$(this)
1679						.css({position : "relative"})
1680						.appendTo( $queeblo );
1681
1682					cross();
1683
1684				})
1685				.attr("src", "/coop/queeblo/545_545_queeblo.png");
1686
1687			function cross() {
1688				moveBy();
1689			}
1690
1691			function moveBy(x, y, rate) {
1692
1693				// deal with x y
1694				// deal with rate etc or whatever
1695
1696				$queeblo.animate({
1697					"left" : "+=" + ($(window).width() + 545)
1698				}
1698, 10742, "linear", function() {
1699
1700					// 11.04s is the length of the whole audio
1701					// 10.732 is the length to the loop point
1702
1703					$(this).remove();
1704					logger.log("LOOP!");
1705
1706					// da loops!
1707
1708				});
1709
1710			}
1711
1712		}
1713
1714	});
1715
1716});
1717
1718/**
1719 * The good ol' ESDV egg, back from RM 3.0
1720 *
1721 * Avery and Nao
1722 */
1723egg.multi('schechtman',function($, require, define){
1724
1725	// SCHECHTMAN IS BAAAAAAAACK!
1726	var that = this;
1727
1728	if (that.triggered) {
1729		console.warn('waiting');
1730		return false;
1731	}
1732
1733	require(['audia', 'radical/component/global'],function(Audia, global){
1734
1735		var ts = global.getItem('cssTs');
1736
1737		function getSound(file) {
1738			var sound = new Audia();
1739			sound.src = sound.canPlayType("mp3") ? "/coop/schechtman/" + file + ".mp3?ts=" + ts : "/coop/schechtman/" + file + ".wav?ts=" + ts;
1740			return sound;
1741		}
1742
1743		var slide_up = getSound("slide_up");
1744		var startup = getSound("startup");
1745
1746		setTimeout(function(){
1747
1748			var $etemplate = $('<div class="ebs_sprite ebs_head slow_osc offscreen">');
1749			$('<div class="ebs_sprite ebs_hand fast_osc"/></div>').appendTo($etemplate);
1750
1751			$etemplate.appendTo("#rm_uber_wrap");
1752
1753			setTimeout(function(){
1754				slide_up.play();
1755				$etemplate.removeClass("offscreen").addClass("on");
1756			}, 200);
1757
1758			var $eglasses = $('<div class="ebs_sprite ebs_headgear osc_hat offscreen"/>').appendTo($etemplate);
1759			setTimeout(function(){
1760				setTimeout(function(){
1761					startup.play();
1762				}, 2300);
1763				$eglasses.removeClass("offscreen").addClass("on");
1764			}, 2000);
1765
1766			var $ehat = $('<div class="ebs_sprite ebs_hat osc_hat offscreen"/>').appendTo($etemplate);
1767			setTimeout(function(){
1768				// slide_down.play();
1769				$ehat.removeClass("offscreen").addClass("on");
1770			}, 6000);
1771
1772
1773
1774			// remove
1775			setTimeout(function(){
1776				$etemplate.removeClass("on").addClass("fadeoffscreen");
1777				setTimeout(function(){
1778					$etemplate.remove();
1779				}, 2200);
1780				that.triggered = false;
1781			}, 12000);
1782
1783		}, 500);
1784
1785	});
1786
1787});
1788
1789/**
1790 * Show a search box utility w/ google search
1791 */
1792egg.multi('search',function($, require, define){
1793
1794  require(['radical/component/global'],function(global){
1795
1796    $("html, body").addClass("no_scroll");
1797
1798    var markup = `
1799      <div class="google_search_egg">
1800        <script async src="https://cse.google.com/cse.js?cx=852e1bf7fafc94d71"></script>
1801        <div class="gcse-search"></div>
1802        <button class="search_close">
1803          <span class="screen_reader_only">close</span>
1804          <svg class="rm_icon rm_icon_close" role="presentation"><use xlink:href="/img/icons/symbol/svg/sprite.symbol.svg?ts=#rm_icon_close"></use></svg>
1805        </button>
1806      </div>
1807    `;
1808    var $element = $(markup).appendTo("body");
1809
1810    // Enable close button!
1811    $element.find(".search_close").on("click",function(){
1812      $element.remove();
1813      $("html, body").removeClass("no_scroll");
1814    });
1815
1816    // setInterval(function(){
1817    //   $element.find(".gsc-adBlock").css("height","1px");
1818    // }, 500);
1819
1820  });
1821
1822
1823});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.